Compare commits
16 Commits
gps
...
voice_tele
Author | SHA1 | Date | |
---|---|---|---|
|
a4691ad117 | ||
|
0613defeb7 | ||
|
86c69340f4 | ||
|
71e6db2c48 | ||
|
6994193e3c | ||
|
61842d1269 | ||
|
f0a8a881c2 | ||
|
3a0dfc4d36 | ||
|
d01aed5ddd | ||
|
7a71d121f4 | ||
|
43a5b89aa2 | ||
|
6394a2d209 | ||
|
23eb56666e | ||
|
1692b3cb72 | ||
|
0677a2c772 | ||
|
5ab34d93d8 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -90,6 +90,7 @@ ENV/
|
|||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
hblink.cfg
|
hblink.cfg
|
||||||
|
deconstructor.cfg
|
||||||
*.config
|
*.config
|
||||||
*.bak
|
*.bak
|
||||||
rules.py
|
rules.py
|
||||||
|
31
bridge.py
31
bridge.py
@ -48,6 +48,7 @@ from dmr_utils3 import decode, bptc, const
|
|||||||
import config
|
import config
|
||||||
import log
|
import log
|
||||||
from const import *
|
from const import *
|
||||||
|
from voice_lib import words
|
||||||
|
|
||||||
# Stuff for socket reporting
|
# Stuff for socket reporting
|
||||||
import pickle
|
import pickle
|
||||||
@ -96,9 +97,9 @@ def config_reports(_config, _factory):
|
|||||||
def make_bridges(_rules):
|
def make_bridges(_rules):
|
||||||
try:
|
try:
|
||||||
bridge_file = import_module(_rules)
|
bridge_file = import_module(_rules)
|
||||||
logger.info('(ROUTER) Routing bridges file found and bridges imported')
|
logger.info('(ROUTER) Routing rules file found and bridges imported')
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit('(ROUTER) TERMINATING: Routing bridges file not found or invalid')
|
sys.exit('(ROUTER) TERMINATING: Routing rules file not found or invalid')
|
||||||
|
|
||||||
# Convert integer GROUP ID numbers from the config into hex strings
|
# Convert integer GROUP ID numbers from the config into hex strings
|
||||||
# we need to send in the actual data packets.
|
# we need to send in the actual data packets.
|
||||||
@ -118,6 +119,15 @@ def make_bridges(_rules):
|
|||||||
else:
|
else:
|
||||||
_system['TIMER'] = time()
|
_system['TIMER'] = time()
|
||||||
return bridge_file.BRIDGES
|
return bridge_file.BRIDGES
|
||||||
|
|
||||||
|
def make_telemetry(_rules):
|
||||||
|
try:
|
||||||
|
bridge_file = import_module(_rules)
|
||||||
|
logger.info('(ROUTER) Routing rules file found and telemetry imported')
|
||||||
|
except ImportError:
|
||||||
|
sys.exit('(ROUTER) TERMINATING: Routing rules file not found or invalid')
|
||||||
|
return bridge_file.TELEMETRY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Run this every minute for rule timer updates
|
# Run this every minute for rule timer updates
|
||||||
@ -462,6 +472,19 @@ class routerHBP(HBSYSTEM):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def play_voice(self, _rf_src, _tgid, _peer, _slot, _speech):
|
||||||
|
speech = pkt_gen(_rf_src, _tgid, _peer, _slot, _speech)
|
||||||
|
|
||||||
|
sleep(1)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
pkt = next(speech)
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
|
sleep(.058)
|
||||||
|
self.send_system(pkt)
|
||||||
|
return None
|
||||||
|
|
||||||
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
||||||
pkt_time = time()
|
pkt_time = time()
|
||||||
dmrpkt = _data[20:53]
|
dmrpkt = _data[20:53]
|
||||||
@ -774,7 +797,9 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# Build the routing rules file
|
# Build the routing rules file
|
||||||
BRIDGES = make_bridges('rules')
|
BRIDGES = make_bridges('rules')
|
||||||
|
# Build the telemetry table
|
||||||
|
TELEMETRY = make_telemetry('rules')
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP
|
# INITIALIZE THE REPORTING LOOP
|
||||||
if CONFIG['REPORTS']['REPORT']:
|
if CONFIG['REPORTS']['REPORT']:
|
||||||
report_server = config_reports(CONFIG, bridgeReportFactory)
|
report_server = config_reports(CONFIG, bridgeReportFactory)
|
||||||
|
195
desconstructor.py
Executable file
195
desconstructor.py
Executable file
@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (C) 2016-2020 Cortney T. Buffington, N0MJS <n0mjs@me.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, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
'''
|
||||||
|
This tool listens to network traffic and breaks apart HBP and DMR packets.
|
||||||
|
|
||||||
|
It is a development and debugging tool and has no purpose in actual production
|
||||||
|
DMR networking systems.
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Python modules we need
|
||||||
|
from binascii import b2a_hex as bhex
|
||||||
|
from bitarray import bitarray
|
||||||
|
|
||||||
|
# Twisted is pretty important, so I keep it separate
|
||||||
|
from twisted.internet.protocol import Factory, Protocol
|
||||||
|
from twisted.internet import reactor
|
||||||
|
|
||||||
|
# Things we import from the main hblink module
|
||||||
|
from hblink import HBSYSTEM, systems, hblink_handler
|
||||||
|
from dmr_utils3.utils import bytes_3, bytes_4, int_id
|
||||||
|
from dmr_utils3 import bptc
|
||||||
|
import config
|
||||||
|
import log
|
||||||
|
from const import *
|
||||||
|
|
||||||
|
|
||||||
|
# REMOVE LATER from datetime import datetime
|
||||||
|
# The module needs logging, but handlers, etc. are controlled by the parent
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
|
||||||
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
__copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
__license__ = 'GNU GPLv3'
|
||||||
|
__maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
|
__email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
|
||||||
|
DUMP_HBP = False
|
||||||
|
DUMP_DMR = True
|
||||||
|
|
||||||
|
# Module gobal varaibles
|
||||||
|
|
||||||
|
class HBP(HBSYSTEM):
|
||||||
|
|
||||||
|
def __init__(self, _name, _config, _report):
|
||||||
|
HBSYSTEM.__init__(self, _name, _config, _report)
|
||||||
|
self.last_stream = b'\x00\x00\x00\x00'
|
||||||
|
self.lcfrags = 0
|
||||||
|
self.lostcount = 0
|
||||||
|
|
||||||
|
|
||||||
|
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
||||||
|
|
||||||
|
pktype = 'UNIDENTIFIED'
|
||||||
|
|
||||||
|
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM):
|
||||||
|
pktype = 'VTERM '
|
||||||
|
|
||||||
|
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VHEAD):
|
||||||
|
pktype = 'VHEAD '
|
||||||
|
|
||||||
|
if (_frame_type == HBPF_VOICE_SYNC):
|
||||||
|
pktype = 'VOICE SYNC ' + str(_dtype_vseq + 1)
|
||||||
|
|
||||||
|
if (_frame_type == HBPF_VOICE):
|
||||||
|
pktype = 'VOICE ' + str(_dtype_vseq + 1)
|
||||||
|
|
||||||
|
if DUMP_HBP:
|
||||||
|
print('STREAM: {} SEQ: {} PEER: {} SRC: {} DST: {} SLOT: {} CALL: {} FRAME: {} DTYPE: {}'.format(
|
||||||
|
int_id(_stream_id), int_id(_seq), int_id(_peer_id), int_id(_rf_src), int_id(_dst_id), _slot, pktype, _frame_type, _dtype_vseq
|
||||||
|
))
|
||||||
|
|
||||||
|
if DUMP_DMR:
|
||||||
|
payload = _data[20:53]
|
||||||
|
bitload = bitarray(endian='big')
|
||||||
|
bitload.frombytes(payload)
|
||||||
|
if pktype == ('VHEAD '):
|
||||||
|
LC = bptc.decode_full_lc(bitload[:98] + bitload[-98:]).tobytes()
|
||||||
|
OPT = bhex(LC[0:3])
|
||||||
|
DST = int_id(LC[3:6])
|
||||||
|
SRC = int_id(LC[6:9])
|
||||||
|
|
||||||
|
ST = bin(int.from_bytes((bitload[98:109] + bitload[-108:-99])[:8].tobytes(), 'big'))
|
||||||
|
SC = bhex(bitload[108:-108].tobytes())
|
||||||
|
|
||||||
|
print('VOICE HEADER: LC:(OPTIONS: {} DEST: {} SOURCE: {}) -- SLOT TYPE: {} -- SYNC: {}'.format(OPT, DST, SRC, ST, SC))
|
||||||
|
|
||||||
|
elif pktype == ('VTERM '):
|
||||||
|
LC = bptc.decode_full_lc(bitload[:98] + bitload[-98:]).tobytes()
|
||||||
|
OPT = bhex(LC[0:3])
|
||||||
|
DST = int_id(LC[3:6])
|
||||||
|
SRC = int_id(LC[6:9])
|
||||||
|
|
||||||
|
ST = bin(int.from_bytes((bitload[98:109] + bitload[-108:-99])[:8].tobytes(), 'big'))
|
||||||
|
SC = bhex(bitload[108:-108].tobytes())
|
||||||
|
|
||||||
|
print('VOICE TERMINATOR: LC:(OPTIONS: {} DEST: {} SOURCE: {}) -- SLOT TYPE: {} -- SYNC: {}'.format(OPT, DST, SRC, ST, SC))
|
||||||
|
|
||||||
|
elif pktype == ('VOICE SYNC 1'):
|
||||||
|
self.lcfrags=0
|
||||||
|
print('Voice Burst A')
|
||||||
|
BVC = bitload[0:108] + bitload[-108:]
|
||||||
|
BSC = bitload[108:-108]
|
||||||
|
self.lcfrags = 0
|
||||||
|
|
||||||
|
elif 'VOICE ' in pktype:
|
||||||
|
print('Voice Burst B-F')
|
||||||
|
BVC = bitload[0:108] + bitload[-108:]
|
||||||
|
BEB = bitload[108:116] + bitload[-116:-108]
|
||||||
|
BES = bitload[116:-116]
|
||||||
|
print(len(BVC), len(BEB), len(BES))
|
||||||
|
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# MAIN PROGRAM LOOP STARTS HERE
|
||||||
|
#************************************************
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
|
||||||
|
# Change the current directory to the location of the application
|
||||||
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
|
||||||
|
# CLI argument parser - handles picking up the config file from the command line, and sending a "help" message
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-c', '--config', action='store', dest='CONFIG_FILE', help='/full/path/to/config.file (usually deconstructor.cfg)')
|
||||||
|
parser.add_argument('-l', '--logging', action='store', dest='LOG_LEVEL', help='Override config file logging level.')
|
||||||
|
cli_args = parser.parse_args()
|
||||||
|
|
||||||
|
# Ensure we have a path for the config file, if one wasn't specified, then use the default (top of file)
|
||||||
|
if not cli_args.CONFIG_FILE:
|
||||||
|
cli_args.CONFIG_FILE = os.path.dirname(os.path.abspath(__file__))+'/hblink.cfg'
|
||||||
|
|
||||||
|
# Call the external routine to build the configuration dictionary
|
||||||
|
CONFIG = config.build_config(cli_args.CONFIG_FILE)
|
||||||
|
|
||||||
|
# Start the system logger
|
||||||
|
if cli_args.LOG_LEVEL:
|
||||||
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
|
logger = log.config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('\n\nCopyright (c) 2013, 2014, 2015, 2016, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n')
|
||||||
|
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')
|
||||||
|
|
||||||
|
# Set up the signal handler
|
||||||
|
def sig_handler(_signal, _frame):
|
||||||
|
logger.info('(GLOBAL) SHUTDOWN: DECONSTRUCTOR IS TERMINATING WITH SIGNAL %s', str(_signal))
|
||||||
|
hblink_handler(_signal, _frame)
|
||||||
|
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
|
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||||
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = None
|
||||||
|
|
||||||
|
# HBlink instance creation
|
||||||
|
logger.info('(GLOBAL) HBlink \'hbp_deconstructor.py\' -- SYSTEM STARTING...')
|
||||||
|
for system in CONFIG['SYSTEMS']:
|
||||||
|
if CONFIG['SYSTEMS'][system]['ENABLED']:
|
||||||
|
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER' or CONFIG['SYSTEMS'][system]['MODE'] == 'PEER':
|
||||||
|
systems[system] = HBP(system, CONFIG, report_server)
|
||||||
|
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
|
||||||
|
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
|
||||||
|
|
||||||
|
def loopingErrHandle(failure):
|
||||||
|
logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error in timed loop.\n %s', failure)
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
|
reactor.run()
|
188
extract_ambe.py
Executable file
188
extract_ambe.py
Executable file
@ -0,0 +1,188 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS <n0mjs@me.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, write to the Free Software Foundation,
|
||||||
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
'''
|
||||||
|
This module is used to extract the AMBE72, FEC encoded data needed to make DMR
|
||||||
|
frames. It prints out a list of lists, the outer list contains the word and each
|
||||||
|
of the inner lists has two elements that comprise the 3 AMBE frames sent in each
|
||||||
|
DMR packet. The frames are split into 1.5 frames and 1.5 frames, that is to say
|
||||||
|
the two 108 bit segments used in DMR bursts.
|
||||||
|
|
||||||
|
This program is intended to produce the data needed to build words (or phrases)
|
||||||
|
that can be used to populate the voice_lib.py file. It does not write the file
|
||||||
|
for you, you must copy the output and paste them into the file. Most of the
|
||||||
|
formatting, but not all, is done for you.
|
||||||
|
|
||||||
|
It will not process OpenBridge systems, and it is strongly recommended you only
|
||||||
|
use it with one system in the hblink.cfg file at a time -- otherwise things can
|
||||||
|
get really out of hand quickly.
|
||||||
|
|
||||||
|
This is a program for ADVANCED USERS ONLY. I really mean it this time, if you're
|
||||||
|
not comfortable with how DMR packets are structured and basic Python, this isn't
|
||||||
|
going to work well for you.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
# Python modules we need
|
||||||
|
from bitarray import bitarray
|
||||||
|
|
||||||
|
# Twisted is pretty important, so I keep it separate
|
||||||
|
from twisted.internet.protocol import Factory, Protocol
|
||||||
|
from twisted.internet import reactor
|
||||||
|
|
||||||
|
# Things we import from the main hblink module
|
||||||
|
from hblink import HBSYSTEM, systems, hblink_handler
|
||||||
|
from dmr_utils3.utils import int_id
|
||||||
|
import config
|
||||||
|
import log
|
||||||
|
|
||||||
|
# The module needs logging, but handlers, etc. are controlled by the parent
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
|
||||||
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
__copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
__credits__ = 'Colin Durbridge, G4EML, Steve Zingman, N4IRS; Mike Zingman, N4IRR; Jonathan Naylor, G4KLX; Hans Barthen, DL5DI; Torsten Shultze, DG1HT'
|
||||||
|
__license__ = 'GNU GPLv3'
|
||||||
|
__maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
|
__email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
# Module gobal varaibles
|
||||||
|
# Precalculated "dmrbits" (DMRD packet byte 15) -- just (slot << 7 | this value) and you're good to go!
|
||||||
|
HEADBITS = 0b00100001
|
||||||
|
BURSTBITS = [0b00010000,0b00000001,0b00000010,0b00000011,0b00000100,0b00000101]
|
||||||
|
TERMBITS = 0b00100010
|
||||||
|
|
||||||
|
|
||||||
|
class HBP(HBSYSTEM):
|
||||||
|
|
||||||
|
def __init__(self, _name, _config, _report):
|
||||||
|
HBSYSTEM.__init__(self, _name, _config, _report)
|
||||||
|
self.current_stream = '\x00'
|
||||||
|
|
||||||
|
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
||||||
|
|
||||||
|
dmr = _data[20:53]
|
||||||
|
bits = _data[15] & ~(1<<7)
|
||||||
|
|
||||||
|
dmrraw = bitarray(endian='big')
|
||||||
|
dmrraw.frombytes(dmr)
|
||||||
|
|
||||||
|
if bits == HEADBITS:
|
||||||
|
if self.current_stream != _stream_id:
|
||||||
|
print('START STREAM ID {} ON SLOT {} FROM SUBSCRIBER {} TO GROUP {}'.format(int_id(_stream_id), _slot, int_id(_rf_src), int_id(_dst_id)))
|
||||||
|
print('[')
|
||||||
|
self.current_stream = _stream_id
|
||||||
|
|
||||||
|
if bits == TERMBITS:
|
||||||
|
if self.current_stream == _stream_id:
|
||||||
|
print(' ]')
|
||||||
|
print('STOP STREAM ID {}'.format(int_id(_stream_id)))
|
||||||
|
self.current_stream = '\x00'
|
||||||
|
|
||||||
|
if bits == BURSTBITS[0]:
|
||||||
|
bts = 'Burst A'
|
||||||
|
sig = [dmrraw[:108], dmrraw[-108:]]
|
||||||
|
print(' {},'.format(sig))
|
||||||
|
if bits == BURSTBITS[1]:
|
||||||
|
bts = 'Burst B'
|
||||||
|
sig = [dmrraw[:108], dmrraw[-108:]]
|
||||||
|
print(' {},'.format(sig))
|
||||||
|
if bits == BURSTBITS[2]:
|
||||||
|
bts = 'Burst C'
|
||||||
|
sig = [dmrraw[:108], dmrraw[-108:]]
|
||||||
|
print(' {},'.format(sig))
|
||||||
|
if bits == BURSTBITS[3]:
|
||||||
|
bts = 'Burst D'
|
||||||
|
sig = [dmrraw[:108], dmrraw[-108:]]
|
||||||
|
print(' {},'.format(sig))
|
||||||
|
if bits == BURSTBITS[4]:
|
||||||
|
bts = 'Burst E'
|
||||||
|
sig = [dmrraw[:108], dmrraw[-108:]]
|
||||||
|
print(' {},'.format(sig))
|
||||||
|
if bits == BURSTBITS[5]:
|
||||||
|
bts = 'Burst F'
|
||||||
|
sig = [dmrraw[:108], dmrraw[-108:]]
|
||||||
|
print(' {},'.format(sig))
|
||||||
|
|
||||||
|
#************************************************
|
||||||
|
# MAIN PROGRAM LOOP STARTS HERE
|
||||||
|
#************************************************
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import signal
|
||||||
|
|
||||||
|
# Change the current directory to the location of the application
|
||||||
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
|
||||||
|
# CLI argument parser - handles picking up the config file from the command line, and sending a "help" message
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-c', '--config', action='store', dest='CONFIG_FILE', help='/full/path/to/config.file (usually hblink.cfg)')
|
||||||
|
parser.add_argument('-l', '--logging', action='store', dest='LOG_LEVEL', help='Override config file logging level.')
|
||||||
|
cli_args = parser.parse_args()
|
||||||
|
|
||||||
|
# Ensure we have a path for the config file, if one wasn't specified, then use the default (top of file)
|
||||||
|
if not cli_args.CONFIG_FILE:
|
||||||
|
cli_args.CONFIG_FILE = os.path.dirname(os.path.abspath(__file__))+'/hblink.cfg'
|
||||||
|
|
||||||
|
# Call the external routine to build the configuration dictionary
|
||||||
|
CONFIG = config.build_config(cli_args.CONFIG_FILE)
|
||||||
|
|
||||||
|
# Start the system logger
|
||||||
|
if cli_args.LOG_LEVEL:
|
||||||
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
|
logger = log.config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('\n\nCopyright (c) 2013, 2014, 2015, 2016, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n')
|
||||||
|
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')
|
||||||
|
|
||||||
|
# Set up the signal handler
|
||||||
|
def sig_handler(_signal, _frame):
|
||||||
|
logger.info('(GLOBAL) SHUTDOWN: CONFBRIDGE IS TERMINATING WITH SIGNAL %s', str(_signal))
|
||||||
|
hblink_handler(_signal, _frame)
|
||||||
|
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
|
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||||
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = None
|
||||||
|
|
||||||
|
# HBlink instance creation
|
||||||
|
logger.info('(GLOBAL) HBlink \'bridge.py\' -- SYSTEM STARTING...')
|
||||||
|
for system in CONFIG['SYSTEMS']:
|
||||||
|
if CONFIG['SYSTEMS'][system]['ENABLED']:
|
||||||
|
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER' or CONFIG['SYSTEMS'][system]['MODE'] == 'PEER':
|
||||||
|
systems[system] = HBP(system, CONFIG, report_server)
|
||||||
|
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
|
||||||
|
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
|
||||||
|
|
||||||
|
def loopingErrHandle(failure):
|
||||||
|
logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error in timed loop.\n %s', failure)
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
|
reactor.run()
|
22
mk_voice.py
22
mk_voice.py
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS <n0mjs@me.com>
|
# Copyright (C) 2016-2020 Cortney T. Buffington, N0MJS <n0mjs@me.com>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -21,10 +21,11 @@
|
|||||||
from bitarray import bitarray
|
from bitarray import bitarray
|
||||||
from dmr_utils3 import bptc, golay, qr
|
from dmr_utils3 import bptc, golay, qr
|
||||||
from dmr_utils3.utils import bytes_3, bytes_4
|
from dmr_utils3.utils import bytes_3, bytes_4
|
||||||
from dmr_utils3.const import EMB, SLOT_TYPE, BS_VOICE_SYNC, BS_DATA_SYNC, LC_OPT
|
from dmr_utils3.const import EMB, SLOT_TYPE, BS_VOICE_SYNC, BS_DATA_SYNC, LC_OPT_G
|
||||||
from random import randint
|
from random import randint
|
||||||
from voice_lib import words
|
from voice_lib import words
|
||||||
|
|
||||||
|
|
||||||
# Precalculated "dmrbits" (DMRD packet byte 15) -- just (slot << 7 | this value) and you're good to go!
|
# Precalculated "dmrbits" (DMRD packet byte 15) -- just (slot << 7 | this value) and you're good to go!
|
||||||
HEADBITS = 0b00100001
|
HEADBITS = 0b00100001
|
||||||
BURSTBITS = [0b00010000,0b00000001,0b00000010,0b00000011,0b00000100,0b00000101]
|
BURSTBITS = [0b00010000,0b00000001,0b00000010,0b00000011,0b00000100,0b00000101]
|
||||||
@ -44,7 +45,7 @@ def pkt_gen(_rf_src, _dst_id, _peer, _slot, _phrase):
|
|||||||
# Calculate all of the static components up-front
|
# Calculate all of the static components up-front
|
||||||
STREAM_ID = bytes_4(randint(0x00, 0xFFFFFFFF))
|
STREAM_ID = bytes_4(randint(0x00, 0xFFFFFFFF))
|
||||||
SDP = _rf_src + _dst_id + _peer
|
SDP = _rf_src + _dst_id + _peer
|
||||||
LC = LC_OPT + _dst_id + _rf_src
|
LC = LC_OPT_G + _dst_id + _rf_src
|
||||||
|
|
||||||
HEAD_LC = bptc.encode_header_lc(LC)
|
HEAD_LC = bptc.encode_header_lc(LC)
|
||||||
HEAD_LC = [HEAD_LC[:98], HEAD_LC[-98:]]
|
HEAD_LC = [HEAD_LC[:98], HEAD_LC[-98:]]
|
||||||
@ -63,6 +64,7 @@ def pkt_gen(_rf_src, _dst_id, _peer, _slot, _phrase):
|
|||||||
EMBED.append(EMB['BURST_F'][:8] + NULL_EMB_LC + EMB['BURST_F'][-8:])
|
EMBED.append(EMB['BURST_F'][:8] + NULL_EMB_LC + EMB['BURST_F'][-8:])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#initialize the HBP calls stream sequence to 0
|
#initialize the HBP calls stream sequence to 0
|
||||||
SEQ = 0
|
SEQ = 0
|
||||||
|
|
||||||
@ -77,15 +79,15 @@ def pkt_gen(_rf_src, _dst_id, _peer, _slot, _phrase):
|
|||||||
# Send each burst, six bursts per Superframe rotating through with the proper EMBED value per burst A-F
|
# Send each burst, six bursts per Superframe rotating through with the proper EMBED value per burst A-F
|
||||||
for word in _phrase:
|
for word in _phrase:
|
||||||
for burst in range(0, len(word)):
|
for burst in range(0, len(word)):
|
||||||
print(burst)
|
pkt = b'DMRD' + bytes([SEQ]) + SDP + bytes([_slot << 7 | BURSTBITS[burst % 6]]) + STREAM_ID + (word[burst][0] + EMBED[burst % 6] + word[burst][1]).tobytes() + TAIL
|
||||||
pkt = b'DMRD' + bytes([SEQ]) + SDP + bytes([_slot << 7 | BURSTBITS[burst % 6]]) + STREAM_ID + (word[burst + 0][0] + EMBED[burst % 6] + word[burst + 0][1]).tobytes() + TAIL
|
|
||||||
SEQ = (SEQ + 1) % 0x100
|
SEQ = (SEQ + 1) % 0x100
|
||||||
yield pkt
|
yield pkt
|
||||||
|
|
||||||
# Send a single Voice Terminator Frame
|
# Send 2 Voice Terminator Frames
|
||||||
pkt = b'DMRD' + bytes([SEQ]) + SDP + bytes([_slot << 7 | TERMBITS]) + STREAM_ID + (TERM_LC[0] + SLOT_TYPE['VOICE_LC_TERM'][:10] + BS_DATA_SYNC + SLOT_TYPE['VOICE_LC_TERM'][-10:] + TERM_LC[1]).tobytes() + TAIL
|
for i in range(2):
|
||||||
SEQ = (SEQ + 1) % 0x100
|
pkt = b'DMRD' + bytes([SEQ]) + SDP + bytes([_slot << 7 | TERMBITS]) + STREAM_ID + (TERM_LC[0] + SLOT_TYPE['VOICE_LC_TERM'][:10] + BS_DATA_SYNC + SLOT_TYPE['VOICE_LC_TERM'][-10:] + TERM_LC[1]).tobytes() + TAIL
|
||||||
yield pkt
|
SEQ = (SEQ + 1) % 0x100
|
||||||
|
yield pkt
|
||||||
|
|
||||||
# Return False to indicate we're done.
|
# Return False to indicate we're done.
|
||||||
return False
|
return False
|
||||||
@ -94,7 +96,7 @@ def pkt_gen(_rf_src, _dst_id, _peer, _slot, _phrase):
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
speech = pkt_gen(bytes_3(3120101), bytes_3(3120), bytes_4(312000), 0, [words['all_circuits'], words['all_circuits']])
|
speech = pkt_gen(bytes_3(3120101), bytes_3(3120), bytes_4(312000), 0, [words['connected']])
|
||||||
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
97
play_ambe.py
97
play_ambe.py
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS <n0mjs@me.com>
|
# Copyright (C) 2016-2020 Cortney T. Buffington, N0MJS <n0mjs@me.com>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -18,30 +18,43 @@
|
|||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
'''
|
||||||
|
This is a short program that is intended to be used only to validate voice entries
|
||||||
|
in the voice_lib.py file. It should only be used for building voice libraries and
|
||||||
|
only used during development to validate the entires.
|
||||||
|
|
||||||
|
It uses a number of hard-coded parameters, like the voice files to play back, the
|
||||||
|
slot, talkgroup, source, etc. of the originating stream.
|
||||||
|
|
||||||
|
It is not for novices to use, and should only be used by those comfortable with
|
||||||
|
how DMR packets are build and Python. It does not handle OpenBridge systems, only
|
||||||
|
HBP systems, and it is HIGHLY recommended to only use it against a single system
|
||||||
|
at a time.
|
||||||
|
|
||||||
|
It is a development and debugging tool and has no purpose in actual production
|
||||||
|
DMR networking systems.
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
# Python modules we need
|
# Python modules we need
|
||||||
import sys
|
from time import sleep
|
||||||
from bitarray import bitarray
|
|
||||||
from time import time, sleep
|
|
||||||
from importlib import import_module
|
|
||||||
from binascii import b2a_hex as bhex
|
from binascii import b2a_hex as bhex
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
# Twisted is pretty important, so I keep it separate
|
# Twisted is pretty important, so I keep it separate
|
||||||
from twisted.internet.protocol import Factory, Protocol
|
from twisted.internet.protocol import Factory, Protocol
|
||||||
from twisted.protocols.basic import NetstringReceiver
|
from twisted.internet import reactor
|
||||||
from twisted.internet import reactor, task
|
|
||||||
|
|
||||||
# Things we import from the main hblink module
|
# Things we import from the main hblink module
|
||||||
from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases
|
from hblink import HBSYSTEM, systems, hblink_handler
|
||||||
from dmr_utils3.utils import bytes_3, bytes_4, int_id, get_alias
|
from dmr_utils3.utils import bytes_3, bytes_4, int_id
|
||||||
from dmr_utils3 import decode, bptc, const
|
|
||||||
import config
|
import config
|
||||||
import log
|
import log
|
||||||
from const import *
|
from const import *
|
||||||
from mk_voice import pkt_gen
|
from mk_voice import pkt_gen
|
||||||
from voice_lib import words
|
from voice_lib import words
|
||||||
|
|
||||||
# Stuff for socket reporting
|
|
||||||
import pickle
|
|
||||||
# REMOVE LATER from datetime import datetime
|
# REMOVE LATER from datetime import datetime
|
||||||
# The module needs logging, but handlers, etc. are controlled by the parent
|
# The module needs logging, but handlers, etc. are controlled by the parent
|
||||||
import logging
|
import logging
|
||||||
@ -58,41 +71,31 @@ __email__ = 'n0mjs@me.com'
|
|||||||
|
|
||||||
# Module gobal varaibles
|
# Module gobal varaibles
|
||||||
|
|
||||||
|
|
||||||
class OBP(OPENBRIDGE):
|
|
||||||
|
|
||||||
def __init__(self, _name, _config, _report):
|
|
||||||
OPENBRIDGE.__init__(self, _name, _config, _report)
|
|
||||||
|
|
||||||
|
|
||||||
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class HBP(HBSYSTEM):
|
class HBP(HBSYSTEM):
|
||||||
|
|
||||||
def __init__(self, _name, _config, _report):
|
def __init__(self, _name, _config, _report):
|
||||||
HBSYSTEM.__init__(self, _name, _config, _report)
|
HBSYSTEM.__init__(self, _name, _config, _report)
|
||||||
self.last_stream = b'\x00'
|
self.last_stream = b'\x00'
|
||||||
|
|
||||||
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
def play_voice(self, _rf_src, _tgid, _peer, _slot, _speech):
|
||||||
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (_stream_id != self.last_stream):
|
speech = pkt_gen(_rf_src, _tgid, _peer, _slot, _speech)
|
||||||
print(int_id(_stream_id), int_id(self.last_stream))
|
|
||||||
self.last_stream = _stream_id
|
|
||||||
print('start speech')
|
|
||||||
speech = pkt_gen(bytes_3(3120101), bytes_3(2), bytes_4(3120119), 0, [words['all_circuits'],words['all_circuits']])
|
|
||||||
|
|
||||||
sleep(1)
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
pkt = next(speech)
|
|
||||||
except StopIteration:
|
|
||||||
break
|
|
||||||
sleep(.058)
|
|
||||||
self.send_system(pkt)
|
|
||||||
print(bhex(pkt))
|
|
||||||
print('end speech')
|
|
||||||
|
|
||||||
|
sleep(1)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
pkt = next(speech)
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
|
sleep(.058)
|
||||||
|
self.send_system(pkt)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
|
||||||
|
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (_stream_id != self.last_stream) and (_dst_id == bytes_3(2)):
|
||||||
|
self.last_stream = _stream_id
|
||||||
|
|
||||||
|
feedback = Thread(target=self.play_voice(bytes_3(3120102), bytes_3(2), bytes_4(3120119), 0, [words['connected'], words['kansas_link']]))
|
||||||
|
feedback.start()
|
||||||
|
|
||||||
|
|
||||||
#************************************************
|
#************************************************
|
||||||
@ -140,23 +143,14 @@ if __name__ == '__main__':
|
|||||||
for sig in [signal.SIGINT, signal.SIGTERM]:
|
for sig in [signal.SIGINT, signal.SIGTERM]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
# Create the name-number mapping dictionaries
|
|
||||||
peer_ids, subscriber_ids, talkgroup_ids = mk_aliases(CONFIG)
|
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP
|
# INITIALIZE THE REPORTING LOOP
|
||||||
if CONFIG['REPORTS']['REPORT']:
|
report_server = None
|
||||||
report_server = config_reports(CONFIG, bridgeReportFactory)
|
|
||||||
else:
|
|
||||||
report_server = None
|
|
||||||
logger.info('(REPORT) TCP Socket reporting not configured')
|
|
||||||
|
|
||||||
# HBlink instance creation
|
# HBlink instance creation
|
||||||
logger.info('(GLOBAL) HBlink \'bridge.py\' -- SYSTEM STARTING...')
|
logger.info('(GLOBAL) HBlink \'bridge.py\' -- SYSTEM STARTING...')
|
||||||
for system in CONFIG['SYSTEMS']:
|
for system in CONFIG['SYSTEMS']:
|
||||||
if CONFIG['SYSTEMS'][system]['ENABLED']:
|
if CONFIG['SYSTEMS'][system]['ENABLED']:
|
||||||
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
|
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER' or CONFIG['SYSTEMS'][system]['MODE'] == 'PEER':
|
||||||
systems[system] = OBP(system, CONFIG, report_server)
|
|
||||||
else:
|
|
||||||
systems[system] = HBP(system, CONFIG, report_server)
|
systems[system] = HBP(system, CONFIG, report_server)
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
|
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
|
||||||
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
|
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
|
||||||
@ -165,5 +159,4 @@ if __name__ == '__main__':
|
|||||||
logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error in timed loop.\n %s', failure)
|
logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error in timed loop.\n %s', failure)
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
|
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
@ -47,6 +47,20 @@ BRIDGES = {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TELEMETRY = {
|
||||||
|
'WORLDWIDE': [
|
||||||
|
{'SYSTEM': 'MASTER-1', 'ON': [], 'OFF': []}
|
||||||
|
],
|
||||||
|
'ENGLISH': [
|
||||||
|
{'SYSTEM': 'MASTER-1', 'ON': [], 'OFF': []},
|
||||||
|
{'SYSTEM': 'REPEATER-1', 'ON': [], 'OFF': []}
|
||||||
|
],
|
||||||
|
'STATEWIDE': [
|
||||||
|
{'SYSTEM': 'MASTER-1', 'ON': [], 'OFF': []},
|
||||||
|
{'SYSTEM': 'REPEATER-1', 'ON': [], 'OFF': []}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
pprint(BRIDGES)
|
pprint(BRIDGES)
|
||||||
|
213
voice_lib.py
213
voice_lib.py
@ -1,146 +1,79 @@
|
|||||||
|
'''
|
||||||
|
This is a voice file library that is used by other programs so that
|
||||||
|
hblink can "talk" and provide voice feedback for users. It does nothing
|
||||||
|
on it's own, but is called by programs that need to create their own
|
||||||
|
voice feedback for users -- like to notify of system events, etc.
|
||||||
|
|
||||||
|
The format is already HIGHLY processed to make assembly of DMR packets
|
||||||
|
quick and easy on the fly. DMR voice packets each contain 3 AMBE
|
||||||
|
frames. They are 72bit FEC encoded and they are combined so that
|
||||||
|
1.5 of the frames fit on each side of the control information in the
|
||||||
|
center of the packet.
|
||||||
|
'''
|
||||||
|
|
||||||
from bitarray import bitarray
|
from bitarray import bitarray
|
||||||
|
|
||||||
words = {
|
words = {
|
||||||
'all_circuits': [
|
'kansas_link': [
|
||||||
[bitarray('001011000001010000100010001001011111101010110000110001100010011001011000001010010000000100000111010000111101'), bitarray('100101001000101100110100111010010101011010110100001001100010000001111001101000010010000101110010111000101011')],
|
[bitarray('111111101110010010000001000001110111000100000111000111111101010111101011111111011100011110000011001101010011'), bitarray('010100010000010011111000011110001001110010100011100110000010011001100001001001010111100111011100010101010011')],
|
||||||
[bitarray('000010010000010101100110000100000010111101001010001111000010001100111011001111010110010000100100110101000111'), bitarray('001000001000100101100010010100100010001111010110011111000110001100100111000110100100110111100011001010011000')],
|
[bitarray('111110000001101110100011000001010010001000000010110011111111001100100101111011111111010010000011001101110001'), bitarray('010000010000000011001001010111001110111011101100011110100011011100010111010101000001010011001010000110101100')],
|
||||||
[bitarray('111111110010101010101001111000111010110110011010011000001001110011011101001110000011001101111010100001111111'), bitarray('010101101001110001010011011000111111000011000011011100000011011001011011100111110010111001100001000000111111')],
|
[bitarray('111111101101010110100010000101110111000001000111001010111101001011111111111111011100010010000011001100110001'), bitarray('001100110101010110011101001011011000111111111110011010100001010100010011001100110100011011001110000111101111')],
|
||||||
[bitarray('001010110011001000100111010100101001100101101010101000100101110110000001010111110001111001000110000000101110'), bitarray('000010110010010111110111111100101110001010100010101101000101000010100111000101001101111000001011010000000011')],
|
[bitarray('111011101110011010100010000101110001000000000101000010001000011011111010111111011100010110100001011100110101'), bitarray('000001010111010110101101000111011010110111111100010110000001010100010001011001010001011111111110011111111011')],
|
||||||
[bitarray('010011010001100000101011110101010011011001101000011100101010001100110110000010100111111001101000101000000010'), bitarray('011011111110101000011001100000000111000011101001010110101000010101111000101110101010001101100001100111010000')],
|
[bitarray('110111101101010010000001010100110111001100100111010011011000000010011111110011111110010110100011011101010011'), bitarray('010100100101010011111101000011111001111011001100010010100011011100110111000001000111000010111010011110101111')],
|
||||||
[bitarray('011111010010011100111010111110010110101001101100100010110000011000101011000111000100001001011000000100111111'), bitarray('000010010011100011001101101101101111000110000101101001000110001000111000111010101111001011111111111000000000')],
|
[bitarray('010011101101110010000101011001000001000000110011110010000010111101100111111001101011100111000101010100100110'), bitarray('000101100111000010111000111000111110110101111000101011100110011101000100010000010001001111001100101100111110')],
|
||||||
[bitarray('010111101111010000000011000001101100111111000101011011001011101001100010001010111010000100000001011100111010'), bitarray('011110001000001110000010111101001111000011111100110100100110011001111100110100101100011100110001101000111111')],
|
[bitarray('110001001001101111000101001101000100010000010101000011001010101100101001000011000000111010100101010101010011'), bitarray('010101010110010001011010000100011100001111110010111110000111010100100010001100110001010000001011011000011000')],
|
||||||
[bitarray('010010011010101100000110011100101011010100000111001101001110100001110101001111001111101000100101001101110110'), bitarray('000110000010000010011011111011101001111100110000000100000000000001000110011110101011100011010001110111100111')],
|
[bitarray('000011000001110010100110001101100000000000100000011101011111000001001101000011010011111010100101000101000110'), bitarray('011101110100010000011010010100011000101100101011010111100101011000000100010001100110010000100101001110101011')],
|
||||||
[bitarray('111001100001010000001010100000000101001011011111000111111111011110001001010110111100000101111001101101001001'), bitarray('011000101100011110011101100100110111000011110001101001111001001001111100111110101010101100101111001011000000')],
|
[bitarray('110101011010101111000101011000100110001000110011000111111000111100101111101000001011011011000111000001000011'), bitarray('001000000001010000000111000111011001100100101011010111100110000001100111001000100011000001110000010111011011')],
|
||||||
[bitarray('011011010000111000010110001000101100101001101011111110111110010000100111010010110110000101100011001100101001'), bitarray('111001100010011101110111100100111110000010000001001100000111001001011001101001001011101100010011111111000001')],
|
[bitarray('101000001000011011100101000001000101010000000001000101110001011011001100111100010110010011000101010000100100'), bitarray('010101110011110011011000110110100111110011011111011010000011011101110101010001010001000111101111010111111111')],
|
||||||
[bitarray('011110110101001101000000010100001011101000010001001101010010101100111010010110010111100001000101101001000111'), bitarray('111011000111011011010010010011001110010110110000111001101010000111110011101001100010011010000010101110101101')],
|
[bitarray('110111001110010110100011010100110101000100100110001011011000001110001101110111011100010010100001000100010011'), bitarray('000100110000000110011110011110101011110101011000100111000101001001110001010100010001011111001101101000001101')],
|
||||||
[bitarray('011010011101000101101000101001111000000101101010010111011001110001010001000010110101100000011011100101111011'), bitarray('000110111010011111001001010111001011011010100010101100001000011110111111110100000111101100010101010100100111')],
|
[bitarray('111001001001101011100110010001110001000000100101011111011000111000101011101111010100000010010101110001110000'), bitarray('010101110000111111011010110100111001100101010011100111100010111101001111100110011001101000100110001100011111')],
|
||||||
[bitarray('001110101010000100000001000000011111011110111011011111000111100100011011010110101101001001000111001101011101'), bitarray('001110000011100011000100110111000111011111001001110100000010010001001010010010101111010101111000011011111011')],
|
[bitarray('101001001010100011000100110000001001000101111111001110000011010010000001101000000100110010000010001101000110'), bitarray('100001000001011101111100011111110001100000010100111111100001010100000100011110111010100100100111111110111011')],
|
||||||
[bitarray('001011101111111001000100011000001101000111100010110101001110000101000110011011101001101101100001011000010100'), bitarray('010010001111110111101001101101110110000010011110110001100010010000010000110011100010101011000011110000011000')],
|
[bitarray('101101011000001011100010000000110010001010111101011100010111111100100010110000111110000100000111010110001111'), bitarray('011010101001110011110000001101111001101100111010000101000001010111101001011011010111000110110001001110100111')],
|
||||||
[bitarray('010110011011111100001101010011000111110001001011000101011011011001011000000010111111010101001000011101111101'), bitarray('111111111011010100001110001101011000010011001101011100110011011101011101100010110000001111001100100000000010')],
|
[bitarray('100101111101001001010111001100111000000000000100110110001001011110001100110101101010000000000000011101011001'), bitarray('000001001110000110111001000001010111100000001110011101100000000101111011001111011001110110001011111001110111')],
|
||||||
[bitarray('001010011100101100100000000001001111101011100110010101000111010010100011011011111001110001000011001001011111'), bitarray('110000100100101001000101111111100011010011001010110001000011011101101100100101100111110000000110101110010001')],
|
[bitarray('110001001000000000000010000100011001001100111101010010001011000100010111111001001001010100000010001100110010'), bitarray('100110110101000101110000000010000001110101101010011001101010001110100111001110101111111111110001011001110000')],
|
||||||
[bitarray('010011111111100001100111110101011100111100100111110010011111101100011100110100100111000101100100100001001010'), bitarray('011011111010000010001011010111000100110001000001000001101111001010101011000011110111000011001011001100101111')],
|
[bitarray('110001101010010001101001000110000011000111101111110011000110011101100001100100101101000101101010010110010101'), bitarray('110110100010100010111100001000011011111100111000110101101100010000010111110101110011010100111100100110010001')],
|
||||||
[bitarray('111101100010001101101100011010011111011010000110000110011011010101011000111100110010010001101000000111011100'), bitarray('010000001110011111011101111010010111100001100000110001101100101000000110100111011100101000011100111011101111')],
|
[bitarray('101010000110011000101100110001100000111000110000111001011010100110100111111100101101101101011001111100110010'), bitarray('110100010011000011110110110100111010100100101011001001011001010100101001000100010010000100111101110100011000')],
|
||||||
[bitarray('101001000000100001101110111000101111000001110100110011000011100101011010110101100101111000001010111001110010'), bitarray('110110000100001101011000100000100100101001000111101101010100111000110000111101100000001010011000101010110111')],
|
[bitarray('101001101000011001100101001011001100001100111000001111110100110001101011111000000111111100100011000100001101'), bitarray('001101111000101111111101000111101001101100000011111001000111000101111110001100110000001110111100010000110010')],
|
||||||
[bitarray('111100100010111001101111111011110110000010101100010000011000011100100100110000100011110001101111110111010100'), bitarray('001010001110010000011011011101000100110100110000111101001110111111010110001010001110010000011010001100010111')],
|
[bitarray('101000101100001101000011000001110100110101010101100001110110100110010001110101001110001101001100111110100010'), bitarray('011110111110100101001010000110111111101001111001001011000011001100000100001110001000011001100010111100100110')],
|
||||||
[bitarray('101000100110111100101001110110110110010010000110110001011101000111011001101100010100111100001000110111110110'), bitarray('011011100101111000011101000111011001101101110110100100101100111111110001010001001111110100011000100100100011')],
|
[bitarray('101101101011000110000000010001000100101100100000111000111010010101111111101101011001000011000000010001000100'), bitarray('011111111010011101100001101001000001110010001100001010000110011001110000010011011001010010111100110000110010')],
|
||||||
[bitarray('100001110100101011110100010100010001011000110100100000010100001100010111101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
[bitarray('101000000110111111100010001101100011001110101011101100100111110110011101100100110100111111100000000100100001'), bitarray('011010001100100000010100101110111011111001101100001010100101011000000110011110010101101101000010101110001100')],
|
||||||
|
[bitarray('110100101011110000011010100010110100011111010100010010000111100011000111101100111000101001001000000011000011'), bitarray('001110111100101001001010100011010111111100111000111001100010100000010100101110001000101100110001100101010111')],
|
||||||
|
[bitarray('101101111100101100000101011111110110110101000101100110100101110100111101111111100111000101100000011011101101'), bitarray('011110011101000011000110100100110111110110000100001101000111001011110010110111011101010001001010011000001010')],
|
||||||
|
[bitarray('100110100100001000100001010000111011001001110101010010111001111111110011111110010001001001100110010101101010'), bitarray('001000101100110110001111111001011001100110110001001100000010001111010110111010000001110100111100011110110011')],
|
||||||
|
[bitarray('101010010101101001100011001011100101111100010100000011100111001100010001100010010110100000000000001010110011'), bitarray('000010001000111110001110101101101110101111001001010111100111010100000010001100011111100010001011010101110110')],
|
||||||
|
[bitarray('100000011101111010100110001001100101010110110010110010101010001100011001101000100010011110000011011101010000'), bitarray('010001001100001111111101111101111001111100010101011111100101011100010110011101000111101111001010110010010011')],
|
||||||
|
[bitarray('011000001000000011101000111100101110101110111000001101010000111001101010100010010100011010100001111101100001'), bitarray('011111011101111010111111010110000100101110011011001011100001011101110011001110100000101111111000111110011111')],
|
||||||
|
[bitarray('101110111000001011100000011101100100010111010000100110001101101011001111110000111110010010100011000001000000'), bitarray('011000011000110001010110000101000011111100001100010010000010000001000010010101001101111100000100010000110011')],
|
||||||
|
[bitarray('101000001000011011000101000001000010000101100011000100010011011111011001111011101100011110000011010101010011'), bitarray('001100010101011011001001001010111101111011011101011110000011001100010011010101100011010110111111000011011101')],
|
||||||
|
[bitarray('111111001100010010000001001100010101000000110100000011001110011111011001101111010010010110100001000100110000'), bitarray('010000110100110101000110110111000101000100111101011010101011000111010000010100010010000001011001000100001111')],
|
||||||
|
[bitarray('100011000001010010000011001100100000000000010001111000110100100110000100101011100000010110000001011101000100'), bitarray('011001100101101101010011101110100010110001101000101011000101010001010011001000110101010110111101101100101111')],
|
||||||
|
[bitarray('110101011000101011100101010001010001010000110000011111001001100000011111110101001011100011000101010001010111'), bitarray('000000110101000111011010100100111110111001101001101111000111001000010111011101100011001110001100111100111001')],
|
||||||
|
[bitarray('000010000010011011000011010010010011000101110101000110111001000010000101111001011000100011100110010001010011'), bitarray('000100010111010110111011100000011111111101101000101111100111001000010001010001100100001110011100101000111111')],
|
||||||
|
[bitarray('110001111001101111000111000100000111010101110010000011011111101101111101101100011100111110100101000101000001'), bitarray('001111000100100011001010011101001101010110101011100011011001000100101111010000010001111011010111111000001111')]
|
||||||
],
|
],
|
||||||
'0': [
|
'connected': [
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
[bitarray('111001011000100011000101010001010001010001000011011110011011101001001100111010000010100010100001001001110100'), bitarray('010101010100110010001010010101110010111011101101010110000001010101010101011001010001000110001000011110111010')],
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
[bitarray('110111101110010010100001001101010001010001010011010011011100011011101111111011011101011110000001000101110101'), bitarray('001000100010000111111100001011111011110011101100010010000000011101010011010101110101011010001101010011011110')],
|
||||||
[bitarray('000110011010000101000001001001011010110001000001101010011000001000010110001010101000001000100011000100111011'), bitarray('000010011011001111010000100100001011010111001000110100100001010000011101011010001110001001011101001111101010')],
|
[bitarray('110111001101010110100011000100110001001100010110000110111010011010101000111011001110011010100011001101110111'), bitarray('000100110100001110011000001110101110111101011000100111100101011001110011011000010000011011011001100101001111')],
|
||||||
[bitarray('000011001010101101111101010101011010011001001101010111001010011100011011000011101100110101001101001111111111'), bitarray('010101110001100010000111110110011010100100100101001100001110011010110110100110001110100000100011110010001110')],
|
[bitarray('111101011010100111100101000000010101001001010111000010001011110100111011111001001011100011000111010000110111'), bitarray('010101010001001010011100101101101111110001111000100011100111000000010011001000010101010111001111101000111011')],
|
||||||
[bitarray('101000100011010100101101011100100010101111100100000000001110010101001001110101010110000001001110001101110000'), bitarray('111101110100110000001110100000001101110100110110101000001010010010100000101101000110110011101011110110110111')],
|
[bitarray('100011010011111010000100110000001101010011110010100111000101011101010100110001001001110111001001111001111110'), bitarray('111101010100101101101110110100011011100100001110110001111101111011110000001111001101110011010111100000001111')],
|
||||||
[bitarray('111001100111111001000000101011000111000011001100111011011001100111110001111001100000100001100010101001110001'), bitarray('000111100111011011010101001100100001111101110010100001000010111101000100001111000000010111000001000101100100')],
|
[bitarray('101101101101110101011101000100101000100111010101010111111001111001011111110001111000101000000001000111110001'), bitarray('010110010101111011101101000110001100110010100000011000101100010010010110001111111001001111000000100001101001')],
|
||||||
[bitarray('111000100001110101010101111100000101010000001000010010010101100110101111111001000100111101101001110100100010'), bitarray('000100111000110101000000000100011011100001100010111000001101100001110100011101110000010000010100011110010111')],
|
[bitarray('110110000000011100001100010011110101011010111001011111010001100001011001100110000001010001010011001111111001'), bitarray('101110010101010111101100111001001110110010100111101001110100000000101010110101010111100100011111011011110110')],
|
||||||
[bitarray('101101110100101111110100001001000110010100000110100101110000010001110110111111111010110011100000010100100010'), bitarray('010010010101110100110110011100001101101011001010101001000000001000000000000001000100010000001000000010000000')]
|
[bitarray('110011000000100000000001011011101000001101111101100101001011110011010111100010110101111001100011000010101100'), bitarray('010111011000010101001111011111110010101111010100100001000101001011001111011000000001010000001110111100101011')],
|
||||||
],
|
[bitarray('100110110100101000100101110000010100010011000100001001111000010001000110000011111000000010101110101110110101'), bitarray('000100101001100101001001011100101001110110100011010010110110111000110011101100001000101010000110110100000000')],
|
||||||
'1': [
|
[bitarray('100011110001010110000011011101110101010100010111100100100011101110110111100000001000011011100111010001000010'), bitarray('001101110001010100110010001111111100111000101101010110110000011000100000010101001010100101010000000101110100')],
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
[bitarray('110100101010101110110111100110011010000011010110001011011010011101000111001101000001101111011000010111010101'), bitarray('100011011100011000100011110111111111111011100110011001011110110011110111101111111000110000110011101001100110')],
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
[bitarray('100111100100111001001110001001000101100001001001000100101100011101100110110110100110110001100101001001110110'), bitarray('011111001000111110110101010101000010101110000111100100100111110000110001010110100100011001111101011001100011')],
|
||||||
[bitarray('001111101011000100000101011101000110111010111110010100001011011000100110000111001000110000000110000010100001'), bitarray('011011001111100111000111001101011000000011101000111000100011111101100100001011000110000100010011101101000011')],
|
[bitarray('111011101100010110100001001100010111000001000110000011011000000011011011100111111011011011100111001101010111'), bitarray('001000001001100011111101010100110101001011101110001011001110111101111101011100010111100110110001011100100010')],
|
||||||
[bitarray('011011001010100100100011010101110111110001000000011110010101010101011011111100010001000000100000000001100011'), bitarray('001010101101100011110000111010000001111000100010001100100001001001010100011010101000101011010001101010110111')],
|
[bitarray('110111100000110010000111000000000111000011011000100010001110100110001110110111100000110010000110011000100011'), bitarray('011110001110110010001001100011011010111110100110000011100001001000010100000011100101001000000001011111000011')],
|
||||||
[bitarray('111000100001001001100011001001010100111001010001010010001111000011001101101100010110000101100010100111000111'), bitarray('000011011000111100000100011100000101101101010010111000000111101011100010011010100101011011001010101001101011')],
|
[bitarray('110011000100011011000100000000110110000001001111000100010101110001011111101011110010011010000001001000010010'), bitarray('011100110001111000110111101110000001111011101111011110100011011100010101000101010101011110011000011011101010')],
|
||||||
[bitarray('100100000000100100100001100011010011010001001110001110011000001010110111110001100100110001100000100110100001'), bitarray('001111101001110110001100100110000101100101000101101100101101111110110111011001101000100001011110111001110011')],
|
[bitarray('000110010010010011100011011011000010010100000011000010111101010011000100111101001001100111100111011000010111'), bitarray('001100010101000010001100110100111001110001101001100011000101011100110101000000010101000111011010101100101101')],
|
||||||
[bitarray('111100010001110001101110110111110110000011001100010000001100010001000110110100111101010001101011100010000000'), bitarray('000001100000100000001001111000010111010011001100111110100110011100110101011101010011110110010000110001110000')],
|
[bitarray('111001111000100111100111011101110011010101010000011110001100100100101111100011110000011110100011001001010000'), bitarray('000100110000110100000101110111100111001101000000101110001011011011010010001001110010110001101111011110010001')],
|
||||||
[bitarray('110011101011111011100000011100000000011010100111111100010110011101001101110010001001100011000101011101100010'), bitarray('011000111100100101100010101111000101110010011000100011000100011101100010011000111100100101100010101011000101')],
|
[bitarray('111101111000101011000100011001010011011101000000011110011100100001111010111001101011101011100101001000010111'), bitarray('011000110001000011001111101000011101111101111010100111000101000000000001001000000001011111011010110100001001')],
|
||||||
[bitarray('110010011000100011000100011101100010011000111100100101100010101011000101101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
[bitarray('110001001010101111000111011000100101001100100010010111101100101001111010110101111000101011000101000000100011'), bitarray('000100010100010011011111101101111111110001001001101111000100000000010000000101110011011010001111100100011100')],
|
||||||
],
|
[bitarray('111111001101011010100001001100110001001100000001001010111100010111011010110011111100011010100011001101010101'), bitarray('001101100100001110001100001110111100111111001101011110000011000101010111011101110001000110011011010011011010')],
|
||||||
'2': [
|
[bitarray('110011101100010010000000011101010101010101000011000011101000001111111110110010000011101110100001000001110000'), bitarray('001000010011110110111111000001110111111110010000100010100001011000110001011100000110111110011100011100010001')],
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
[bitarray('110111001101010010000011000101110001011100100001010011001010010011101011111011111110011010000001001100110001'), bitarray('000000000001001010001011001110001100001101001111101111001110001101111111111011011101000100010101000101100110')],
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
[bitarray('100111111000011111000101011100110001000001011110110010111000011001010001100001010010110011010011100100100111'), bitarray('011000010100100011001000011111101101001000100000000000000010000001000000001000100000010000000100010000000000')]
|
||||||
[bitarray('110000000100010000000111110101100001000011101100110101111000111100111111100000100000100000001000101001000000'), bitarray('001110101010000000010101110101101110100100100011100101101010111000010010101101010010100100111111010001100101')],
|
|
||||||
[bitarray('110000100001111001001101100111000110000110111110010100011100000001010011100000100110110000001010101110110110'), bitarray('011111010100110100001000001011011110101100011000010000001101110010100110010000111110010000011101111110001111')],
|
|
||||||
[bitarray('101000100010011101001000110110000111000000000011000110010000001001011011111100010101010111010101011101000100'), bitarray('011100010001100010011011100010110010110110011000100011000100011101100010011000111101101001000010101011110100')],
|
|
||||||
[bitarray('111110011010100011100100011101000010010000011100100001100010111011110100110110011000100011000100011101100010'), bitarray('011000101101100001100010100011110110101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'3': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('010010100001100001000010001101011011001000111110001111000001000111100011010011101110011001000010011100101110'), bitarray('000101101010111011000011011101101111000111011100111101100110011000001100001010100110101000011000000101110010')],
|
|
||||||
[bitarray('010010101010100100100101011001111111011100100101010000101101101100100110010010101000100000100110010101011100'), bitarray('010100110111010000111110111100110011101101010100011100100010000001000101101110000101101011011010111111111010')],
|
|
||||||
[bitarray('101000100000010100000000111100100100110101001101101100010100011110101010101000000011011100000010111100010101'), bitarray('110101001100101100000001000110011010100101100101101100100111111000000101001011011011110011100110011110101010')],
|
|
||||||
[bitarray('100000000110111000111111010001110111001011011001011010011001100110000111111100000001110101011001010001010110'), bitarray('001010100001110010011110110000011110100000100111111100011100011001000101001011001011010010011100101111100110')],
|
|
||||||
[bitarray('111100010010111101001001000101110110000110000111100011011000100100001110100100101001010000101110111011110000'), bitarray('000001101111010100011100110111011010111001010010101001001010101011110110011000100110000000011101111110011110')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'4': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('001111001110110001100001110011011110000111111111011111011001101000001110010011001010111000000110111111111100'), bitarray('011110010000100110001110101111010010100000010010001000001101000001101001001100001010000111000111001110101111')],
|
|
||||||
[bitarray('111000110110000101001001011001111001010001000000101010000100001100000011101100100110010100101101001111001101'), bitarray('011000000100110010001011101001011001110000010010000001001010010111110111110010100100001000000101110000000110')],
|
|
||||||
[bitarray('101001110011100101001010011010001100011000001110000001000110011100000011100001010000110001101000000011000101'), bitarray('101011100010001110011001011010110000111101110110111000001110011011100000111110101100110011011001001000101001')],
|
|
||||||
[bitarray('101000110011100101101111010011000000101000101110001011011100110000011011100100110000101101101110010011000010'), bitarray('101000001100010011111010111000011011101100010100110001101110000000000011110100100000100111000101010010011100')],
|
|
||||||
[bitarray('111100100101101001101111110100000110010010000011100000010000101011100010101001010011110000001101101000110010'), bitarray('010101110011000001010101011011000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'5': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('000110011110101101100001011101001101000100011001100100001011111010011010001011101000100101101110000101011111'), bitarray('010101111111000011111000001100011000100100000011001100101100001000001101011101111011010011110101010011001011')],
|
|
||||||
[bitarray('101000000000000000101101000000011100010000011101001111000110001110101011100001110001010000000111111100101000'), bitarray('010100111111101111011011110110000111111001000111011101000001111100001001011001110101011011001111100100011010')],
|
|
||||||
[bitarray('111100110111010001011000011101010010101010111010100101111001000010000110100000010100110101111111010000000000'), bitarray('101001110101111011000101000011111001100100000000101001101011100000000101110000010111100100011001010001000111')],
|
|
||||||
[bitarray('101000110000101100001011100000010110001111101010010000010000110001001011101100000100110001101011111011110011'), bitarray('111000011100000100010011111010110100101100110100101101101000111110101011011010100110011011111000101100000011')],
|
|
||||||
[bitarray('110101110010110111100011001100001111011000101101110010110101101000110100110100111010110110100011011000100101'), bitarray('100001000101110011010100100111001000011100010011101111110000011110000111000001001000100011011000101010001110')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'6': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('111000010110100001101000010011100011000111101011011111110101000111001110110000110101010111100111010100010101'), bitarray('001101100101110011011110111111110110101100010000010001111011111110100010000101000000001110110010010000011100')],
|
|
||||||
[bitarray('100101110110100000101101111011100100001101001000100101111010101100110100111111001000011010100100110100111101'), bitarray('111110101111011111111011001110110100001011110011100110001010101101111110101001100010111010001111011001101111')],
|
|
||||||
[bitarray('110101011001100010000111000100110000101011101100100011000110010000100110100111111000010010100101001101010001'), bitarray('101110100000010110100100100000001101100010110001001110000111001101010100000011111110101001010001001101111000')],
|
|
||||||
[bitarray('111101001010101010100100010100100111100010101100110111110010011000110110100100011110111111000111001101000011'), bitarray('110100101111011010000001110101110010111011110011111010100101010000110001011011001011101011101001100111101011')],
|
|
||||||
[bitarray('101110110111100111000101001001010111010000001000010110111010011010011010111110010011101110100000000000110011'), bitarray('001000100101110010111111011100110100111010101010101011100111011101100110000100111100110101010000101010010000')],
|
|
||||||
[bitarray('110001010011010011011001011000100101010001000110000101011010000000010000001100010101011011101000111000100100'), bitarray('000001100010101001010100001010100100110011001000111111000010011101000100010111110001110000100100011000001001')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'7': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('010010110001100100000010000100111111101010100000111011011001111010001000010110111100000100000100001101101100'), bitarray('101100001111000010001011011111001101011111011000111101100000010001101111111001010111100000000110111110100010')],
|
|
||||||
[bitarray('000110011010110001011000011101001101011110100101000110111000101111000000100101010011000101111001011001000001'), bitarray('000111000111100101010110011110101011111101010101000000011101001001110011000010001100001100000000010001000011')],
|
|
||||||
[bitarray('110100000000001100100000001101000000000010011111100011010011110011000011100000110101000101100101001101100111'), bitarray('001111100111011010010000100000011011111000100001001000000011000101010000010110001011111011010011110111000011')],
|
|
||||||
[bitarray('110001010101111001100010101010000000001011011101111110001110101010110010100101000010110000000100100010100011'), bitarray('000010100110010111101011101001101111110101010110110101100000101011010010001011011001111010011101100110100111')],
|
|
||||||
[bitarray('101101010010111100100111100111000110001110110100001010011100101101111011100100110011101000100000100110000110'), bitarray('011000101110010110011000011011110011100001010111100000001110111010110101010100101100110001001100101000010100')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'8': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('110000011010100110100000001001001110000010011000100100001000110100111111101000110100101011101100101101101001'), bitarray('111111001100011110100011111011001101101011100011001111000010011001101110011100010000010011010101010101011010')],
|
|
||||||
[bitarray('110011110101011110000101000101100101100011010100100000101111001101110111110010010101000111100010011101000101'), bitarray('000110010110010101000011001111000101101111010011011110000010011101000010001100010001100001110011100011000111')],
|
|
||||||
[bitarray('111110101011100011100100010101000100010000101101100101010000100010100001101110101101101010000011010100100110'), bitarray('001001000101010100010101100000001101101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'9': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('010010001110100101111111001101110010011110111100001000011101000110010111010110111100100001001110011101010101'), bitarray('000010101110010000011010001111000101110000100001001000100011000000100100010010001100101011000000101111110001')],
|
|
||||||
[bitarray('111100110010001100000010000000000101011110111101101111010000111111100011110000100011001000000011000001100001'), bitarray('001011101100100011000110110111000110110100110000001101000011011001110110111001100101000010001001010111011011')],
|
|
||||||
[bitarray('110100010010000000000011001001110011000011101100100011000000110111000011100100110100000101100101001101100110'), bitarray('001011100110010010010010100000001011100001000111011000101000010111110110111001010000101100010110001000100011')],
|
|
||||||
[bitarray('100101110101010100001101100100010101110001101010011111010011101000101110101000110001000100001001100110011001'), bitarray('000001010101110000010011110010010010111000110000111101001101111011000111001011001001000001001001011001000100')],
|
|
||||||
[bitarray('110001010001100001101001100011110100000100010110010100001101101110011111111000110101010011100111010100100111'), bitarray('000100000100100010011000100110010101110110001000100111000100011101000100010000111101101000110101100010110011')],
|
|
||||||
[bitarray('111110101010101111000110011101000110011001011101110001100111100011010001101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'disabled': [
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('101011001010101001000000001000000000000001000100010000001000000010000000101011001010101001000000001000000000'), bitarray('000001000100010000001000000010000000101011001010101001000000001000000000000001000100010000001000000010000000')],
|
|
||||||
[bitarray('001111000111111001000001001101111110111101100010011111001010011011101111000011110110111101100001000101011010'), bitarray('111100000010010011101000011111011100001111110101111100000011000101011100011011011100101010000011111110110011')],
|
|
||||||
[bitarray('000000100100010011111110010011100100011100001001001011100101101011101000010110111111101101011011100010110100'), bitarray('011111100001110010001110111011011110000011101001010000011011110001001101011011011110110010001111000000100101')],
|
|
||||||
[bitarray('010110111100001000111110010011101111100010001100001000100101111000110101000010101010000000010111111010011011'), bitarray('000110000101101001000001001100100001000111011010010100100100011100001101011101100000001010010111001111110101')],
|
|
||||||
[bitarray('010010001000101100000100010001001000011001100110001100011001101100010101000011101100100101100100011001010101'), bitarray('100100111111111011010101011110110001001111111000100101100010101101111110000010100111110010100010001111111111')],
|
|
||||||
[bitarray('100000100000011100000011111000000000110100001101100001100000001111111111110100110100011101000101111001110100'), bitarray('111001100110000000100111011101010001100001000001001000100110110001110001100010100111110001010111101100000001')],
|
|
||||||
[bitarray('110000100111011101100100110101100010110001000100000000000010011101010001111100110110010101100101111101000001'), bitarray('111101100110000100100011011100110001101001100101011001001011001110110101001111011000000100101101110100001011')],
|
|
||||||
[bitarray('100100110100000100101001111100010111111111010011001011110010010111000001110100110000110001001111101010010010'), bitarray('000010111010000101011100001101000001100101100111100111110101010001010111000001100000101000010101011101110110')],
|
|
||||||
[bitarray('101001110110101010000100000000110001100110001110000001111001110101011100100101100000011010111010101100011001'), bitarray('100010100000110101101001011111110010100110111001001011000000001100010111001011110000110110111100110010011111')],
|
|
||||||
[bitarray('110111111101011110100011010001010001000001110000001011101001000010001101110110101010101011100110011101000010'), bitarray('001101101001110101010001101111000001101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
],
|
|
||||||
'enabled': [
|
|
||||||
[bitarray('010011101100010000101011000011111110110001110110001001110101000111111001011010001100000001100011101111001101'), bitarray('001111101111000000110100010110011101010111011000111001100000000001001010110001100110110000100001110110100010')],
|
|
||||||
[bitarray('011010101011101100000111011001011010010101000101001000001101111001110101010010001000101000000111011101101001'), bitarray('011000010100001000001001110101000100110001000111001101000110001011100100100010000000111010000001001111010001')],
|
|
||||||
[bitarray('100000000010010100100000110000010011111001001100101000000101011111011101100101110100010100000011001101000011'), bitarray('101111010101101110001001100111111111111101010110001101000000101101110110101010011000011100000101101111111101')],
|
|
||||||
[bitarray('100001100111101100000111111000100000000010001011101011000111010110111111110000100000101100000100111001101101'), bitarray('010001001010111000000111001101110111101001000111100100000100110000000011000111111000101010000001011110011101')],
|
|
||||||
[bitarray('110100110000111000100101101001100100101010010010111011011001010110110011111100110100100101101000011011100000'), bitarray('001010011110000010110001000111011100110101100111110001001111011011100100000000000100011011010111110000100010')],
|
|
||||||
[bitarray('100000110100001001101101011110010011010000100010011100111111011010100011110101010110001111000011011100010111'), bitarray('011011101100111011011011010101011011000001001100101011101100001101111010111011111100010101100111001001110110')],
|
|
||||||
[bitarray('110101101110001110100111011001110010011011000000110100010011101010001000101101011011001100101001110010110010'), bitarray('010010000000010001111001001001100010101011001010101001000000001000000000000001000100010000001000000010000000')]
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user