From 0f18eebedc66bbfd6e8edcbe9a9340b2b317ec2a Mon Sep 17 00:00:00 2001 From: sylnsfar Date: Tue, 30 Aug 2016 20:43:52 +0800 Subject: [PATCH] finish --- README.md | 17 ++++++++++++- data.py | 13 +--------- draw.py | 48 +++++++++--------------------------- ecc.py | 40 +++++++++--------------------- matrix.py | 24 ++++++++++++++---- mylibs/constant.py | 28 +++++++++++++++++++++ myqrcode.py | 60 ++++++++++++++++++++++++--------------------- qrcode.jpg | Bin 0 -> 33541 bytes structure.py | 19 +------------- 9 files changed, 121 insertions(+), 128 deletions(-) create mode 100644 qrcode.jpg diff --git a/README.md b/README.md index 134dc82..4947a22 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # QR-Code -QR Code in Python Python QR二维码生成器 +QR Code in Python + +Python QR二维码生成器 + +### Usage 用法 + +```python +python myqrcode.py [-l [L,M,Q,H]] xxxxxx +``` + +### Example 示例 + +```python +python myqrcode.py -l H https://github.com/sylnsfar/QR-Code +``` + diff --git a/data.py b/data.py index 2a74c00..71ee7de 100644 --- a/data.py +++ b/data.py @@ -103,15 +103,4 @@ def get_cci(ver, mode, str): cci = bin(len(str))[2:] cci = '0' * (cci_len - len(cci)) + cci - return cci - - - -if __name__ == '__main__': - # test: - c,m = encode('M', 'HELLO WORLD') - print(c,m) - print(bool(m=='00100000010110110000101101111000110100010111001011011100010011010100001101000000111011000001000111101100')) - print(len(m)) - - print(all(grouping_list[v][l][3]==0 or grouping_list[v][l][3]-1==grouping_list[v][l][1] for v in range(40) for l in range(4))) \ No newline at end of file + return cci \ No newline at end of file diff --git a/draw.py b/draw.py index c21fe42..12534c9 100644 --- a/draw.py +++ b/draw.py @@ -1,46 +1,22 @@ # -*- coding: utf-8 -*- from PIL import Image, ImageDraw +import os -# test: -m1 = [[1]*7+[0]*7+[1]*7, - [1,0,0,0,0,0,1]+[0]*7+[1,0,0,0,0,0,1], - [1,0,1,1,1,0,1]+[0]*7+[1,0,1,1,1,0,1], - [1,0,1,1,1,0,1]+[0]*7+[1,0,1,1,1,0,1], - [1,0,1,1,1,0,1]+[0]*7+[1,0,1,1,1,0,1], - [1,0,0,0,0,0,1]+[0]*7+[1,0,0,0,0,0,1], - [1]*7+[0,1,0,1,0,1,0]+[1]*7, - [0]*21, - [0]*6+[1]+[0]*14, - [0]*21, - [0]*6+[1]+[0]*14, - [0]*21, - [0]*6+[1]+[0]*14, - [0]*21, - [1]*7+[0]*14, - [1,0,0,0,0,0,1]+[0]*14, - [1,0,1,1,1,0,1]+[0]*14, - [1,0,1,1,1,0,1]+[0]*14, - [1,0,1,1,1,0,1]+[0]*14, - [1,0,0,0,0,0,1]+[0]*14, - [1]*7+[0]*14 - ] - -def draw_qrcode(qrmatrix): - x, y = 0, 0 +def draw_qrcode(abspath, qrmatrix): unit_len = 9 - pic = Image.new('1', [len(qrmatrix)*unit_len]*2, 'white') + x = y = 4*unit_len + pic = Image.new('1', [(len(qrmatrix)+8)*unit_len]*2, 'white') draw = ImageDraw.Draw(pic) - for a in range(len(qrmatrix)): - for b in range(len(qrmatrix[a])): - if qrmatrix[a][b]: + for line in qrmatrix: + for module in line: + if module: draw.rectangle([x,y,x+unit_len,y+unit_len], fill = 0) x += unit_len - x, y = 0, y+unit_len + x, y = 4*unit_len, y+unit_len - pic.save('qrcode.jpg') - pic.show() - -# test: -#draw_qrcode(m1) \ No newline at end of file + saving = os.path.join(abspath, 'qrcode.jpg') + pic.save(saving) + #pic.show() + return saving \ No newline at end of file diff --git a/ecc.py b/ecc.py index 0f5b919..232bfba 100644 --- a/ecc.py +++ b/ecc.py @@ -18,16 +18,16 @@ def get_ecc(dc, ecc_num): return remainder def divide(MP, *GP): - po2 = get_power_of_2_list() - log = get_log_list(po2) - GP = list(GP) - for i in range(len(GP)): - GP[i] += log[MP[0]] - if GP[i] > 255: - GP[i] %= 255 - GP[i] = po2[GP[i]] - - return XOR(GP, *MP) + if MP[0]: + GP = list(GP) + for i in range(len(GP)): + GP[i] += log[MP[0]] + if GP[i] > 255: + GP[i] %= 255 + GP[i] = po2[GP[i]] + return XOR(GP, *MP) + else: + return MP[1:] def XOR(GP, *MP): @@ -39,22 +39,6 @@ def XOR(GP, *MP): GP += [0] * a remainder = [] - for i in range(len(MP)): + for i in range(1, len(MP)): remainder.append(MP[i]^GP[i]) - remainder = [i for i in remainder if i] - return remainder - -def get_power_of_2_list(): - po2 = [1] - for i in range(255): - a = po2[i] * 2 - if a > 255: - a ^= 285 - po2.append(a) - return po2 - -def get_log_list(po2): - log = [None]*256 - for i in range(255): - log[po2[i]] = i - return log \ No newline at end of file + return remainder \ No newline at end of file diff --git a/matrix.py b/matrix.py index 34e1179..9b7caf8 100644 --- a/matrix.py +++ b/matrix.py @@ -26,9 +26,9 @@ def get_qrmatrix(ver, ecl, bits): # Data Masking mask_num, qrmatrix = mask(maskmatrix, qrmatrix) - # Format and Version Information - - + # Format Information + add_format_and_version_string(ver, ecl, mask_num, qrmatrix) + return qrmatrix def add_finder_and_separator(m): @@ -96,7 +96,6 @@ def mask(mm, m): best = scores.index(min(scores)) return best, mps[best] - def get_mask_patterns(mm): def formula(i, row, column): if i == 0: @@ -177,4 +176,19 @@ def compute_score(m): return 2*s if s >=0 else -2*s score = evaluation1(m) + evaluation2(m)+ evaluation3(m) + evaluation4(m) - return score \ No newline at end of file + return score + +def add_format_and_version_string(ver, ecl, mask_num, m): + fs = [int(i) for i in format_info_str[lindex[ecl]][mask_num]] + for j in range(6): + m[8][j] = m[-j-1][8] = fs[j] + m[8][-j-1] = m[j][8] = fs[-j-1] + m[8][7] = m[-7][8] = fs[6] + m[8][8] = m[8][-8] = fs[7] + m[7][8] = m[8][-7] = fs[8] + + if ver > 6: + vs = (int(i) for i in version_info_str[ver-7]) + for j in range(5, -1, -1): + for i in (-9, -10, -11): + m[i][j] = m[j][i] = next(vs) \ No newline at end of file diff --git a/mylibs/constant.py b/mylibs/constant.py index a9e3f8d..a74ed07 100644 --- a/mylibs/constant.py +++ b/mylibs/constant.py @@ -76,4 +76,32 @@ required_remainder_bits = (0,7,7,7,7,7,0,0,0,0,0,0,0,3,3,3,3,3,3,3,4,4,4,4,4,4,4 # Alignment Pattern Locations alig_location = [ (6, 18), (6, 22), (6, 26), (6, 30), (6, 34), (6, 22, 38), (6, 24, 42), (6, 26, 46), (6, 28, 50), (6, 30, 54), (6, 32, 58), (6, 34, 62), (6, 26, 46, 66), (6, 26, 48, 70), (6, 26, 50, 74), (6, 30, 54, 78), (6, 30, 56, 82), (6, 30, 58, 86), (6, 34, 62, 90), (6, 28, 50, 72, 94), (6, 26, 50, 74, 98), (6, 30, 54, 78, 102), (6, 28, 54, 80, 106), (6, 32, 58, 84, 110), (6, 30, 58, 86, 114), (6, 34, 62, 90, 118), (6, 26, 50, 74, 98, 122), (6, 30, 54, 78, 102, 126), (6, 26, 52, 78, 104, 130), (6, 30, 56, 82, 108, 134), (6, 34, 60, 86, 112, 138), (6, 30, 58, 86, 114, 142), (6, 34, 62, 90, 118, 146), (6, 30, 54, 78, 102, 126, 150), (6, 24, 50, 76, 102, 128, 154), (6, 28, 54, 80, 106, 132, 158), (6, 32, 58, 84, 110, 136, 162), (6, 26, 54, 82, 110, 138, 166), (6, 30, 58, 86, 114, 142, 170) + ] + + +# List of all Format Information Strings +# [ +# level1[mask_pattern0, mask_pattern1, mask_...3,...], +# level2[...], +# level3[...], +# level4[...] +# ] +format_info_str = [ + ['111011111000100', '111001011110011', '111110110101010', '111100010011101', '110011000101111', '110001100011000', '110110001000001', '110100101110110'], ['101010000010010', '101000100100101', '101111001111100', '101101101001011', '100010111111001', '100000011001110', '100111110010111', '100101010100000'], ['011010101011111', '011000001101000', '011111100110001', '011101000000110', '010010010110100', '010000110000011', '010111011011010', '010101111101101'], ['001011010001001', '001001110111110', '001110011100111', '001100111010000', '000011101100010', '000001001010101', '000110100001100', '000100000111011'] + ] + + +# Version Information Strings +version_info_str = [ + '000111110010010100', '001000010110111100', '001001101010011001', '001010010011010011', '001011101111110110', '001100011101100010', '001101100001000111', '001110011000001101', '001111100100101000', '010000101101111000', '010001010001011101', '010010101000010111', '010011010100110010', '010100100110100110', '010101011010000011', '010110100011001001', '010111011111101100', '011000111011000100', '011001000111100001', '011010111110101011', '011011000010001110', '011100110000011010', '011101001100111111', '011110110101110101', '011111001001010000', '100000100111010101', '100001011011110000', '100010100010111010', '100011011110011111', '100100101100001011', '100101010000101110', '100110101001100100', '100111010101000001', '101000110001101001' + ] + +# powers of 2 list +po2 = [ + 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1 + ] + +# log list +log = [ + None, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 ] \ No newline at end of file diff --git a/myqrcode.py b/myqrcode.py index a50ca5e..d8b3fee 100644 --- a/myqrcode.py +++ b/myqrcode.py @@ -1,38 +1,42 @@ # -*- coding: utf-8 -*- -import data, ECC, structure, matrix, draw +import data, ECC, structure, matrix, draw, os # ecl: Error Correction Level(L,M,Q,H) def get_qrcode(ecl, str): - try: - # Data Coding - ver, data_codewords = data.encode(ecl, str) - ndc = 0 - for i in range(len(data_codewords)): - ndc += len(data_codewords[i]) + if ecl not in 'LMQH': + print('Level Error: please choose one of L,M,Q,H!') + else: + try: + # Data Coding + ver, data_codewords = data.encode(ecl, str) - # Error Correction Coding - ecc = ECC.encode(ver, ecl, data_codewords) - ndc = 0 - for i in range(len(data_codewords)): - ndc += len(data_codewords[i]) - - # Structure final bits - final_bits = structure.structure_final_bits(ver, ecl, data_codewords, ecc) - - # Get the QR Matrix - qrmatrix = matrix.get_qrmatrix(ver, ecl, final_bits) + # Error Correction Coding + ecc = ECC.encode(ver, ecl, data_codewords) - # Draw the picture - draw.draw_qrcode(qrmatrix) - - except UnicodeEncodeError: - print('Error input!!') + # Structure final bits + final_bits = structure.structure_final_bits(ver, ecl, data_codewords, ecc) + + # Get the QR Matrix + qrmatrix = matrix.get_qrmatrix(ver, ecl, final_bits) + + # Draw the picture and Save it, then return the absolute path + return draw.draw_qrcode(os.path.abspath('.'), qrmatrix) + + except UnicodeEncodeError: + print('Input Error: please read the README file for the supported characters!!') if __name__ == '__main__': - # test: - str = 'HELLO WORLD' - str2 = 'http://www.thonky.com/qr-code-tutorial/log-antilog-table' - err = '💩' - get_qrcode('Q',str) \ No newline at end of file + import argparse, os + + argparser = argparse.ArgumentParser() + argparser.add_argument('WORDs', help='The words to produce you QR-code picture, like a URL or a sentence. Please read the README file for the supported characters.') + argparser.add_argument('-l', '--level', help='Use this argument to choose an Error-Correction-Level: L(Low), M(Medium), Q(Quartile), H(High). Otherwise, just use the default one: Q') + args = argparser.parse_args() + + # the default level is Q + ecl = args.level if args.level else 'Q' + path = get_qrcode(ecl, args.WORDs) + if path is not None: + print('Succeed! Check out your QR-code at', path) \ No newline at end of file diff --git a/qrcode.jpg b/qrcode.jpg new file mode 100644 index 0000000000000000000000000000000000000000..806f3c7865c8a1b500936c47e02f516c7ee80eef GIT binary patch literal 33541 zcmd432|Uzm`#(O4h$5A;#3)K76xp&&Qb|rtX_0j*6`GLBzDyBHmLeR9Ns?rlWSOjE zizK^@h{4zyW-QY%+y9=?^Zg!r&N)cd&aQ z>y95aJ__OCfk1e`-w<{e#1JB|Y8C$~J^_Ay{?)4m1lMd_yGBT8jl}v5A{(V8p)%5v zTeir`D=Wxu+atGS%TCQ*d-m?zzkfeeL0eBtRaaSUzbd;7A|${Q4gTg4g|Mq2Q1Ib= zJlww^KmX!cv67c>6~Dl0K_T!9dFvo6cvh}l!Ml==kCzwxwlDZOgjbYr{nmX3t2Ugz z#J|mDqw2jUNdj_*vdhIxo5}KOmv8y67TmO1TtagD4uze&cJEi$(A3gCV0ie*QKMtV z$IqNSci!xRxrObOtJm!89j@QLQip*MExHkbdVX0?iEe4Mo|>YNDg!*$@@|^Y!ttjvK=$?C}{kgyw)* zc#4`%VM99KupvRu*pM_MHe@$~`8MJ|{!x09zJ$*SHY6~NnZ|~!kCHwXR{)~G6%qu-|HI>v!v@x$eif1^t3_6Ki{S? zK|)Ls#Yt9dNEIp+O2#k@onNsbmwa&zxt3^6lHYmN$s(6*T*33<5*Idv+=`gn$%YJ? zupxP;*^ssBY=~(D>nx6b&fXr83!@Sq+^JV!i8?Eg@Gh2~xK62j=bJ^@gP}z2>LcE( ziom*E_V7OQwHU24p%M9g-ZFoxBQSrMU!qzqzy`YH^PqqHDzkSU3RU3Sf2SR)LC~Qc ztgl0U#QGTx(vzsEi*`D+m{CM^5m?Qbbyral_|;pyUhwmZ*6=E7Yq-f84J5Fpzr zBCNnEMgo=%AwES_MACxUkV8LMC%f1X%4b-gv5z4elH|>XC^&*#8-$Wym2PE2no8J^ zsC@9Iw<2h!h;?kphz%Q3+l69jTlryMUf18!uF&F&MCA|+uwNc|m3Ds?zx67hoIk*Z zKv!i$zO=F-PH4JCp-6b*YRcwN)H~F>{UF?ZV@WdZQ^^rdQ!37cOV3G8iO~bUd|}QU zF0fRUJQSgynQl+8%MNgkQ|V0dE&6?DpH)=t%6nG6Ui^$*Di2VzDyRVxjt$v@Nnn3lNMnBxi6FvSGv(ekYdGDHDyU;nY2;$Z^ zK8_SKYHGlpM+GlhCthMdSf*_ajDGaFEVR~NpwX~{ZYRRp7+VEf*o>QYBd{UiAfW_J z`k_oA!n}?%8&acaTY(bLb${(qXNW6qDlW3LKGfrYCf$^N^M04@-FYp@EGC&@ZtIdp z)3kb*6Y-_6uyt~4pe9d2r-q=ahlIQ$R;df;XpRT8M<(KyBD8W4Q;$% zKZ4ALOh7x^@vXi^U#3}~9&~)eYJaa|Qd;%KYju5z<0_9jof7&GLJrTOu7`Okiz?qg zt+@Nhj$WxRa$4HM(raB%e-{l11inmcjtwbSnU_DXnOTe)JsjN&l|l_*kT~iT8}f>R zhxJA9(jHaAuCvNoS>LGEiQEX7Akin(5;9v`3PqL$n9Klk)7i4MSUb5f{W>1X4LRj%Zp0ZV zMDnlr020F*CjuL}1ad$zf~9H1P$mSUXZNxp1JN~Xh*UCbvvXzRf;ejWIFStr!(V!d z^m2bN>!I$rgGkz>HaR`mQCox*)7{H^OJKn4^V0P}{V`)o0;*UVM$3~)5EGF|dsF+25GN`6XHYCyv%5VbD7J}GVEY%MSmduZOH4d{cMb}RE z)A!UC-S|`!bC4gBc*3U-fnY-_NHkA2#88A~Y=xo}PVQ03oYOnd$!dVBwvWj_+uV6{ z;G*DjnWF~M$Os$_*Ly_PsRh8(&AaF8YX* zadP>vhA5Z%26Ku63oF*?oq7-UWDIIcKM#t~4^`tLCr#gvTGfN&Bz#mIcWWWz0%Jndm0LSSrP2l5%_oARp% zzok(&+b)-$HI&`QFTrcqfq#ptaPI{VBRLCWh=ZK?X!gLbX<;$~qW zzAHwbBpV}DKPMG`JGt8Q=uLx~4;V$vLE3gUWV`nvHUt~NREPv;G0~Y3DecbcW=zq3or z`uM^y!yWwEOcjnQSO~uF1Y+H31cJedYC~>RKQ*@D0YQD7`ZK8E(%|=VR2cOz>L}=k z-!Na}hCo@u;+V-cJV(TSFnxHI|M`2MB|Eaw3?$(nR{8G##T{(WUw6TL47D*AsY5@e zOu91jqf+*&EA2-C$Jw^uFlBt~BQ2XM2xTclAu=tu#e^jZoi(^9s6gbIw zmXn;;AUQV}F=P|Lzmv`wf`;Y}jB(<|g%0!47?*Dy76uMT88<`T%loY&Pj0-aY77hW zdGh}tZb~ujvnO<_ymS{%W`g!!f;#`i`ATI9<=x=HSM$T_wGj9VO8;Mkf{R+^x@@3XC250?jRLegKnQF@0i zycaD@tC_%cEugye>u|Nq*(ap#FoH|a?L4mqvj~PY`FsHAI4dEqO2!-+gNX zPYrU|#-h918`SQ#j`kD>ur}btQBC+PRByF2Yj-lbI&pU)Hl~MIRrsapc%Xc^$-KGs zv2xx`<-9H-l^85zH79>75mdoEkiRC@d@c)w3c@N{#07Bn<~rvh;Mgy*q%%86Z#Uk| zg7or~VG{M#X_iOH5uq6q`*mRNEoxI=eMv;t#;P7$T^H%KlktYOtItvDV~=X_JNzCN z9x0PJv)dCRv&C4Pf2YAn%}f@df66}>8qAV-*Us35)Q?UBHEYkdF`-)QefyN}JjyQ5 zh0!PHh7*M-sUca#u6^U)5$ng*43txEL>g^pWMsWQ$GgswSF~Dj3?&Iy$K3NVbaCGE zxN%e5ElRDF*p*8g)){Q^7tzK&L&3Wb zM1y+5oddw|$C(4bDIC_!h6rK7@V5pwzulP)sU898+6AWZASfde3)0oKX56bMxnJ+H zujTm<^dqx$pIW!wPMt|cf{-l`Eiq7+|Mw(He?c21I*WSf(D~^rPXXwnw0YQXNL$l! zn#!Ehsva60x4G2EhO8SWY+{^yMLYA+>&uKol!<(m!J2&s3JtfKiYv6;PRwibISj%d zCqUa^ir=H+YOb8=llf3L`>9UKVeJ)rz4lGnh#=q~hqY)hmcPX?lMMldILs{cf)9ey z6PIdv!F;^bIy1v~%`WOO;kHvNLZ8-_t<3aQA!EV18Ig&`U-OU=ASs7EBPY&w=i8mG zxXTX_=JVwLs1jnMN*=EAwKQ&VMdx&s56rvx#%%5?+-O_3RUs0-Bb_E>0F%m-2B&Sc zMdoa*#f|giGOEA0-%-^_0ny&xh&K8~%A~)az}SIvpeu8=9GT49nYA@xvP#V-Vu1otJS|gu_sEDcW>3$=$gP|7tyC1yzmGj;=YAKC78^= z(=dnIToEKa)eAfF)oM4qKxsp^`(!`2g9UrdJYqv0v2@yI$K!?S-2rIuurE%(7Vu%5Qni_jq0`j$DRnyH>?&K1kfMD+w7^&VRAS6zK?sF zz1w>D_DoE4_V7ik$%k78?((14OMgRyk%>mMd(0eW=51e*4xb2>iSS1WtZTOmEa?HS zb($#webt=NpDsn;F|^=}^<>#~c1ua=7TaFO{AjeIW^h}_{~dloScX{iB=V99|yy|Jv9uku?21R#-{)a!ozwl9|fj(Stn0|(}1B_Hq=V{zv*XM6J;KQF!QAcf1 ze*h(lZ7X`@i^&lWNa}S0y^&*hzp4ad!vYE6gR-->JtZrq`f(5S<&|&&&ZOCN6Kk8v zo^QkctA%RfP6a_~1N`}=nT2?eynlFpU!H$b`j*X_<}5y1M1~KHj-sB(3ne&BGaB=f z^EI5RHNb-T%r#!0*n@G6=;W{3>u?~iK0KNk=b--OR;NYL)OX4*Q%QKzC%p(O3W283 zi(qW+QOU-G@+=3+wol`C-{89LLJfGy&=y-aFSo3KWm8N^083J*8alhSi4B>mA~4*F z{Yr71##ugiarD_4Spcf4j}RMjzvknQPJjl;qipGBvGj;{^YL!gX+Mg~pOYF-&Xw8p zj6-vNJg{rI6CW>aMnBmi6}P=8@6NZp!Ba2xpwC2lhyOktLBUt~+V=Bz!16LPF40Be z2ANN!Z{wV97sPYYrac&7Sc;uo3`;k93VbhW;PE&Y#7Ysxe-fL3lAC)#rGMcBDxx3Q zOJW{zIn>lh>jI0gLtmwIaS;H(j021Cr7K?@ECLr{&O)&yVp*@J7_Y%})d}m1Lydu9 z`m-||;+XuO{)7W>+p^Y830xR~-r(*4Vcy1u)S|}x{@m8>05uEr(*NLs$V_)?Fsq6p zoC>Ic3Z-G+ph-(-O}e2IGu+HgHz$;+RSW9G9|)Ger%J%@heCzbBOX9I2;Vd{_A-MT zXY|`A3kZWmsdKmwUc@}lV1`;mC~RaqX!i;8INI0i9?0I!A-T?C4w5O=Ny+;+nZ5gd zEW3W!F^j>#$!O_Jd~~)#%t7LfW5KdV zjn3(f*XSa9Gfm38z8tVg(|grg=Y$n(&-#*NqS`xoPW!V=PxS4+ns8hnf)+$P&uXBf z671W1%+Q0j%3(!1mh|7Nb?{i40x^}dm)T9QzAap?fWRyQTd9F68VntFI`AWl*sl;Y zrEA@L!o=`hq`+iWab|?hx_}#RhUHgy?IPKTf>b0DMHW`uqkgcQS?Wg1ULHzr(B}kH z3<-yu)&)N_E2)T zZ_Y$1Vv5y0IN2?U>z;1dS0wFi#^Zf8!>>tyEBbtkW5ylKMBOpRS0R(51i#_vfEC%y zqXH8LhQnbs2(VA!YcI0e3$o)$J$A8FBe&}Mf`&oFRCwH!#nPd_g$)ta)%5J2T5;V% z`u<}hSJ%NCo*nn4t{Q2}ZfJ&ICr8liprENY0do^>21NmI$#WmjBN-@(u-K4#aG<~8 zoRy&0<;{hGvl7%rj2^lj+@qEz_kh_;$ z!V;PGw0MdpORSNKU>t|#>Jz{c*EL4xTx+CCX%k2-ptSHZ?r=*B^#DIZ4h-Z?cFw6WVoAI zQgtau*Et@&9VxHyGVyDNM`~4!pD1~-rvSBO+M;u!=kZQu_X97=lC_HTQ@oD`y~1$h#D(Q7Ybyh)c2 z1NA=;o_>j_w0l7(^SGkt3lqaNgl%yK@(=f_!bf~_#{C3oIWK54=J6&iB=wzkA>COL zS;Z&Kz#dx^MAPee8MdEG-Zre^gNNp9Jrqe8IGZ4tuq zkAFUJ!!OK=8&t?|6RoZiEjpWEdA_-{(Uw19$b|X^;WT1xBsh?GY>VK6KB%ds2RUfe zcJD4;!I`5baY_-ywrmi9ni-i-SzL7{}^18Y_s9IGtx3a)~O`AJdS@2M*Z zSJa&g9~=MNG4oN}Aph*oXziT?SlYei>=9_MTXlrbKK76$ zBj5cqoO%c<o{1yOC&`GDxq77zFJI(VD*x)H>%`xL7wl#cwT%xDtv+W=*ZWqMAK!Tq#+|)i?rm_~~4)JddZ?c+s*wkOm$ts`{j#Jmq9qpY#D8=B=5DnD@uGnoTGER=|7j zKJVrs4!T8mUO*v%h) zY-0OWS2q-sA_RU1LKIQ>@z-&Zjb8v`U#z4E2baz zwfd$P(;NTJ!?wCdniA28d#5e}7+||aYDLFyA#@mdXEyoY? z$5U^4#$Zp&H_T&O z=(V~(SzQO6(^pJuRz}?wIlh2i#t^+^9*AyyBIz!|VGIrFfB z$P-;Y^#qrb`wF}kzBY#1$hNY!TiLs@*3xbA^dhZFs@(F=Yzn(j#UuMd>yw;ZSDRVX zn2jVp7wP)p>;4nRt5@B8wEb&(Rm!`QJQr8pTwRl$L6dzp*01R8@d_Zp@-EdWaUIVg zkby{#k2m1GI5CT^Iv1C|%xmJ?4ow?xzyJ2liz|`Gdm-BOzD9o&ey$z%&w3L2^<>ss z8UySjlwMrmrs~xB5x$0Ji@&y5(mw;$%M|}Z-UhTG_ovDMhoTOk<$d533`quXBtHP4 z@ks!Hu7D}sM@?ujEh1VmgAkF|Wz&(_gT}f5)VaEDvqmpVe`);7$w{3~Wp2 ztzVZZ^N|!??_`5cozMqBH~?(@@v$&}gGymx0XZ@zaw(XHfnhE(pQ8qn#-LQeC^qEi zM{q2Xq&YAy98i53sD<4YWD&qP7y`y2&=ECz9gk<}EafD2{&RYA=gVSHxt393J29zj zh#eG=O2N#)D*z-uZN|e{U_;IVi$PgoF%jQtSjT0+4qr@z&E7Z%WHW?mIN+q{f;DW& z%M=WRtiX5*TZ`&A55~5mnZ7tc=ls?3m)^xdnaQ|;L~t@v#Uj{{BPKRHfXm$J$Kf(F zF|06)1)%jnfekg`Y$%4g@hb%|4om6I5zsfF{=hF;@&Dxj3UojJ25|+XPZR(*=&+23 z(4ZZ@0Al`ZUat%D&AhJJbFauABupxY4qNk{XcZQP# zD*U9{Ser)hu`Fmy*5s?1AN6`qZ*j3;(Wtu+hGLbz3Se2#8}s6IgpMgG*-mS4d6ses ztYXEZG;F#iOy9nQTR4|aPtu{DjRYSHjwCnWR;)CE$l)Lh=8E1HKeF81D$ZQ zNHZ7!jQ^;`D82jED<5iTL)@vlVb3N$t3f$8Umlz2sEsg_@R#G_h%>~UBo`( zf^zNc9#(?tEvhKD^09%?V}oIJXgGj{6Fp*CoqFJ{m`w0?jj? z2grDiQvvl_; zD@tq`)17#>dW};7@0Ps-SJuNMn@TBm57l+F_W-v2ZFgsF7`f3~{y~TAPue1T`~|1D zgMLhX98KE?`mvBKzx+KufbCFi(9scDcRfEQd-%#;n_5X_V+BFsRmKVwj2-PrZzg{~ ze~|MWPOP)>?HK6SRu?8tI}UEzneT5HN>sqK=7D}qiN6vhVQ{IpE1tBeeHz=+{tdGSx;06Ux9vTO-l+BC zd&}4JhHFg?o;$J<0+E97R4dAO4i$cg>F+n+k!YqOAGzl)B!4LjfVn9ZDK}Ug$8Pq8#6dxpf(wHCfJ5L zIVI)|0-{^LD8n924o6)X!?w$~cltEGx6-ww4BF}(Yf$xCct#Nc0*Xr<0R`xt10-;? zx8KQ#Fx_*mKyqRE-6Pig*=kpvE0NkNgI8Tu-^luR$cFDjoTg2&jE5hhCd6DpRen|~ z`||I$?-h&ZdS^^dujP2ynNvlj39j0pNsddoSbEk7lC2;iPyCL5YX<8_@zUI@VOLoM zuKbJzpL!MHG~q-KRZB?6w-lrPTWsIN0mc4b-g`O4hi8d;C>qf2^~E!tKf2|N6{4vD zhn!N2<2{drD7|4(u@nm%KRx````ZK`^lI-ug*2pgF>e?4>w@TkEre zoR!mOEqC@qn|gF2^|RE&P1-L7C7SlF+!qy!K4T-=Z>=FM1t5r6rxpMX=2%v@th?}5 z`_xH@MA@tufFK?u?k0yPY!3>4%ZzL{{_P9eF66fY$c9)`K=h`=suFj#`&hrJL1o$a zW{qjx-_0^Ly3hM~?_ExukLqvmP&`2y4#~y;?> zFqFt=D*Z$$(yxEM1nx3?&sE`pD~nv2C3It6iBTn5SlyA+#Olq;z`1m#~*Wy!|| z%o;ettF55D1Y}brAhsAzobhGd9~eX%)Dc%1DcZw+jKFBi1$!^dH>E32ztmDaUe!J3 z(RNjM8Sy!vqvit08duGg2{762+bjhN_Cc{N6+vQhQuOd1t z0Cbb57@(WHWQkx(=1~(fUsq;~;5)4=kG-?$s&$q-dhlXaiZPH-@i*b4f93nWh)qF- zS%MzUAA5LPUF+!G=XKICnqCHbF0J}zy^1F^F+>NSO;aqlaK1b1kXxecUGO5N4`4S5 z<^f{o$~xcfyDwdWe1(DjEoUj(4+mQaP$cP~g11b7A|3t=woq4#cjePlUi%p1=y#@Sy@>Ru=G-;}1 zFL(L%xq-dE`3sBm^^`!XaFAlfWDhg5uS#=kucp3#|Eym<(mo{S@E)G3i$u9LvuB){ zJa|#0X$d;0!e6%D7y36$tJ`AEdZMaD9xT*=xSMdEh(}74b`Q^^kw!OeOjE)#a0I>E zoyC>Q$d~kPh8abnDiBL{WR^xdAk(|Mx^&3~TRmoWuPc+-d-EU>hqV|5NBo~r7C+Vs z{l=;yQ{!IE1IL2nw)`145+QrVWc5k4P~whalr=LEmd`Lu8zYdP&cmFFVunAn8oP76 zW4h3L?IfyiD#HGh0LiNCt0@PeZ^qjC;VTa7M;NwH$3|1(iV}Amzx5ElSMTd7ImF?L zJZw4geuO>XKRDzI;6H%6Uy=Ep3)o}8DH{aXxU?cRWEYN^A3?i@Scu0>gJz)%=;AP^ zXn@aUZQ>8kQg?~DG$DE1AwaSS5;mx?I8tIl_&}jx}*+s2UCmA zc}p3OSIX{(!*3nF>uTFs5J9t_0Xn&#;W``tYvIZ3WY~oF6xO?&S}E zk*IcgF1Yjyyn-tuRsawj_&BPgn8~0KKS0XzA;t2v9k(CMxCU{cPUXSccdUVh#!SG+=I!z_tYA$bXsbdwLQvseA8 zJtm%#T36SIwWZ0aiav)LS|b>0D$Emv`4eDX&Fft*ZT+V@at>uHRZMYzK-#afS{A^Z zel-aX4DuuzjsXy^6HvB&Mi2F+GI61p$^Gd?*4rj~27CQISJpl}#m8H7FVaY_WWfyn zpE3x;EDah+Oab>tQ@J8EBmHkwgvt*f(w+X{6o#0bw-fIUFG)v(*njrF-l-yyV5m5( z@1jQ#(U?_1=Z~_->pOQczV|h|5ibL#MZ59(h`til6gRpa?1^?E9>f1E!*X=Hbjb|nmUHc(aBy*ub?fDh6cSz9VC!Ryrs(Mi+5|>88tbTP^iIFg5OMQCMxB7t&g>>v$lY|Kza31m<)3_dKr=D3j-`WurmR^5D-O+d?APb27DplzmEdG zkW0V5X$)|k3M@&yAl8jt%_80Z&s@c*7ysQlL%uTC`p>4DOn~*IQA{v zVgGbjW<_3l&Q8-WA9SKm-U`O1xTBX$WnHYl-6PZ=U(nE+nZ)&-rGet~$P?z28`D+K zYU>1zHXPC zEJ!QCX}y1!NM1p$yTE+mW2m3`s_Vii;#3Ap;wnDdg;3EB*TyZV@X{?v zs0gbZh+J$nyNVlu$b}RZe>>qbjv%eplg&^9?BQmQ@YY4@6+6KpBu_sdxC=j`m;R0d zFNd%9Fsh988e~pJZ_muCALV_&StsGtMe#B~Pk5GiFWvV)OLh-1iov<=l@3^kBuDm0 zjnMhgT!VFw#ZJ9zaKpln&xnZ7ylrU4{h10M{S=#1gMSM$-@0RUQuMbTi4}K~SgFtN zWZ|lDoA1CM$cPn?Uq4K}j_dS#{?71*Lb&`P)~$6yp1~5;FqyBzn?VW#Ymft8^T)Hz zu}I{GdNpR&%Dj#1Yj~z_@{HOvE@$j)_Fdxmni3NnQFcj-_%^PySL(^#-8T_(vf+6n zEJ0e)OCK0H6C0>rqH~Vb+PXba>ItvQ0sfiikEJ-3n&zHmSfww6FIA$YpQj)K_d5)= z?ugMcNVLD~dM9XaSsE&dsD})uCt*WWdBCoEN-IBzyPZYxM_o%n} z@b{-@o;mA32`aa@tL54A7e6+?cUKL)B!W6V`LCFbF45q9{Nb~W687$k@BhYfaRD|R z*>e-B0FjBFMLpW%qz+p(9<#}1KGw{_w`%X}ULcMvKMG$dAD%Z|v(!2C|Hu~hbvd(& z7bSLkFr3=%q>HQ?HEXeU$hJCh!20(~^Ws%Jyg;V|J3SSSSn6sz8-o*JSoZ3fz$xcT zUK$I>ru1}uw<>nud#wC$dfBOY`R5`vd0vEN3@t~IBEnImfX;_AW&lOXCMXCYF5%&| zIS%Q%{)7-Si>E+*MJgYc^7w_}^v0FLg^>E9WXHjv0x)W(sq@F3sW(;)(kjzFWONP| z4ZsLVmNYFL=w)+oO|zK1&YIL$KbhXhLr10Wja1Gg_oi0j#5|0u&0-gZqB-;Gk3a-T z)Hqi4=)sD8dK+2iI((4i{G9%&Ro^=7-B8HFh*QRKx@{2xa*sE}%DP^f$2Uq6DhLvb zj+$I&AP?lIdQX*he*vmqlVvdF11nc3oz7(;ed-EpsMaj~>}Y4heLmMSs|hkPUc3a|ht|a?hg|8&ZY?Szb=) zA^>qSu%c2?3O|}_i=5+%Cihiqsvs=%4*<8S%|2H7qKOTW>q#gL*DES6!TAFDbD@{n zRx-BFIkZ?CKs;ab9Hl0xdp&!u;I0Q!Cj;9SUjYMOZdt$pX~Pop+AsFZ1z4Zc!#A|s zebrH~#@YeQT^i6Zv#ke%z0*(`EiWUWD><>K=ox0fiO#|_9gaFX7`y;bXMc%w>H_L) zE*FFc>TF6@0A(c*XDb9Mr+#$>;_Tlo%I!3!A8jmpz_-ffN$YrL@l3g&5ak>uyjbri ztJ6kGG?srC&9%lX@;Y$hu^okEl?RTb{z!+xR%KHyqUo23%NHRlBaMk-lwlyD-^-EE zbELp`2#gcHB7Lw&EZ$aKsiY1YWU2MnEVT2QTB>ma{zBW{Prq$h=VjI)v!@i>#<-e= z_*Oe)(S3dMhC}pYTyLgssQ&@{JD-hQ_ZCfKy3*>aU#;to7c;wk6V16X%JpvnIy1~~ zS97s7QBj8}JoA&=e@f}Aid?_9S0)s8V8&}gf77^^d$7LT=z;u97pk|o?iAOvb!bfM z6eqwi$sjKN#x(`Vhh;S0UmN}Efmcm|tG3SZywu0!sIBF$G?^O%wRPy0z2aK35f#Oa zrY){Yl6{WA*f3e`c5qy}O=*Kztpv|qz|ZMdmz<%31dI%RgX-7~XG)3riuA)bj`WDO zCgbob`n5>;mtv@019gv&i64X?fkk`5I5OL{6li4_S7r-@xLlbnKpL;u*2%8C3*S+C zGb>;z&s`c!Mt=kr5QoIIO%p2W1m!V292<0nER2V$1#$&L=4{5vw@* z(3jP|Jyt~$nvR!KgCOAsTSA8CaNt|XL)rRK=|~ueQRleL->w1O^xnZ!98<7`j5q}w z>|;yCEZXb70p;>B>SP0<6yO!zdOQEl257#Z@KJ>$`3JrQS2TF3qPj;DIY9D%VfquK zcLPVL28i5au8TzOgYf}D#lIx8k=-mw#&L4&{o<9W_6Mk`+r!hY%%s%k#@vp1SUjwy zbx6%$i)3xL%zC)Y-XrxW z0H>r`1)iWLZeN!^58q+sf3O0G!x-tctX)2)WakI0E!R6wMrANxE}#?^-zrB=#vHO` zg{S&Vpf4L@gIY$Uj=yULXF0Hh0K2CPu!Q{ZyfpzVAt8z4E3|oUDIVfV{Fd(FPJ{veaYFiAe4o3&nxhzwj9WMDuF$(y(_2kh41@ zsvgFw$Ohn98gfXG<62to(xds8rqT@h8`qAah3+7AfEwQ6eC+9YdS4<{tNXU@{j0{G zKFPAw`=OhsCgxxv7WIRH-#5Fx_mtYI z#j+}}hz0d@5ROZU-*;w>e`Uif#bu$E)3O^+|3drym)PCKOkBWy z?ND?D0dG;TurrI;#}}BGN-+UhlQXr5QC`XOEpg<;JKyu?$k=#76x8D)pNs8cCVb4yxn)aGv!C6g>YD}rBs;8 z;no{=jwkm!C^?$$P#ipd^Y~qt$HIDn9;txsO`;)L75TUYbtI{vH)yQK()&U3v(=|w zJ^7Rr-4?pepx0mP<0X(#t2s(YvHdW{W`Ji@HUCPk0=Z6$fTNFVzm&H}a*#lt&eL$M zw%souUVuP)A>cEbkGMkx_Uz%574-z>D^6Jfb!XqAv8uQCE=mxfUXNHCxOLLJ_#K(W zsgqCM+wVyRb+Y=WO%bu@Pk8jD9$PQIMU>Z;7FE%y`6zc}LcIXr5P1IXu`;jN%^PtTI=x zNOC_tCL)OI+zz_?(0lhU9>`{lN6_$qpQ_MT&3V@}!Ky{>NQ_eT#O$!Dl~qtS9!Z`C z14Ll1^Jb6Fpu@|dTW5HAf8h{VF7g+*B=ILh8%l$l^*7NpE1y+?LoXQ^RMz$^zK3aQ z&@B<(@FRC5dw{Vq!U%2rHIvnBt4~l>nuyPT_mf@q#68kq=ds~8vQq(PPm1gxw!NInN4|M*9H9$*cq;2a*#m*J#m&R7@>e-8X-W_XaEF3ODU%hew@R63Ho5|)#7e)ZzDbz zE3Y2P`w-IKW4@K^`prInlwa0gn^)$xC7PT-t7HY0+-5^osi7!mm%nZkYXi-o_XNDW zP?|XuIAm?@K%MywXjh**xrLc*;V-LINbx%Q@TEh~mgZhyvOs|e4K!ii`rThHOjkwK zDnwbauw-m`sa(4PXZ#^;ZY9lZr=P7Yx*oVi@vatx1MY8(1$Sg{E=B>TQn*=+&t)QR|ejqz{&YDk|4l2v%mHfUxE}rk(GFE zt-tEZ^=ke{ee3PYb=$F`R+e@0YE^y2NR8c}$_CaM$p$naZ!h(kMl2_!mlLzX{{dr8 zWc{_{G`)W8V;FNN&QlsR9Mss;!&jP)*}8s`?F*KZeL};Zet}#dJS;wu3>0w%ZwaHZ zoq@%g8aagHwYw$EWWxxoth`wifHuI5Bb*y=YB)FE9K^tuDFmW{pl(M(U%kv)1!F9b zz)BT=z~+#?e~j2;tQ+a6z9^_WZR1SAd_2&2-$%+0mDJ-KId;NetKD?uZ%N^Yj&2eC zYBY$@MWQwqUj@QEUxoASe%xGAd0)XzrWbOLMOJ-SSO69l4jVJO9t_?L7~^`$8ROPV z&ACWvs8_f=!vT(8zONX%YjcUD_3?30QltdFo(QEJ(*APHV*I9S@;SA6JfiLTyGa=BAkddy}nuq_B8V9npK1G4Td<&g+547TncM+)h=*X89s+#0A~%hMSG zIUO0N1#wOPTQb<%=x*)?O3~@B&Wx*X3C6CkKRT}wvELdzV7p89o{X>n6P~Zqw{fa(gAx0lw;4h4eS|}|FCB)u`&WWYsnTDU#{#2Svy;QptGXUdYa^T z`Pe0}T5d1zZoKmPBt#lHiV7?QURH1m&B@GkD_=0q=zNL2{F;<=AbcZ)lmDOe!N5a_ z1rzufci>5^1}?)#6Yom9o04VBS94+%&k*AB+RPHp&aWI>yn=vy|1pVdbFjPZ_SAKz29rA;b|BFigLVgSbrwM1nVFvr1&k9 z=peA?+?F>A5MW9YTu|Z8C!Sy|KM!Y$iQP$5r=8&V7=q7!Ri5Mc7#zPkUI9LaxcBaI zTLv3Z$AR}``J$)ar{$324am?yN7oa|Q>M>6olU!A#tvTiA^VKmw}hX5&uNp0mKG8la3kJ z=vDP0Qhe&|x4eSp6$GvfMT@?4;I9%VZpS%zgjrFTi!s=hDb_wlm2egGd zu!>0~u_1(qI2!3!``w^deu_p;2H|?FkYuB`%l4{A;#&=MHpyP$N=F`&i6GJ$dqhO6 zt`oX&7pI*%yFSwuxcB2taqq{o*o-Z#nPB!y%qHv@ssZSDZqSgi6Ukb`(evz1A%(Vq zMB;00SYL86Xb=x}i?A4g7py_Xg94i1UGr=|aF#i|uH-cnx|xZTO5Y?{7f{e)E9~uc z9=fFOoWQLgJ7eD?_I1w0HEfadf4n~Bi4f$bLAB8vOu{c;P&3}4yMe6ok8A44PnZ!T z8@oyU$|1)tIfb5?RkyKvIsgm&BUyRR+dIRrv1cpVxW(xPFf{8NbGi~U`L*>LKKjtz z_r52MClA<0Eu)*4^Tx{`#GZq<0>i_~J1{y$6X30w)bU=y*$5#YBt_xAkG8{4K6(lm zJGR~~_||ajv2cdB8MGh0-o~S-%H3;_aT8d@a=Z?{lI;u$fPlLfrYvRt#%oH&-6w2v zos#i*J8tq-X@AF}D#zCKa(VMjcO7p1ilTz4CDJpM(}2R5VoE-JNe<{PzpbtN(K@ws z*YD?hoVvR-KUjBs`pG}ya%vU{NY?tFcN8MN(cLEwb=@A?Vkh3P*28zXGbKGdaG$p@i5dX6@jW@;ZKv zsJUK6UWQY~g#*gM!&jA)acGt2d+g81MaRUq^rJ*%e6{KRNoE_ zq5gNcdoZZ{OFmMJ3ay+>ya1f&Va%x8w!n!FZmc3XjVG{d_T^d9gR^wZf;{kj8YR7Y zlG10+7PVgUw+zId%X{)IKjDXmCXZIN== zR#fOtC>Xq0mVr9$uOnOl>PgU27h{%lHEwm@6wgT0*t3+L`2B#>EzHaa|015QadO~v z=+>#x3x3Nq*Y6o7uj?~tW@as}W@uedskFG! zsTp`DOt~-FVIm_5`y^RD?aIMdp?6)Lj3}Ch%m;9*QZT0~?S?U>lmKimtP7wWK>#Oc zN@A(*U5xRg`O|sm`yWTk8a;Uo z*PZ?Gsh|%7)~~tv+^g%cl0l(O<~Efs+iLcwgd_*aUfZj7Z%ncK-wi3uONKgFau2g( zi!zGOQd}9uVZlWiMcyK(q{wy5L;Juh0n0q*HQk+KnHSB@0hak#I`OqPKEwyqIMDZ0 z)8mMuSyQ2j_jq4az*73q8(3aot1@4~npt(~pKv+rM5uZf(cKyAz#e7kZ zK=Mxa8({V=Ax0-uNac zOzmExTAP{Kazfu)!M}9Rh`w(7HI4@AxI{k|2{cg6XWv`}8mJm=m#+2#+%iwc4Btkx zE*7W8cmiJsp9O%&Q!tNp0Y0%^1l)QiRtTWi%=5aM?v>`O4G&l{O6^|NAwhkQ-Q7t*J@0#t#d#{+^^%&dF-;FM8{5r z^&3LbhBj#&h@11zGIY3N&kYrIolg@JN(x1VQ94`w)#UPd6a=-kAn1z1u$2ef8EXBG zQkLzrdgm*D%LXr4P?%VK?%3nw1@eG>m;+a}{=yl0@%iu^@dk+4gG4cMM1b=i^?EbT z^eLj6`fV_3r)}uUr=|ze80i3ET*fxu@Nn)|0K)t?wU?5{aLB@NIW>iEgAoD(yn}7R z8L$H&4VT`W_vNvH`q!%SREqKb=?}+ z54STS`xu`dLilRSpusXP3sH|sfwffD<67lma!T7m7I2p42wm7S)N}fBtPA8tgX#fa zZ?jN@2fXUp)#tImS@hLW$+mhv^?l@itH-M@gszF?CtjE}YXhhj=O$BtY6T7z4R%|M zQpsP?SDuqx!wlElFE8g$@i>Zmf%Mx!(a6ahc_x#NdW`_|v!%6xt)l#!t2frU0aUoq zES0ehkmq2=uhd*n2$@XfTy3`M_s&K;&edj?#yrAm0r>Hrl9fx>6>RapWx)NLOFNet zU#){4W{&pAHTQykB?1^qit1u*caSp9lFLLt$vr{rTza3Vm0w&EQj!qQj7mWu=C#0u zm`>9Z4K4{Uh+2BSYb6r{Gwc)17O!cwTfC)Jyg`%a`IS3!Vm8$kGiQo979Q`SG&Nx1 zQPsJ){$_I2-PH`mTr$F+ac=P!NZ@{u1P!nYCD1cK%0GuL|N zKq9y|3ckNFH{s2T7_BYOAzo%+!u-n>`akiA{_Vw!|CGZ72i_d~u0?))vd7p0@obyY zo{NsEhs~8=Us!ZpALKf&yBNL{<$w&@rfPyo`)t=J{!G}SwR7Gy^dH{Nt-S?(c@%tb zmhyJMw{Z0n7vF|#H#Jtc3mI0QgN1RJR)8x9^$@BG_qW!)wtD4Kg97&}KD-NA#YtY; zbSVLFFj0-bkGLBTRE$b@#HRoJPR->1=4GA3vz$7KIKz;o*agit1{SI(uptljr<=U_ z|C&4Ru%^zpj|Zqw0R^?VSW-qUs0cDzMUYldz!s@i&6VDabG-+Nu}KmNmY2}w@QbDrmWe?H&g5x}h! zuy1`*%N|+kLY_?c0RKSZy`_$QCEXx)G>VKfT@)iPYd&-SzI~?3hkccESa&YJPV9}P zl3i~ZDEZdV8M!aih`d*=^2gx&d*FnLbCB;k*vB?1j6SIRjWV2g^IhVe+ZH}f4_Q8O z5e;wq_1T!H^SyqSMC6ic+TuMyDOU_OM#INOq1czbS9iT~q(`tGFZr-LT?+CU>g?C$ z*2_+N#;_HKH#}i!028Ga$I@zk_z?gPvkAPLQh8eawoI5znxrKpEt(kT!4vSr6QX^} z5Mckl+GMoY23F`AGW#_!zoRH2)G8Y_01Q#38Z)1F0_ZN*m{md8Kz#TSkyqy1**O7`)O7PGZRyF7uB*y%{uTbXHmCc}*7c z$&mGFzLi&auu+EC=FlMz8ZX+;eg@Rjn`XJEt zFLW4BD?;49!Jv0Vi&<=Yr8-GUcpWlV)X`@*k(SXpKo2v3MzyzVk`?VSd?ulC)&<|~TM_boj{`t`h2(VXWSk+}qqz?10@X=L`%+2$e-Wf4GD2Mf&S$U;&3 z!1$moS_>VdGo%7B!#-pi&RplB#3y*T`P-ArhxZ}BrOzh}q^7*`Vq?W#U%m{^)COIC zGSUz8nJ=LQ0n;JUg9|1q5uOL@(a0otPQcRKrMfS%bhAVQ&vQvi!U68oc{TBOYy*Vm zffSA0nzSXTJ3vg}sth_Rj#1AGwnkTx1Ggx7{)@WRklc`bWZ1rGRiWqT0MZ;e_J`V)%t%RDF1@GU zrk)dD{-tVQ;udJ|<}+Q$<&IdK+oevyXTlFWCM$@u|akqLzbXU9HTsLcUvU zK;&!`w7Imr^X#;(E!eY(DT?MQ0%6xVL1Ej`F*sSrM`t!A+|!2X?Iu7v+E$j;bnfU2 zyj}E2s;f>?=Vde+53r}+Wq=NpWr8NGk0Oo&CaiUUqkswP#qX`Y<4g!4zlKY7M6R&8 z#mI?+Mwe3>hxuW-6`{!zpt;=Esg1oK%1qsZsEee z;Y`ed*Zni*`^y~X*Uw-!OMv1MJ~O@{?(%$tyFC5R_mdGVY?9XB;@cYwDCYV`jg4HXoKBH@;w#RqKTkqYgUrJu2ZuRwC zLPJj4kuB3E{5B=L@8|BO829Z*}< zU<+PFrZR~AeqgT|a)JxtRWRr;fmDl0>~3k6&#un(l6xaONZ358;5QGz%wz6)iCxNB z{sxizU%gXu-}m~CM?RHtt~K`nb$l9j@nUe9@^hL>xjsc;8Q7CmcW?hosuQrNOt-Q> zFzl>@_E|5hI;uL!kJwB)Zlv1y=qC`GS;kgX2eWD4N}Yf51jjIe(iRE|!+4pI-r7p! zyUsvIlzZZFlK5q zh#b+lIr?R7%G*jllL!M%zR2Q|A3QGoPVGV(|GqWxXi*PUd zxe^w;@oXV%yvB8#eP$O~VDVIL{H#v~VSi9Tsm%nXw(`i|1o);z{u;nItfVGzzcs4M zxcyf~msj|mfP~QLEixMFYrdMJByOR=A7~>k?CFvj$!qMgwty#WBBYy1x9TbUBVA{o zW_0@R{_crKjDs?X0!Qo?tx%yMM}|#be1W7EYjnx52E_ACsrH+!?v(Eg)l!3tE2c7B z!sk9GLg%RB2>H;B8&xJwJ+j5Au2oelGx_I}s-E3*@oLKJQ_yuU9D3_ZAb(O z=O2P1_8R#8`#Y(wZ%n|!xx)Q<4LCSgoWG4uy;$|%zzahD?_y^Z`J_b z3;ZtP5RuCeIK=taa1Jrq{^-GAKn7)vxnpT00}CUEvLml^U##}vfW3X9r8L6N&_SS{ z>JqG5DSkGkSdK|d&rN@ny23&_Ozoy0L7FyFbjeyi&Ee3flk%lQE;-5BGAa&Bk&Z zarK#P_N?gyh;a(={pJ6u=4$f!i53WZg<9XLVyXwXa9B*QJ=w_b&y*Gv^OTXR9TIXkS$_xKDF+bI54k$e9^)BOeCn1-xZwDZlhg=v$zIZYCW-2=b9@-ET&#- zRn$sBeg|govR)13cW}+Fv-bzT!{sjx9)jQD5I6+rN=0y2A3La-`lRyTmNO}XFXtIu zHF+KK<$z9St>);a2MLS7mqR;2)$C&&C(Wj-H*pE=D`$pXdk}Qpfj-^MP4Qgg70UNB z#WzYfD6OhK^m$fDgld7g01h)PUR{KH+g6kQ&A&bj4C<{aOcS)TnysGcYrUSgA#$M= z(H81{Zk(Ha0Rx5{AUgf>8yFAUTy4^8Z#dT7vwS>w=_2HhX7Q*ebr_YDMsr-jk3A|tr*PY}Fj1fLj) z3Qe44q}8Y_UT;Uny5uU9_FCsW(%8s``j{kd5U=J4rWBrLY9m|SZX#Mx!B$tq=nKYd zbuViY!B&T&q^H%#s3p^38eLAmY1E_(>(_MCP1&=RaZlU zd1rbOyvbTj-Jsb0xfRh&mF4?P+epTNYjO*Dtx>r_0VN#AE2%D?^z{h_w{&mB+wGQ? zc@%Bh8B|D45v*#OVbYk+%BM7I=f2LVzmikS_TIbPMQ+1|Xwf+l(Yiq+GXh9cb8{Ki z&E0X=$i~yM^Zx1|x`T%-cH6c{y|mQ*A=D#QJm_8^Tr!{d^n)1x6>x5%kS_p6Whb^s zeKo09MyOoD9t1oQYBwbN;VK% z(rhis5zJ#&4JfHYJK0j*8t8lyoQgSQ`Q@TprV&}P;@@K8Cn5;*%c~GQ>va+|E;Z|N{Br73h z8);3!9_PQd{dpsWVz4Q6bIdtekM6~SX{jy+xL)~(zgXhsYH)nM_qdgRwt{G>bildU3Iy9(1d+Q0j}!dA2_X&(pL!>Xa<{vl(Ks8lvfcCR2i~r+StL!>5W6`M zu^!#zV}c>*tus8C=GI?mj4m@(pOaN`aGBkRh`u1*AdVjKee=^Zy7z9%l{S9-a)Z?@cA|1r!a{UV34y2DRs z74wC&7NK)>)apBq27p-Hq0HoBZEPtoxb@Bsdn+q4 z^~(79tkzv)JQO^Fd{+6MP(+Ys7YJQ%r&DT4HLo4)E7Pv&Y4h`+RR1D*ZeDS*Sh_Ei zpRY!b^`fo^A|K;SmgRdSOAQ|DrDG4+nogOOI0@n~)hF^Fx{zR^NCn68rjLm}AtIad z1!RL==I$BC%a~opcgu|=oS6gt9!cVhnYk})&=Nc0W7EolHu6=>Ge%e&dBA)_e-t+5 zhb!5Ee6)}JLq2tO;Huut@Z9-5I4M}FVmq`pyHP|vh|MFkCzia*nyFRRq literal 0 HcmV?d00001 diff --git a/structure.py b/structure.py index 8cdc98a..b24b425 100644 --- a/structure.py +++ b/structure.py @@ -24,21 +24,4 @@ def interleave_ecc(ecc): ie = [] for t in zip(*ecc): ie += list(t) - return ie - -if __name__ == '__main__': - dc = [[67,85,70,134,87,38,85,194,119,50,6,18,6,103,38], - [246,246,66,7,118,134,242,7,38,86,22,198,199,146,6], - [182,230,247,119,50,7,118,134,87,38,82,6,134,151,50,7], - [70,247,118,86,194,6,151,50,16,236,17,236,17,236,17,236]] - ecc = [[213, 199, 11, 45, 115, 247, 241, 223, 229, 248, 154, 117, 154, 111, 86, 161, 111, 39], - [87, 204, 96, 60, 202, 182, 124, 157, 200, 134, 27, 129, 209, 17, 163, 163, 120, 133], - [148, 116, 177, 212, 76, 133, 75, 242, 238, 76, 195, 230, 189, 10, 108, 240, 192, 141], - [235, 159, 5, 173, 24, 147, 59, 33, 106, 40, 255, 172, 82, 2, 131, 32, 178, 236]] - v = 5 - l = 'Q' - finalbits = structure_final_bits(v,l,dc,ecc) - print(finalbits) - - a = '01000011111101101011011001000110010101011111011011100110111101110100011001000010111101110111011010000110000001110111011101010110010101110111011000110010110000100010011010000110000001110000011001010101111100100111011010010111110000100000011110000110001100100111011100100110010101110001000000110010010101100010011011101100000001100001011001010010000100010001001011000110000001101110110000000110110001111000011000010001011001111001001010010111111011000010011000000110001100100001000100000111111011001101010101010111100101001110101111000111110011000111010010011111000010110110000010110001000001010010110100111100110101001010110101110011110010100100110000011000111101111011011010000101100100111111000101111100010010110011101111011111100111011111001000100001111001011100100011101110011010101111100010000110010011000010100010011010000110111100001111111111011101011000000111100110101011001001101011010001101111010101001001101111000100010000101000000010010101101010001101101100100000111010000110100011111100000010000001101111011110001100000010110010001001111000010110001101111011000000000' - print(bool(a==finalbits)) \ No newline at end of file + return ie \ No newline at end of file