| <!doctype html> |
| <html lang="ru"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>LocalDrop — локальная передача файлов</title> |
| <meta name="theme-color" content="#0ea5e9" /> |
| <meta name="description" content="Передача файлов между устройствами напрямую через WebRTC, без сервера." /> |
| <link rel="manifest" href="data:application/manifest+json,{%22name%22: %22LocalDrop%22, %22short_name%22: %22LocalDrop%22, %22description%22: %22\u041f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0447\u0435\u0440\u0435\u0437 WebRTC, \u0431\u0435\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.%22, %22start_url%22: %22.%22, %22display%22: %22standalone%22, %22background_color%22: %22%23f8fafc%22, %22theme_color%22: %22%230ea5e9%22, %22icons%22: [{%22src%22: %22data:image/png;base64,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%22, %22sizes%22: %22192x192%22, %22type%22: %22image/png%22, %22purpose%22: %22any%22}, {%22src%22: %22data:image/png;base64,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%22, %22sizes%22: %22512x512%22, %22type%22: %22image/png%22, %22purpose%22: %22any%22}, {%22src%22: %22data:image/png;base64,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%22, %22sizes%22: %22512x512%22, %22type%22: %22image/png%22, %22purpose%22: %22maskable%22}]}" /> |
| <link rel="icon" href="data:image/png;base64,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" /> |
| <link rel="apple-touch-icon" href="data:image/png;base64,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" /> |
| <meta name="apple-mobile-web-app-capable" content="yes" /> |
| <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> |
| <meta name="apple-mobile-web-app-title" content="LocalDrop" /> |
| <style> |
| :root{ |
| --bg:#f8fafc;--text:#0f172a;--muted:#64748b;--muted-2:#94a3b8;--label:#475569; |
| --heading-hover:#1e293b;--card-bg:#ffffff;--border:#e2e8f0;--border-soft:#f1f5f9; |
| --input-bg:#f8fafc;--input-text:#1e293b;--code-bg:#f8fafc; |
| --accent:#0ea5e9;--accent-soft-bg:#f0f9ff;--accent-soft-border:#7dd3fc; |
| --green:#10b981;--green-soft-bg:#ecfdf5;--green-soft-border:#6ee7b7;--green-strong:#059669; |
| --amber:#f59e0b;--red:#ef4444;--red-hover:#fb7185; |
| --shadow-sm:rgba(15,23,42,.05);--shadow-md:rgba(15,23,42,.10);--shadow-lg:rgba(15,23,42,.25); |
| --overlay-bg:rgba(15,23,42,.45);--switch-track:#e2e8f0;--switch-thumb:#ffffff; |
| --disabled-bg:#e2e8f0;--disabled-text:#94a3b8;--peer-chip-text:#334155;--remove-color:#cbd5e1; |
| font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; |
| color:var(--text);background:var(--bg);font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased |
| } |
| [data-theme="dark"]{ |
| --bg:#0a0f1c;--text:#e5e9f0;--muted:#8b96a8;--muted-2:#606b7d;--label:#c3cad6; |
| --heading-hover:#ffffff;--card-bg:#131b2c;--border:#25324a;--border-soft:#1c2536; |
| --input-bg:#0f1727;--input-text:#e5e9f0;--code-bg:#0f1727; |
| --accent:#38bdf8;--accent-soft-bg:#0f2438;--accent-soft-border:#1c4966; |
| --green:#34d399;--green-soft-bg:#0d2a20;--green-soft-border:#155e42;--green-strong:#34d399; |
| --amber:#fbbf24;--red:#f87171;--red-hover:#fca5a5; |
| --shadow-sm:rgba(0,0,0,.3);--shadow-md:rgba(0,0,0,.4);--shadow-lg:rgba(0,0,0,.5); |
| --overlay-bg:rgba(0,0,0,.6);--switch-track:#28334a;--switch-thumb:#e5e9f0; |
| --disabled-bg:#1c2536;--disabled-text:#5b6577;--peer-chip-text:#c3cad6;--remove-color:#3d4b64; |
| } |
| *{box-sizing:border-box} |
| body{margin:0;min-width:320px;min-height:100vh;background:var(--bg);color:var(--text);transition:background .2s,color .2s} |
| .app-shell{min-height:100vh} |
| .screen{position:relative;min-height:100vh;width:min(100% - 32px,672px);margin:0 auto;padding:24px 0} |
| .icon-button{position:absolute;top:24px;right:0;width:40px;height:40px;border-radius:12px;border:1px solid var(--border);background:var(--card-bg);display:grid;place-items:center;color:var(--muted);cursor:pointer;transition:.2s;padding:0} |
| .icon-button:hover{color:var(--accent);border-color:var(--accent-soft-border)} |
| .icon-button svg{width:20px;height:20px} |
| .home{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center} |
| .brand{margin-bottom:48px} |
| .brand-row{display:flex;align-items:center;justify-content:center;gap:12px;margin-bottom:16px} |
| .logo{width:48px;height:48px;border-radius:18px;background:var(--accent);display:grid;place-items:center;color:white;box-shadow:0 12px 28px rgba(14,165,233,.3)} |
| .logo svg,.tile-icon svg,.icon svg{width:28px;height:28px} |
| h1{font-size:30px;line-height:36px;margin:0;font-weight:800;letter-spacing:-.025em} |
| h2{font-size:24px;line-height:32px;margin:0;font-weight:800} |
| .muted{color:var(--muted)} |
| .brand p{font-size:18px;line-height:28px;max-width:430px;margin:0} |
| .tiles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;width:100%;max-width:576px} |
| .tile{position:relative;display:flex;flex-direction:column;align-items:center;gap:16px;padding:32px;border:1px solid var(--border);border-radius:28px;background:var(--card-bg);box-shadow:0 1px 2px var(--shadow-sm);cursor:pointer;transition:.2s;color:inherit;font:inherit} |
| .tile:hover{transform:translateY(-4px);box-shadow:0 20px 32px var(--shadow-md)} |
| .tile:focus-visible,.button:focus-visible,.back:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible{outline:3px solid rgba(14,165,233,.35);outline-offset:2px} |
| .tile-icon{width:64px;height:64px;border-radius:18px;display:grid;place-items:center} |
| .tile.send:hover{border-color:var(--accent-soft-border)} |
| .tile.receive:hover{border-color:var(--green-soft-border)} |
| .tile.send .tile-icon{background:var(--accent-soft-bg);color:var(--accent)} |
| .tile.receive .tile-icon{background:var(--green-soft-bg);color:var(--green)} |
| .tile-title{font-size:20px;font-weight:700;margin-bottom:4px} |
| .tile-desc,.tiny{font-size:14px;color:var(--muted)} |
| .footnote{margin-top:24px;font-size:12px;color:var(--muted-2);max-width:430px} |
| .back{display:inline-flex;align-items:center;gap:8px;border:0;background:transparent;color:var(--muted);font-weight:600;font-size:14px;padding:0;margin-bottom:24px;cursor:pointer} |
| .back:hover{color:var(--heading-hover)} |
| .header{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:24px} |
| .badge{display:flex;align-items:center;gap:8px;font-size:14px;font-weight:700} |
| .dot{width:8px;height:8px;border-radius:999px;background:currentColor} |
| .idle{color:var(--muted-2)} |
| .waiting{color:var(--amber)} |
| .signaling,.connecting{color:var(--accent)} |
| .connected,.done{color:var(--green)} |
| .error,.disconnected{color:var(--red)} |
| .pulse{animation:pulse 1.4s ease-in-out infinite} |
| @keyframes pulse{50%{opacity:.35}} |
| .card{background:var(--card-bg);border:1px solid var(--border-soft);border-radius:28px;box-shadow:0 1px 2px var(--shadow-sm);padding:24px;margin-bottom:20px} |
| .settings-card{width:100%;max-width:576px;margin-top:20px;text-align:left} |
| .settings-card>*:first-child{margin-top:0} |
| .section-title{font-size:12px;font-weight:800;color:var(--muted-2);text-transform:uppercase;letter-spacing:.04em;margin-bottom:14px} |
| .field-group{display:flex;flex-direction:column;gap:8px;margin:8px 0 10px} |
| .field-group .plain-input{margin:0} |
| .center{text-align:center} |
| .code-row{display:flex;justify-content:center;gap:8px;margin:12px 0} |
| .code-char{width:44px;height:56px;display:grid;place-items:center;border:1px solid var(--border);border-radius:12px;background:var(--code-bg);font-size:24px;font-weight:800} |
| .drop{border:2px dashed var(--border);border-radius:28px;padding:40px;display:flex;flex-direction:column;align-items:center;gap:12px;cursor:pointer;transition:.2s;margin-bottom:20px} |
| .drop:hover,.drop.drag{border-color:var(--accent);background:var(--accent-soft-bg)} |
| .hidden{display:none!important} |
| .queue,.files{display:flex;flex-direction:column;gap:12px;margin-bottom:20px} |
| .file-row{display:flex;align-items:center;gap:12px;background:var(--card-bg);border:1px solid var(--border-soft);border-radius:18px;padding:12px;box-shadow:0 1px 2px var(--shadow-sm)} |
| .file-main{min-width:0;flex:1} |
| .file-name{font-size:14px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} |
| .remove{border:0;background:transparent;color:var(--remove-color);font-size:22px;cursor:pointer} |
| .remove:hover{color:var(--red-hover)} |
| .button{width:100%;border:0;border-radius:18px;padding:16px 18px;color:white;font-weight:800;font-size:16px;cursor:pointer;transition:.2s;display:inline-flex;align-items:center;justify-content:center;gap:8px;margin-top:14px} |
| .button.sky{background:var(--accent);box-shadow:0 14px 28px rgba(14,165,233,.28)} |
| .button.green{background:var(--green);box-shadow:0 14px 28px rgba(16,185,129,.28)} |
| .button:hover:not(:disabled){filter:brightness(.96);transform:translateY(-1px)} |
| .button:disabled{background:var(--disabled-bg);color:var(--disabled-text);box-shadow:none;cursor:not-allowed} |
| input,textarea,select{width:100%;border:2px solid var(--border);background:var(--input-bg);color:var(--input-text);font:inherit;padding:12px;border-radius:16px;transition:border-color .2s} |
| #roomInput{text-align:center;font-size:30px;font-weight:800;letter-spacing:.22em;text-transform:uppercase;margin-top:20px} |
| .plain-input{text-align:left;font-size:14px;font-weight:500;letter-spacing:0;text-transform:none;margin:8px 0 10px} |
| .field-label{display:block;font-size:13px;font-weight:800;color:var(--label)} |
| .field-divider{height:1px;background:var(--border-soft);margin:18px 0} |
| .check-row{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:700;color:var(--label);margin:8px 0 10px} |
| .check-row input{width:18px;height:18px;margin:0;accent-color:var(--accent)} |
| .switch-row{display:flex;align-items:center;justify-content:space-between;gap:16px;margin:14px 0;cursor:pointer} |
| .switch-label{display:flex;flex-direction:column;gap:2px} |
| .switch{position:relative;display:inline-block;width:44px;height:26px;flex:0 0 auto} |
| .switch input{opacity:0;width:0;height:0;position:absolute} |
| .switch-slider{position:absolute;inset:0;background:var(--switch-track);transition:.2s;border-radius:999px} |
| .switch-slider:before{content:"";position:absolute;height:20px;width:20px;left:3px;top:3px;background:var(--switch-thumb);transition:.2s;border-radius:50%;box-shadow:0 1px 2px var(--shadow-sm)} |
| .switch input:checked+.switch-slider{background:var(--green)} |
| .switch input:checked+.switch-slider:before{transform:translateX(18px)} |
| .switch input:focus-visible+.switch-slider{outline:3px solid rgba(14,165,233,.35);outline-offset:2px} |
| .peer-list{display:flex;flex-direction:column;gap:8px;margin-top:10px} |
| .peer-button{text-align:left} |
| .peer-quick{margin-top:20px;padding-top:16px;border-top:1px solid var(--border-soft)} |
| .peer-quick-label{font-size:12px;font-weight:800;color:var(--muted-2);text-transform:uppercase;letter-spacing:.04em;margin-bottom:10px} |
| .peer-chips{display:flex;flex-wrap:wrap;gap:8px;justify-content:center} |
| .peer-chip{border:1px solid var(--border);background:var(--input-bg);color:var(--peer-chip-text);border-radius:999px;padding:8px 16px;font-size:13px;font-weight:700;cursor:pointer;transition:.15s} |
| .peer-chip:hover{background:var(--accent-soft-bg);border-color:var(--accent-soft-border);color:var(--accent)} |
| .advanced-settings{margin-top:10px} |
| .advanced-settings summary{cursor:pointer;font-size:13px;font-weight:800;color:var(--muted)} |
| .small-button{border:1px solid var(--border);background:var(--card-bg);color:var(--label);border-radius:12px;padding:9px 12px;font-weight:700;cursor:pointer} |
| .small-button:hover{background:var(--input-bg)} |
| .small-button:disabled{opacity:.5;cursor:not-allowed;pointer-events:none} |
| .settings-card .small-button{width:100%;margin:4px 0 10px} |
| .progress{height:6px;background:var(--border-soft);border-radius:999px;overflow:hidden;margin-top:10px} |
| .bar{height:100%;width:0;background:linear-gradient(90deg,#38bdf8,#0ea5e9);border-radius:999px} |
| .done .bar{width:100%;background:#34d399} |
| .download{color:var(--green-strong);text-decoration:none;font-weight:800;font-size:13px;background:var(--green-soft-bg);padding:7px 10px;border-radius:12px} |
| .status-text{font-size:12px;color:var(--muted);margin-top:6px;text-align:right} |
| .notice{font-size:13px;line-height:20px;color:var(--muted);background:var(--input-bg);border-radius:16px;padding:12px;margin-bottom:20px} |
| .error-box{color:var(--red);font-size:14px;margin-top:8px} |
| .invite-overlay{position:fixed;inset:0;background:var(--overlay-bg);display:flex;align-items:center;justify-content:center;padding:20px;z-index:50} |
| .invite-card{background:var(--card-bg);border-radius:28px;padding:28px;max-width:360px;width:100%;text-align:center;box-shadow:0 20px 60px var(--shadow-lg)} |
| .invite-card h3{margin:0 0 8px;font-size:20px;font-weight:800} |
| .invite-actions{display:flex;flex-direction:column;gap:10px;margin-top:18px} |
| .invite-actions .button{margin-top:0} |
| .invite-actions .small-button{width:100%} |
| .qr-wrap{display:flex;justify-content:center;margin:16px 0 4px;cursor:pointer} |
| .qr-wrap svg{background:white;border-radius:12px;padding:8px;transition:.15s} |
| .qr-wrap:hover svg{transform:scale(1.03)} |
| .qr-scanner{margin-top:16px;padding-top:16px;border-top:1px solid var(--border-soft);display:flex;flex-direction:column;align-items:center;gap:10px} |
| .qr-scanner video{width:100%;max-width:320px;border-radius:18px;background:#000} |
| .qr-scanner .small-button{width:100%;max-width:320px} |
| .folder-banner{display:flex;flex-direction:column;gap:10px;align-items:flex-start;margin-bottom:20px} |
| .breadcrumb{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-bottom:12px;font-size:13px;font-weight:700} |
| .crumb{border:0;background:transparent;color:var(--accent);cursor:pointer;padding:2px 4px;font:inherit} |
| .crumb:last-child{color:var(--text);cursor:default} |
| .crumb-sep{color:var(--muted-2)} |
| .browser-list{display:flex;flex-direction:column;gap:2px;max-height:320px;overflow-y:auto;margin-bottom:14px} |
| .browser-row{display:flex;align-items:center;gap:10px;width:100%;border:0;background:transparent;text-align:left;padding:10px 8px;border-radius:12px;cursor:pointer;font:inherit;color:inherit} |
| .browser-row:hover{background:var(--input-bg)} |
| .browser-row input[type="checkbox"]{width:16px;height:16px;margin:0;accent-color:var(--accent)} |
| .browser-row .browser-size{margin-left:auto} |
| .file-row.error .status-text{color:var(--red)} |
| .receiver-chip{display:inline-flex;align-items:center;gap:6px;cursor:default} |
| .receiver-dot{width:8px;height:8px;border-radius:999px;background:var(--muted-2);flex:0 0 auto} |
| .receiver-chip.connected .receiver-dot{background:var(--green)} |
| .receiver-chip.connecting .receiver-dot{background:var(--amber)} |
| .receiver-chip.disconnected .receiver-dot{background:var(--red)} |
| .aggregate-row{display:flex;justify-content:space-between;font-size:13px;font-weight:700;margin-bottom:6px} |
| .aggregate-row.tiny{font-weight:600;margin-top:6px;margin-bottom:0} |
| .tiles{grid-template-columns:1fr} |
| .screen{width:min(100% - 24px,672px)} |
| .header{align-items:flex-start;flex-direction:column} |
| .code-char{width:38px;height:50px} |
| .small-button{width:100%} |
| } |
| |
| </style> |
| </head> |
| <body> |
| <main id="app" class="app-shell"></main> |
| <script> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| var qrcode = function() { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| var qrcode = function(typeNumber, errorCorrectionLevel) { |
| |
| var PAD0 = 0xEC; |
| var PAD1 = 0x11; |
| |
| var _typeNumber = typeNumber; |
| var _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel]; |
| var _modules = null; |
| var _moduleCount = 0; |
| var _dataCache = null; |
| var _dataList = []; |
| |
| var _this = {}; |
| |
| var makeImpl = function(test, maskPattern) { |
| |
| _moduleCount = _typeNumber * 4 + 17; |
| _modules = function(moduleCount) { |
| var modules = new Array(moduleCount); |
| for (var row = 0; row < moduleCount; row += 1) { |
| modules[row] = new Array(moduleCount); |
| for (var col = 0; col < moduleCount; col += 1) { |
| modules[row][col] = null; |
| } |
| } |
| return modules; |
| }(_moduleCount); |
| |
| setupPositionProbePattern(0, 0); |
| setupPositionProbePattern(_moduleCount - 7, 0); |
| setupPositionProbePattern(0, _moduleCount - 7); |
| setupPositionAdjustPattern(); |
| setupTimingPattern(); |
| setupTypeInfo(test, maskPattern); |
| |
| if (_typeNumber >= 7) { |
| setupTypeNumber(test); |
| } |
| |
| if (_dataCache == null) { |
| _dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList); |
| } |
| |
| mapData(_dataCache, maskPattern); |
| }; |
| |
| var setupPositionProbePattern = function(row, col) { |
| |
| for (var r = -1; r <= 7; r += 1) { |
| |
| if (row + r <= -1 || _moduleCount <= row + r) continue; |
| |
| for (var c = -1; c <= 7; c += 1) { |
| |
| if (col + c <= -1 || _moduleCount <= col + c) continue; |
| |
| if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) |
| || (0 <= c && c <= 6 && (r == 0 || r == 6) ) |
| || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { |
| _modules[row + r][col + c] = true; |
| } else { |
| _modules[row + r][col + c] = false; |
| } |
| } |
| } |
| }; |
| |
| var getBestMaskPattern = function() { |
| |
| var minLostPoint = 0; |
| var pattern = 0; |
| |
| for (var i = 0; i < 8; i += 1) { |
| |
| makeImpl(true, i); |
| |
| var lostPoint = QRUtil.getLostPoint(_this); |
| |
| if (i == 0 || minLostPoint > lostPoint) { |
| minLostPoint = lostPoint; |
| pattern = i; |
| } |
| } |
| |
| return pattern; |
| }; |
| |
| var setupTimingPattern = function() { |
| |
| for (var r = 8; r < _moduleCount - 8; r += 1) { |
| if (_modules[r][6] != null) { |
| continue; |
| } |
| _modules[r][6] = (r % 2 == 0); |
| } |
| |
| for (var c = 8; c < _moduleCount - 8; c += 1) { |
| if (_modules[6][c] != null) { |
| continue; |
| } |
| _modules[6][c] = (c % 2 == 0); |
| } |
| }; |
| |
| var setupPositionAdjustPattern = function() { |
| |
| var pos = QRUtil.getPatternPosition(_typeNumber); |
| |
| for (var i = 0; i < pos.length; i += 1) { |
| |
| for (var j = 0; j < pos.length; j += 1) { |
| |
| var row = pos[i]; |
| var col = pos[j]; |
| |
| if (_modules[row][col] != null) { |
| continue; |
| } |
| |
| for (var r = -2; r <= 2; r += 1) { |
| |
| for (var c = -2; c <= 2; c += 1) { |
| |
| if (r == -2 || r == 2 || c == -2 || c == 2 |
| || (r == 0 && c == 0) ) { |
| _modules[row + r][col + c] = true; |
| } else { |
| _modules[row + r][col + c] = false; |
| } |
| } |
| } |
| } |
| } |
| }; |
| |
| var setupTypeNumber = function(test) { |
| |
| var bits = QRUtil.getBCHTypeNumber(_typeNumber); |
| |
| for (var i = 0; i < 18; i += 1) { |
| var mod = (!test && ( (bits >> i) & 1) == 1); |
| _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod; |
| } |
| |
| for (var i = 0; i < 18; i += 1) { |
| var mod = (!test && ( (bits >> i) & 1) == 1); |
| _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; |
| } |
| }; |
| |
| var setupTypeInfo = function(test, maskPattern) { |
| |
| var data = (_errorCorrectionLevel << 3) | maskPattern; |
| var bits = QRUtil.getBCHTypeInfo(data); |
| |
| |
| for (var i = 0; i < 15; i += 1) { |
| |
| var mod = (!test && ( (bits >> i) & 1) == 1); |
| |
| if (i < 6) { |
| _modules[i][8] = mod; |
| } else if (i < 8) { |
| _modules[i + 1][8] = mod; |
| } else { |
| _modules[_moduleCount - 15 + i][8] = mod; |
| } |
| } |
| |
| |
| for (var i = 0; i < 15; i += 1) { |
| |
| var mod = (!test && ( (bits >> i) & 1) == 1); |
| |
| if (i < 8) { |
| _modules[8][_moduleCount - i - 1] = mod; |
| } else if (i < 9) { |
| _modules[8][15 - i - 1 + 1] = mod; |
| } else { |
| _modules[8][15 - i - 1] = mod; |
| } |
| } |
| |
| |
| _modules[_moduleCount - 8][8] = (!test); |
| }; |
| |
| var mapData = function(data, maskPattern) { |
| |
| var inc = -1; |
| var row = _moduleCount - 1; |
| var bitIndex = 7; |
| var byteIndex = 0; |
| var maskFunc = QRUtil.getMaskFunction(maskPattern); |
| |
| for (var col = _moduleCount - 1; col > 0; col -= 2) { |
| |
| if (col == 6) col -= 1; |
| |
| while (true) { |
| |
| for (var c = 0; c < 2; c += 1) { |
| |
| if (_modules[row][col - c] == null) { |
| |
| var dark = false; |
| |
| if (byteIndex < data.length) { |
| dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); |
| } |
| |
| var mask = maskFunc(row, col - c); |
| |
| if (mask) { |
| dark = !dark; |
| } |
| |
| _modules[row][col - c] = dark; |
| bitIndex -= 1; |
| |
| if (bitIndex == -1) { |
| byteIndex += 1; |
| bitIndex = 7; |
| } |
| } |
| } |
| |
| row += inc; |
| |
| if (row < 0 || _moduleCount <= row) { |
| row -= inc; |
| inc = -inc; |
| break; |
| } |
| } |
| } |
| }; |
| |
| var createBytes = function(buffer, rsBlocks) { |
| |
| var offset = 0; |
| |
| var maxDcCount = 0; |
| var maxEcCount = 0; |
| |
| var dcdata = new Array(rsBlocks.length); |
| var ecdata = new Array(rsBlocks.length); |
| |
| for (var r = 0; r < rsBlocks.length; r += 1) { |
| |
| var dcCount = rsBlocks[r].dataCount; |
| var ecCount = rsBlocks[r].totalCount - dcCount; |
| |
| maxDcCount = Math.max(maxDcCount, dcCount); |
| maxEcCount = Math.max(maxEcCount, ecCount); |
| |
| dcdata[r] = new Array(dcCount); |
| |
| for (var i = 0; i < dcdata[r].length; i += 1) { |
| dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; |
| } |
| offset += dcCount; |
| |
| var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); |
| var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); |
| |
| var modPoly = rawPoly.mod(rsPoly); |
| ecdata[r] = new Array(rsPoly.getLength() - 1); |
| for (var i = 0; i < ecdata[r].length; i += 1) { |
| var modIndex = i + modPoly.getLength() - ecdata[r].length; |
| ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0; |
| } |
| } |
| |
| var totalCodeCount = 0; |
| for (var i = 0; i < rsBlocks.length; i += 1) { |
| totalCodeCount += rsBlocks[i].totalCount; |
| } |
| |
| var data = new Array(totalCodeCount); |
| var index = 0; |
| |
| for (var i = 0; i < maxDcCount; i += 1) { |
| for (var r = 0; r < rsBlocks.length; r += 1) { |
| if (i < dcdata[r].length) { |
| data[index] = dcdata[r][i]; |
| index += 1; |
| } |
| } |
| } |
| |
| for (var i = 0; i < maxEcCount; i += 1) { |
| for (var r = 0; r < rsBlocks.length; r += 1) { |
| if (i < ecdata[r].length) { |
| data[index] = ecdata[r][i]; |
| index += 1; |
| } |
| } |
| } |
| |
| return data; |
| }; |
| |
| var createData = function(typeNumber, errorCorrectionLevel, dataList) { |
| |
| var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel); |
| |
| var buffer = qrBitBuffer(); |
| |
| for (var i = 0; i < dataList.length; i += 1) { |
| var data = dataList[i]; |
| buffer.put(data.getMode(), 4); |
| buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); |
| data.write(buffer); |
| } |
| |
| |
| var totalDataCount = 0; |
| for (var i = 0; i < rsBlocks.length; i += 1) { |
| totalDataCount += rsBlocks[i].dataCount; |
| } |
| |
| if (buffer.getLengthInBits() > totalDataCount * 8) { |
| throw 'code length overflow. (' |
| + buffer.getLengthInBits() |
| + '>' |
| + totalDataCount * 8 |
| + ')'; |
| } |
| |
| |
| if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { |
| buffer.put(0, 4); |
| } |
| |
| |
| while (buffer.getLengthInBits() % 8 != 0) { |
| buffer.putBit(false); |
| } |
| |
| |
| while (true) { |
| |
| if (buffer.getLengthInBits() >= totalDataCount * 8) { |
| break; |
| } |
| buffer.put(PAD0, 8); |
| |
| if (buffer.getLengthInBits() >= totalDataCount * 8) { |
| break; |
| } |
| buffer.put(PAD1, 8); |
| } |
| |
| return createBytes(buffer, rsBlocks); |
| }; |
| |
| _this.addData = function(data, mode) { |
| |
| mode = mode || 'Byte'; |
| |
| var newData = null; |
| |
| switch(mode) { |
| case 'Numeric' : |
| newData = qrNumber(data); |
| break; |
| case 'Alphanumeric' : |
| newData = qrAlphaNum(data); |
| break; |
| case 'Byte' : |
| newData = qr8BitByte(data); |
| break; |
| case 'Kanji' : |
| newData = qrKanji(data); |
| break; |
| default : |
| throw 'mode:' + mode; |
| } |
| |
| _dataList.push(newData); |
| _dataCache = null; |
| }; |
| |
| _this.isDark = function(row, col) { |
| if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { |
| throw row + ',' + col; |
| } |
| return _modules[row][col]; |
| }; |
| |
| _this.getModuleCount = function() { |
| return _moduleCount; |
| }; |
| |
| _this.make = function() { |
| if (_typeNumber < 1) { |
| var typeNumber = 1; |
| |
| for (; typeNumber < 40; typeNumber++) { |
| var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel); |
| var buffer = qrBitBuffer(); |
| |
| for (var i = 0; i < _dataList.length; i++) { |
| var data = _dataList[i]; |
| buffer.put(data.getMode(), 4); |
| buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); |
| data.write(buffer); |
| } |
| |
| var totalDataCount = 0; |
| for (var i = 0; i < rsBlocks.length; i++) { |
| totalDataCount += rsBlocks[i].dataCount; |
| } |
| |
| if (buffer.getLengthInBits() <= totalDataCount * 8) { |
| break; |
| } |
| } |
| |
| _typeNumber = typeNumber; |
| } |
| |
| makeImpl(false, getBestMaskPattern() ); |
| }; |
| |
| _this.createTableTag = function(cellSize, margin) { |
| |
| cellSize = cellSize || 2; |
| margin = (typeof margin == 'undefined')? cellSize * 4 : margin; |
| |
| var qrHtml = ''; |
| |
| qrHtml += '<table style="'; |
| qrHtml += ' border-width: 0px; border-style: none;'; |
| qrHtml += ' border-collapse: collapse;'; |
| qrHtml += ' padding: 0px; margin: ' + margin + 'px;'; |
| qrHtml += '">'; |
| qrHtml += '<tbody>'; |
| |
| for (var r = 0; r < _this.getModuleCount(); r += 1) { |
| |
| qrHtml += '<tr>'; |
| |
| for (var c = 0; c < _this.getModuleCount(); c += 1) { |
| qrHtml += '<td style="'; |
| qrHtml += ' border-width: 0px; border-style: none;'; |
| qrHtml += ' border-collapse: collapse;'; |
| qrHtml += ' padding: 0px; margin: 0px;'; |
| qrHtml += ' width: ' + cellSize + 'px;'; |
| qrHtml += ' height: ' + cellSize + 'px;'; |
| qrHtml += ' background-color: '; |
| qrHtml += _this.isDark(r, c)? '#000000' : '#ffffff'; |
| qrHtml += ';'; |
| qrHtml += '"/>'; |
| } |
| |
| qrHtml += '</tr>'; |
| } |
| |
| qrHtml += '</tbody>'; |
| qrHtml += '</table>'; |
| |
| return qrHtml; |
| }; |
| |
| _this.createSvgTag = function(cellSize, margin, alt, title) { |
| |
| var opts = {}; |
| if (typeof arguments[0] == 'object') { |
| |
| opts = arguments[0]; |
| |
| cellSize = opts.cellSize; |
| margin = opts.margin; |
| alt = opts.alt; |
| title = opts.title; |
| } |
| |
| cellSize = cellSize || 2; |
| margin = (typeof margin == 'undefined')? cellSize * 4 : margin; |
| |
| |
| alt = (typeof alt === 'string') ? {text: alt} : alt || {}; |
| alt.text = alt.text || null; |
| alt.id = (alt.text) ? alt.id || 'qrcode-description' : null; |
| |
| |
| title = (typeof title === 'string') ? {text: title} : title || {}; |
| title.text = title.text || null; |
| title.id = (title.text) ? title.id || 'qrcode-title' : null; |
| |
| var size = _this.getModuleCount() * cellSize + margin * 2; |
| var c, mc, r, mr, qrSvg='', rect; |
| |
| rect = 'l' + cellSize + ',0 0,' + cellSize + |
| ' -' + cellSize + ',0 0,-' + cellSize + 'z '; |
| |
| qrSvg += '<svg version="1.1" xmlns="http://www.w3.org/2000/svg"'; |
| qrSvg += !opts.scalable ? ' width="' + size + 'px" height="' + size + 'px"' : ''; |
| qrSvg += ' viewBox="0 0 ' + size + ' ' + size + '" '; |
| qrSvg += ' preserveAspectRatio="xMinYMin meet"'; |
| qrSvg += (title.text || alt.text) ? ' role="img" aria-labelledby="' + |
| escapeXml([title.id, alt.id].join(' ').trim() ) + '"' : ''; |
| qrSvg += '>'; |
| qrSvg += (title.text) ? '<title id="' + escapeXml(title.id) + '">' + |
| escapeXml(title.text) + '</title>' : ''; |
| qrSvg += (alt.text) ? '<description id="' + escapeXml(alt.id) + '">' + |
| escapeXml(alt.text) + '</description>' : ''; |
| qrSvg += '<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>'; |
| qrSvg += '<path d="'; |
| |
| for (r = 0; r < _this.getModuleCount(); r += 1) { |
| mr = r * cellSize + margin; |
| for (c = 0; c < _this.getModuleCount(); c += 1) { |
| if (_this.isDark(r, c) ) { |
| mc = c*cellSize+margin; |
| qrSvg += 'M' + mc + ',' + mr + rect; |
| } |
| } |
| } |
| |
| qrSvg += '" stroke="transparent" fill="black"/>'; |
| qrSvg += '</svg>'; |
| |
| return qrSvg; |
| }; |
| |
| _this.createDataURL = function(cellSize, margin) { |
| |
| cellSize = cellSize || 2; |
| margin = (typeof margin == 'undefined')? cellSize * 4 : margin; |
| |
| var size = _this.getModuleCount() * cellSize + margin * 2; |
| var min = margin; |
| var max = size - margin; |
| |
| return createDataURL(size, size, function(x, y) { |
| if (min <= x && x < max && min <= y && y < max) { |
| var c = Math.floor( (x - min) / cellSize); |
| var r = Math.floor( (y - min) / cellSize); |
| return _this.isDark(r, c)? 0 : 1; |
| } else { |
| return 1; |
| } |
| } ); |
| }; |
| |
| _this.createImgTag = function(cellSize, margin, alt) { |
| |
| cellSize = cellSize || 2; |
| margin = (typeof margin == 'undefined')? cellSize * 4 : margin; |
| |
| var size = _this.getModuleCount() * cellSize + margin * 2; |
| |
| var img = ''; |
| img += '<img'; |
| img += '\u0020src="'; |
| img += _this.createDataURL(cellSize, margin); |
| img += '"'; |
| img += '\u0020width="'; |
| img += size; |
| img += '"'; |
| img += '\u0020height="'; |
| img += size; |
| img += '"'; |
| if (alt) { |
| img += '\u0020alt="'; |
| img += escapeXml(alt); |
| img += '"'; |
| } |
| img += '/>'; |
| |
| return img; |
| }; |
| |
| var escapeXml = function(s) { |
| var escaped = ''; |
| for (var i = 0; i < s.length; i += 1) { |
| var c = s.charAt(i); |
| switch(c) { |
| case '<': escaped += '<'; break; |
| case '>': escaped += '>'; break; |
| case '&': escaped += '&'; break; |
| case '"': escaped += '"'; break; |
| default : escaped += c; break; |
| } |
| } |
| return escaped; |
| }; |
| |
| var _createHalfASCII = function(margin) { |
| var cellSize = 1; |
| margin = (typeof margin == 'undefined')? cellSize * 2 : margin; |
| |
| var size = _this.getModuleCount() * cellSize + margin * 2; |
| var min = margin; |
| var max = size - margin; |
| |
| var y, x, r1, r2, p; |
| |
| var blocks = { |
| '██': '█', |
| '█ ': '▀', |
| ' █': '▄', |
| ' ': ' ' |
| }; |
| |
| var blocksLastLineNoMargin = { |
| '██': '▀', |
| '█ ': '▀', |
| ' █': ' ', |
| ' ': ' ' |
| }; |
| |
| var ascii = ''; |
| for (y = 0; y < size; y += 2) { |
| r1 = Math.floor((y - min) / cellSize); |
| r2 = Math.floor((y + 1 - min) / cellSize); |
| for (x = 0; x < size; x += 1) { |
| p = '█'; |
| |
| if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) { |
| p = ' '; |
| } |
| |
| if (min <= x && x < max && min <= y+1 && y+1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) { |
| p += ' '; |
| } |
| else { |
| p += '█'; |
| } |
| |
| |
| ascii += (margin < 1 && y+1 >= max) ? blocksLastLineNoMargin[p] : blocks[p]; |
| } |
| |
| ascii += '\n'; |
| } |
| |
| if (size % 2 && margin > 0) { |
| return ascii.substring(0, ascii.length - size - 1) + Array(size+1).join('▀'); |
| } |
| |
| return ascii.substring(0, ascii.length-1); |
| }; |
| |
| _this.createASCII = function(cellSize, margin) { |
| cellSize = cellSize || 1; |
| |
| if (cellSize < 2) { |
| return _createHalfASCII(margin); |
| } |
| |
| cellSize -= 1; |
| margin = (typeof margin == 'undefined')? cellSize * 2 : margin; |
| |
| var size = _this.getModuleCount() * cellSize + margin * 2; |
| var min = margin; |
| var max = size - margin; |
| |
| var y, x, r, p; |
| |
| var white = Array(cellSize+1).join('██'); |
| var black = Array(cellSize+1).join(' '); |
| |
| var ascii = ''; |
| var line = ''; |
| for (y = 0; y < size; y += 1) { |
| r = Math.floor( (y - min) / cellSize); |
| line = ''; |
| for (x = 0; x < size; x += 1) { |
| p = 1; |
| |
| if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) { |
| p = 0; |
| } |
| |
| |
| line += p ? white : black; |
| } |
| |
| for (r = 0; r < cellSize; r += 1) { |
| ascii += line + '\n'; |
| } |
| } |
| |
| return ascii.substring(0, ascii.length-1); |
| }; |
| |
| _this.renderTo2dContext = function(context, cellSize) { |
| cellSize = cellSize || 2; |
| var length = _this.getModuleCount(); |
| for (var row = 0; row < length; row++) { |
| for (var col = 0; col < length; col++) { |
| context.fillStyle = _this.isDark(row, col) ? 'black' : 'white'; |
| context.fillRect(col * cellSize, row * cellSize, cellSize, cellSize); |
| } |
| } |
| } |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| qrcode.stringToBytesFuncs = { |
| 'default' : function(s) { |
| var bytes = []; |
| for (var i = 0; i < s.length; i += 1) { |
| var c = s.charCodeAt(i); |
| bytes.push(c & 0xff); |
| } |
| return bytes; |
| } |
| }; |
| |
| qrcode.stringToBytes = qrcode.stringToBytesFuncs['default']; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| qrcode.createStringToBytes = function(unicodeData, numChars) { |
| |
| |
| |
| var unicodeMap = function() { |
| |
| var bin = base64DecodeInputStream(unicodeData); |
| var read = function() { |
| var b = bin.read(); |
| if (b == -1) throw 'eof'; |
| return b; |
| }; |
| |
| var count = 0; |
| var unicodeMap = {}; |
| while (true) { |
| var b0 = bin.read(); |
| if (b0 == -1) break; |
| var b1 = read(); |
| var b2 = read(); |
| var b3 = read(); |
| var k = String.fromCharCode( (b0 << 8) | b1); |
| var v = (b2 << 8) | b3; |
| unicodeMap[k] = v; |
| count += 1; |
| } |
| if (count != numChars) { |
| throw count + ' != ' + numChars; |
| } |
| |
| return unicodeMap; |
| }(); |
| |
| var unknownChar = '?'.charCodeAt(0); |
| |
| return function(s) { |
| var bytes = []; |
| for (var i = 0; i < s.length; i += 1) { |
| var c = s.charCodeAt(i); |
| if (c < 128) { |
| bytes.push(c); |
| } else { |
| var b = unicodeMap[s.charAt(i)]; |
| if (typeof b == 'number') { |
| if ( (b & 0xff) == b) { |
| |
| bytes.push(b); |
| } else { |
| |
| bytes.push(b >>> 8); |
| bytes.push(b & 0xff); |
| } |
| } else { |
| bytes.push(unknownChar); |
| } |
| } |
| } |
| return bytes; |
| }; |
| }; |
| |
| |
| |
| |
| |
| var QRMode = { |
| MODE_NUMBER : 1 << 0, |
| MODE_ALPHA_NUM : 1 << 1, |
| MODE_8BIT_BYTE : 1 << 2, |
| MODE_KANJI : 1 << 3 |
| }; |
| |
| |
| |
| |
| |
| var QRErrorCorrectionLevel = { |
| L : 1, |
| M : 0, |
| Q : 3, |
| H : 2 |
| }; |
| |
| |
| |
| |
| |
| var QRMaskPattern = { |
| PATTERN000 : 0, |
| PATTERN001 : 1, |
| PATTERN010 : 2, |
| PATTERN011 : 3, |
| PATTERN100 : 4, |
| PATTERN101 : 5, |
| PATTERN110 : 6, |
| PATTERN111 : 7 |
| }; |
| |
| |
| |
| |
| |
| var QRUtil = function() { |
| |
| var PATTERN_POSITION_TABLE = [ |
| [], |
| [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] |
| ]; |
| var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0); |
| var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0); |
| var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); |
| |
| var _this = {}; |
| |
| var getBCHDigit = function(data) { |
| var digit = 0; |
| while (data != 0) { |
| digit += 1; |
| data >>>= 1; |
| } |
| return digit; |
| }; |
| |
| _this.getBCHTypeInfo = function(data) { |
| var d = data << 10; |
| while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { |
| d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) ); |
| } |
| return ( (data << 10) | d) ^ G15_MASK; |
| }; |
| |
| _this.getBCHTypeNumber = function(data) { |
| var d = data << 12; |
| while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { |
| d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) ); |
| } |
| return (data << 12) | d; |
| }; |
| |
| _this.getPatternPosition = function(typeNumber) { |
| return PATTERN_POSITION_TABLE[typeNumber - 1]; |
| }; |
| |
| _this.getMaskFunction = function(maskPattern) { |
| |
| switch (maskPattern) { |
| |
| case QRMaskPattern.PATTERN000 : |
| return function(i, j) { return (i + j) % 2 == 0; }; |
| case QRMaskPattern.PATTERN001 : |
| return function(i, j) { return i % 2 == 0; }; |
| case QRMaskPattern.PATTERN010 : |
| return function(i, j) { return j % 3 == 0; }; |
| case QRMaskPattern.PATTERN011 : |
| return function(i, j) { return (i + j) % 3 == 0; }; |
| case QRMaskPattern.PATTERN100 : |
| return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; }; |
| case QRMaskPattern.PATTERN101 : |
| return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; }; |
| case QRMaskPattern.PATTERN110 : |
| return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; }; |
| case QRMaskPattern.PATTERN111 : |
| return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; }; |
| |
| default : |
| throw 'bad maskPattern:' + maskPattern; |
| } |
| }; |
| |
| _this.getErrorCorrectPolynomial = function(errorCorrectLength) { |
| var a = qrPolynomial([1], 0); |
| for (var i = 0; i < errorCorrectLength; i += 1) { |
| a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) ); |
| } |
| return a; |
| }; |
| |
| _this.getLengthInBits = function(mode, type) { |
| |
| if (1 <= type && type < 10) { |
| |
| |
| |
| switch(mode) { |
| case QRMode.MODE_NUMBER : return 10; |
| case QRMode.MODE_ALPHA_NUM : return 9; |
| case QRMode.MODE_8BIT_BYTE : return 8; |
| case QRMode.MODE_KANJI : return 8; |
| default : |
| throw 'mode:' + mode; |
| } |
| |
| } else if (type < 27) { |
| |
| |
| |
| switch(mode) { |
| case QRMode.MODE_NUMBER : return 12; |
| case QRMode.MODE_ALPHA_NUM : return 11; |
| case QRMode.MODE_8BIT_BYTE : return 16; |
| case QRMode.MODE_KANJI : return 10; |
| default : |
| throw 'mode:' + mode; |
| } |
| |
| } else if (type < 41) { |
| |
| |
| |
| switch(mode) { |
| case QRMode.MODE_NUMBER : return 14; |
| case QRMode.MODE_ALPHA_NUM : return 13; |
| case QRMode.MODE_8BIT_BYTE : return 16; |
| case QRMode.MODE_KANJI : return 12; |
| default : |
| throw 'mode:' + mode; |
| } |
| |
| } else { |
| throw 'type:' + type; |
| } |
| }; |
| |
| _this.getLostPoint = function(qrcode) { |
| |
| var moduleCount = qrcode.getModuleCount(); |
| |
| var lostPoint = 0; |
| |
| |
| |
| for (var row = 0; row < moduleCount; row += 1) { |
| for (var col = 0; col < moduleCount; col += 1) { |
| |
| var sameCount = 0; |
| var dark = qrcode.isDark(row, col); |
| |
| for (var r = -1; r <= 1; r += 1) { |
| |
| if (row + r < 0 || moduleCount <= row + r) { |
| continue; |
| } |
| |
| for (var c = -1; c <= 1; c += 1) { |
| |
| if (col + c < 0 || moduleCount <= col + c) { |
| continue; |
| } |
| |
| if (r == 0 && c == 0) { |
| continue; |
| } |
| |
| if (dark == qrcode.isDark(row + r, col + c) ) { |
| sameCount += 1; |
| } |
| } |
| } |
| |
| if (sameCount > 5) { |
| lostPoint += (3 + sameCount - 5); |
| } |
| } |
| }; |
| |
| |
| |
| for (var row = 0; row < moduleCount - 1; row += 1) { |
| for (var col = 0; col < moduleCount - 1; col += 1) { |
| var count = 0; |
| if (qrcode.isDark(row, col) ) count += 1; |
| if (qrcode.isDark(row + 1, col) ) count += 1; |
| if (qrcode.isDark(row, col + 1) ) count += 1; |
| if (qrcode.isDark(row + 1, col + 1) ) count += 1; |
| if (count == 0 || count == 4) { |
| lostPoint += 3; |
| } |
| } |
| } |
| |
| |
| |
| for (var row = 0; row < moduleCount; row += 1) { |
| for (var col = 0; col < moduleCount - 6; col += 1) { |
| if (qrcode.isDark(row, col) |
| && !qrcode.isDark(row, col + 1) |
| && qrcode.isDark(row, col + 2) |
| && qrcode.isDark(row, col + 3) |
| && qrcode.isDark(row, col + 4) |
| && !qrcode.isDark(row, col + 5) |
| && qrcode.isDark(row, col + 6) ) { |
| lostPoint += 40; |
| } |
| } |
| } |
| |
| for (var col = 0; col < moduleCount; col += 1) { |
| for (var row = 0; row < moduleCount - 6; row += 1) { |
| if (qrcode.isDark(row, col) |
| && !qrcode.isDark(row + 1, col) |
| && qrcode.isDark(row + 2, col) |
| && qrcode.isDark(row + 3, col) |
| && qrcode.isDark(row + 4, col) |
| && !qrcode.isDark(row + 5, col) |
| && qrcode.isDark(row + 6, col) ) { |
| lostPoint += 40; |
| } |
| } |
| } |
| |
| |
| |
| var darkCount = 0; |
| |
| for (var col = 0; col < moduleCount; col += 1) { |
| for (var row = 0; row < moduleCount; row += 1) { |
| if (qrcode.isDark(row, col) ) { |
| darkCount += 1; |
| } |
| } |
| } |
| |
| var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; |
| lostPoint += ratio * 10; |
| |
| return lostPoint; |
| }; |
| |
| return _this; |
| }(); |
| |
| |
| |
| |
| |
| var QRMath = function() { |
| |
| var EXP_TABLE = new Array(256); |
| var LOG_TABLE = new Array(256); |
| |
| |
| for (var i = 0; i < 8; i += 1) { |
| EXP_TABLE[i] = 1 << i; |
| } |
| for (var i = 8; i < 256; i += 1) { |
| EXP_TABLE[i] = EXP_TABLE[i - 4] |
| ^ EXP_TABLE[i - 5] |
| ^ EXP_TABLE[i - 6] |
| ^ EXP_TABLE[i - 8]; |
| } |
| for (var i = 0; i < 255; i += 1) { |
| LOG_TABLE[EXP_TABLE[i] ] = i; |
| } |
| |
| var _this = {}; |
| |
| _this.glog = function(n) { |
| |
| if (n < 1) { |
| throw 'glog(' + n + ')'; |
| } |
| |
| return LOG_TABLE[n]; |
| }; |
| |
| _this.gexp = function(n) { |
| |
| while (n < 0) { |
| n += 255; |
| } |
| |
| while (n >= 256) { |
| n -= 255; |
| } |
| |
| return EXP_TABLE[n]; |
| }; |
| |
| return _this; |
| }(); |
| |
| |
| |
| |
| |
| function qrPolynomial(num, shift) { |
| |
| if (typeof num.length == 'undefined') { |
| throw num.length + '/' + shift; |
| } |
| |
| var _num = function() { |
| var offset = 0; |
| while (offset < num.length && num[offset] == 0) { |
| offset += 1; |
| } |
| var _num = new Array(num.length - offset + shift); |
| for (var i = 0; i < num.length - offset; i += 1) { |
| _num[i] = num[i + offset]; |
| } |
| return _num; |
| }(); |
| |
| var _this = {}; |
| |
| _this.getAt = function(index) { |
| return _num[index]; |
| }; |
| |
| _this.getLength = function() { |
| return _num.length; |
| }; |
| |
| _this.multiply = function(e) { |
| |
| var num = new Array(_this.getLength() + e.getLength() - 1); |
| |
| for (var i = 0; i < _this.getLength(); i += 1) { |
| for (var j = 0; j < e.getLength(); j += 1) { |
| num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) ); |
| } |
| } |
| |
| return qrPolynomial(num, 0); |
| }; |
| |
| _this.mod = function(e) { |
| |
| if (_this.getLength() - e.getLength() < 0) { |
| return _this; |
| } |
| |
| var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) ); |
| |
| var num = new Array(_this.getLength() ); |
| for (var i = 0; i < _this.getLength(); i += 1) { |
| num[i] = _this.getAt(i); |
| } |
| |
| for (var i = 0; i < e.getLength(); i += 1) { |
| num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio); |
| } |
| |
| |
| return qrPolynomial(num, 0).mod(e); |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var QRRSBlock = function() { |
| |
| var RS_BLOCK_TABLE = [ |
| |
| |
| |
| |
| |
| |
| |
| [1, 26, 19], |
| [1, 26, 16], |
| [1, 26, 13], |
| [1, 26, 9], |
| |
| |
| [1, 44, 34], |
| [1, 44, 28], |
| [1, 44, 22], |
| [1, 44, 16], |
| |
| |
| [1, 70, 55], |
| [1, 70, 44], |
| [2, 35, 17], |
| [2, 35, 13], |
| |
| |
| [1, 100, 80], |
| [2, 50, 32], |
| [2, 50, 24], |
| [4, 25, 9], |
| |
| |
| [1, 134, 108], |
| [2, 67, 43], |
| [2, 33, 15, 2, 34, 16], |
| [2, 33, 11, 2, 34, 12], |
| |
| |
| [2, 86, 68], |
| [4, 43, 27], |
| [4, 43, 19], |
| [4, 43, 15], |
| |
| |
| [2, 98, 78], |
| [4, 49, 31], |
| [2, 32, 14, 4, 33, 15], |
| [4, 39, 13, 1, 40, 14], |
| |
| |
| [2, 121, 97], |
| [2, 60, 38, 2, 61, 39], |
| [4, 40, 18, 2, 41, 19], |
| [4, 40, 14, 2, 41, 15], |
| |
| |
| [2, 146, 116], |
| [3, 58, 36, 2, 59, 37], |
| [4, 36, 16, 4, 37, 17], |
| [4, 36, 12, 4, 37, 13], |
| |
| |
| [2, 86, 68, 2, 87, 69], |
| [4, 69, 43, 1, 70, 44], |
| [6, 43, 19, 2, 44, 20], |
| [6, 43, 15, 2, 44, 16], |
| |
| |
| [4, 101, 81], |
| [1, 80, 50, 4, 81, 51], |
| [4, 50, 22, 4, 51, 23], |
| [3, 36, 12, 8, 37, 13], |
| |
| |
| [2, 116, 92, 2, 117, 93], |
| [6, 58, 36, 2, 59, 37], |
| [4, 46, 20, 6, 47, 21], |
| [7, 42, 14, 4, 43, 15], |
| |
| |
| [4, 133, 107], |
| [8, 59, 37, 1, 60, 38], |
| [8, 44, 20, 4, 45, 21], |
| [12, 33, 11, 4, 34, 12], |
| |
| |
| [3, 145, 115, 1, 146, 116], |
| [4, 64, 40, 5, 65, 41], |
| [11, 36, 16, 5, 37, 17], |
| [11, 36, 12, 5, 37, 13], |
| |
| |
| [5, 109, 87, 1, 110, 88], |
| [5, 65, 41, 5, 66, 42], |
| [5, 54, 24, 7, 55, 25], |
| [11, 36, 12, 7, 37, 13], |
| |
| |
| [5, 122, 98, 1, 123, 99], |
| [7, 73, 45, 3, 74, 46], |
| [15, 43, 19, 2, 44, 20], |
| [3, 45, 15, 13, 46, 16], |
| |
| |
| [1, 135, 107, 5, 136, 108], |
| [10, 74, 46, 1, 75, 47], |
| [1, 50, 22, 15, 51, 23], |
| [2, 42, 14, 17, 43, 15], |
| |
| |
| [5, 150, 120, 1, 151, 121], |
| [9, 69, 43, 4, 70, 44], |
| [17, 50, 22, 1, 51, 23], |
| [2, 42, 14, 19, 43, 15], |
| |
| |
| [3, 141, 113, 4, 142, 114], |
| [3, 70, 44, 11, 71, 45], |
| [17, 47, 21, 4, 48, 22], |
| [9, 39, 13, 16, 40, 14], |
| |
| |
| [3, 135, 107, 5, 136, 108], |
| [3, 67, 41, 13, 68, 42], |
| [15, 54, 24, 5, 55, 25], |
| [15, 43, 15, 10, 44, 16], |
| |
| |
| [4, 144, 116, 4, 145, 117], |
| [17, 68, 42], |
| [17, 50, 22, 6, 51, 23], |
| [19, 46, 16, 6, 47, 17], |
| |
| |
| [2, 139, 111, 7, 140, 112], |
| [17, 74, 46], |
| [7, 54, 24, 16, 55, 25], |
| [34, 37, 13], |
| |
| |
| [4, 151, 121, 5, 152, 122], |
| [4, 75, 47, 14, 76, 48], |
| [11, 54, 24, 14, 55, 25], |
| [16, 45, 15, 14, 46, 16], |
| |
| |
| [6, 147, 117, 4, 148, 118], |
| [6, 73, 45, 14, 74, 46], |
| [11, 54, 24, 16, 55, 25], |
| [30, 46, 16, 2, 47, 17], |
| |
| |
| [8, 132, 106, 4, 133, 107], |
| [8, 75, 47, 13, 76, 48], |
| [7, 54, 24, 22, 55, 25], |
| [22, 45, 15, 13, 46, 16], |
| |
| |
| [10, 142, 114, 2, 143, 115], |
| [19, 74, 46, 4, 75, 47], |
| [28, 50, 22, 6, 51, 23], |
| [33, 46, 16, 4, 47, 17], |
| |
| |
| [8, 152, 122, 4, 153, 123], |
| [22, 73, 45, 3, 74, 46], |
| [8, 53, 23, 26, 54, 24], |
| [12, 45, 15, 28, 46, 16], |
| |
| |
| [3, 147, 117, 10, 148, 118], |
| [3, 73, 45, 23, 74, 46], |
| [4, 54, 24, 31, 55, 25], |
| [11, 45, 15, 31, 46, 16], |
| |
| |
| [7, 146, 116, 7, 147, 117], |
| [21, 73, 45, 7, 74, 46], |
| [1, 53, 23, 37, 54, 24], |
| [19, 45, 15, 26, 46, 16], |
| |
| |
| [5, 145, 115, 10, 146, 116], |
| [19, 75, 47, 10, 76, 48], |
| [15, 54, 24, 25, 55, 25], |
| [23, 45, 15, 25, 46, 16], |
| |
| |
| [13, 145, 115, 3, 146, 116], |
| [2, 74, 46, 29, 75, 47], |
| [42, 54, 24, 1, 55, 25], |
| [23, 45, 15, 28, 46, 16], |
| |
| |
| [17, 145, 115], |
| [10, 74, 46, 23, 75, 47], |
| [10, 54, 24, 35, 55, 25], |
| [19, 45, 15, 35, 46, 16], |
| |
| |
| [17, 145, 115, 1, 146, 116], |
| [14, 74, 46, 21, 75, 47], |
| [29, 54, 24, 19, 55, 25], |
| [11, 45, 15, 46, 46, 16], |
| |
| |
| [13, 145, 115, 6, 146, 116], |
| [14, 74, 46, 23, 75, 47], |
| [44, 54, 24, 7, 55, 25], |
| [59, 46, 16, 1, 47, 17], |
| |
| |
| [12, 151, 121, 7, 152, 122], |
| [12, 75, 47, 26, 76, 48], |
| [39, 54, 24, 14, 55, 25], |
| [22, 45, 15, 41, 46, 16], |
| |
| |
| [6, 151, 121, 14, 152, 122], |
| [6, 75, 47, 34, 76, 48], |
| [46, 54, 24, 10, 55, 25], |
| [2, 45, 15, 64, 46, 16], |
| |
| |
| [17, 152, 122, 4, 153, 123], |
| [29, 74, 46, 14, 75, 47], |
| [49, 54, 24, 10, 55, 25], |
| [24, 45, 15, 46, 46, 16], |
| |
| |
| [4, 152, 122, 18, 153, 123], |
| [13, 74, 46, 32, 75, 47], |
| [48, 54, 24, 14, 55, 25], |
| [42, 45, 15, 32, 46, 16], |
| |
| |
| [20, 147, 117, 4, 148, 118], |
| [40, 75, 47, 7, 76, 48], |
| [43, 54, 24, 22, 55, 25], |
| [10, 45, 15, 67, 46, 16], |
| |
| |
| [19, 148, 118, 6, 149, 119], |
| [18, 75, 47, 31, 76, 48], |
| [34, 54, 24, 34, 55, 25], |
| [20, 45, 15, 61, 46, 16] |
| ]; |
| |
| var qrRSBlock = function(totalCount, dataCount) { |
| var _this = {}; |
| _this.totalCount = totalCount; |
| _this.dataCount = dataCount; |
| return _this; |
| }; |
| |
| var _this = {}; |
| |
| var getRsBlockTable = function(typeNumber, errorCorrectionLevel) { |
| |
| switch(errorCorrectionLevel) { |
| case QRErrorCorrectionLevel.L : |
| return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; |
| case QRErrorCorrectionLevel.M : |
| return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; |
| case QRErrorCorrectionLevel.Q : |
| return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; |
| case QRErrorCorrectionLevel.H : |
| return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; |
| default : |
| return undefined; |
| } |
| }; |
| |
| _this.getRSBlocks = function(typeNumber, errorCorrectionLevel) { |
| |
| var rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel); |
| |
| if (typeof rsBlock == 'undefined') { |
| throw 'bad rs block @ typeNumber:' + typeNumber + |
| '/errorCorrectionLevel:' + errorCorrectionLevel; |
| } |
| |
| var length = rsBlock.length / 3; |
| |
| var list = []; |
| |
| for (var i = 0; i < length; i += 1) { |
| |
| var count = rsBlock[i * 3 + 0]; |
| var totalCount = rsBlock[i * 3 + 1]; |
| var dataCount = rsBlock[i * 3 + 2]; |
| |
| for (var j = 0; j < count; j += 1) { |
| list.push(qrRSBlock(totalCount, dataCount) ); |
| } |
| } |
| |
| return list; |
| }; |
| |
| return _this; |
| }(); |
| |
| |
| |
| |
| |
| var qrBitBuffer = function() { |
| |
| var _buffer = []; |
| var _length = 0; |
| |
| var _this = {}; |
| |
| _this.getBuffer = function() { |
| return _buffer; |
| }; |
| |
| _this.getAt = function(index) { |
| var bufIndex = Math.floor(index / 8); |
| return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; |
| }; |
| |
| _this.put = function(num, length) { |
| for (var i = 0; i < length; i += 1) { |
| _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); |
| } |
| }; |
| |
| _this.getLengthInBits = function() { |
| return _length; |
| }; |
| |
| _this.putBit = function(bit) { |
| |
| var bufIndex = Math.floor(_length / 8); |
| if (_buffer.length <= bufIndex) { |
| _buffer.push(0); |
| } |
| |
| if (bit) { |
| _buffer[bufIndex] |= (0x80 >>> (_length % 8) ); |
| } |
| |
| _length += 1; |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var qrNumber = function(data) { |
| |
| var _mode = QRMode.MODE_NUMBER; |
| var _data = data; |
| |
| var _this = {}; |
| |
| _this.getMode = function() { |
| return _mode; |
| }; |
| |
| _this.getLength = function(buffer) { |
| return _data.length; |
| }; |
| |
| _this.write = function(buffer) { |
| |
| var data = _data; |
| |
| var i = 0; |
| |
| while (i + 2 < data.length) { |
| buffer.put(strToNum(data.substring(i, i + 3) ), 10); |
| i += 3; |
| } |
| |
| if (i < data.length) { |
| if (data.length - i == 1) { |
| buffer.put(strToNum(data.substring(i, i + 1) ), 4); |
| } else if (data.length - i == 2) { |
| buffer.put(strToNum(data.substring(i, i + 2) ), 7); |
| } |
| } |
| }; |
| |
| var strToNum = function(s) { |
| var num = 0; |
| for (var i = 0; i < s.length; i += 1) { |
| num = num * 10 + chatToNum(s.charAt(i) ); |
| } |
| return num; |
| }; |
| |
| var chatToNum = function(c) { |
| if ('0' <= c && c <= '9') { |
| return c.charCodeAt(0) - '0'.charCodeAt(0); |
| } |
| throw 'illegal char :' + c; |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var qrAlphaNum = function(data) { |
| |
| var _mode = QRMode.MODE_ALPHA_NUM; |
| var _data = data; |
| |
| var _this = {}; |
| |
| _this.getMode = function() { |
| return _mode; |
| }; |
| |
| _this.getLength = function(buffer) { |
| return _data.length; |
| }; |
| |
| _this.write = function(buffer) { |
| |
| var s = _data; |
| |
| var i = 0; |
| |
| while (i + 1 < s.length) { |
| buffer.put( |
| getCode(s.charAt(i) ) * 45 + |
| getCode(s.charAt(i + 1) ), 11); |
| i += 2; |
| } |
| |
| if (i < s.length) { |
| buffer.put(getCode(s.charAt(i) ), 6); |
| } |
| }; |
| |
| var getCode = function(c) { |
| |
| if ('0' <= c && c <= '9') { |
| return c.charCodeAt(0) - '0'.charCodeAt(0); |
| } else if ('A' <= c && c <= 'Z') { |
| return c.charCodeAt(0) - 'A'.charCodeAt(0) + 10; |
| } else { |
| switch (c) { |
| case ' ' : return 36; |
| case '$' : return 37; |
| case '%' : return 38; |
| case '*' : return 39; |
| case '+' : return 40; |
| case '-' : return 41; |
| case '.' : return 42; |
| case '/' : return 43; |
| case ':' : return 44; |
| default : |
| throw 'illegal char :' + c; |
| } |
| } |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var qr8BitByte = function(data) { |
| |
| var _mode = QRMode.MODE_8BIT_BYTE; |
| var _data = data; |
| var _bytes = qrcode.stringToBytes(data); |
| |
| var _this = {}; |
| |
| _this.getMode = function() { |
| return _mode; |
| }; |
| |
| _this.getLength = function(buffer) { |
| return _bytes.length; |
| }; |
| |
| _this.write = function(buffer) { |
| for (var i = 0; i < _bytes.length; i += 1) { |
| buffer.put(_bytes[i], 8); |
| } |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var qrKanji = function(data) { |
| |
| var _mode = QRMode.MODE_KANJI; |
| var _data = data; |
| |
| var stringToBytes = qrcode.stringToBytesFuncs['SJIS']; |
| if (!stringToBytes) { |
| throw 'sjis not supported.'; |
| } |
| !function(c, code) { |
| |
| var test = stringToBytes(c); |
| if (test.length != 2 || ( (test[0] << 8) | test[1]) != code) { |
| throw 'sjis not supported.'; |
| } |
| }('\u53cb', 0x9746); |
| |
| var _bytes = stringToBytes(data); |
| |
| var _this = {}; |
| |
| _this.getMode = function() { |
| return _mode; |
| }; |
| |
| _this.getLength = function(buffer) { |
| return ~~(_bytes.length / 2); |
| }; |
| |
| _this.write = function(buffer) { |
| |
| var data = _bytes; |
| |
| var i = 0; |
| |
| while (i + 1 < data.length) { |
| |
| var c = ( (0xff & data[i]) << 8) | (0xff & data[i + 1]); |
| |
| if (0x8140 <= c && c <= 0x9FFC) { |
| c -= 0x8140; |
| } else if (0xE040 <= c && c <= 0xEBBF) { |
| c -= 0xC140; |
| } else { |
| throw 'illegal char at ' + (i + 1) + '/' + c; |
| } |
| |
| c = ( (c >>> 8) & 0xff) * 0xC0 + (c & 0xff); |
| |
| buffer.put(c, 13); |
| |
| i += 2; |
| } |
| |
| if (i < data.length) { |
| throw 'illegal char at ' + (i + 1); |
| } |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| var byteArrayOutputStream = function() { |
| |
| var _bytes = []; |
| |
| var _this = {}; |
| |
| _this.writeByte = function(b) { |
| _bytes.push(b & 0xff); |
| }; |
| |
| _this.writeShort = function(i) { |
| _this.writeByte(i); |
| _this.writeByte(i >>> 8); |
| }; |
| |
| _this.writeBytes = function(b, off, len) { |
| off = off || 0; |
| len = len || b.length; |
| for (var i = 0; i < len; i += 1) { |
| _this.writeByte(b[i + off]); |
| } |
| }; |
| |
| _this.writeString = function(s) { |
| for (var i = 0; i < s.length; i += 1) { |
| _this.writeByte(s.charCodeAt(i) ); |
| } |
| }; |
| |
| _this.toByteArray = function() { |
| return _bytes; |
| }; |
| |
| _this.toString = function() { |
| var s = ''; |
| s += '['; |
| for (var i = 0; i < _bytes.length; i += 1) { |
| if (i > 0) { |
| s += ','; |
| } |
| s += _bytes[i]; |
| } |
| s += ']'; |
| return s; |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var base64EncodeOutputStream = function() { |
| |
| var _buffer = 0; |
| var _buflen = 0; |
| var _length = 0; |
| var _base64 = ''; |
| |
| var _this = {}; |
| |
| var writeEncoded = function(b) { |
| _base64 += String.fromCharCode(encode(b & 0x3f) ); |
| }; |
| |
| var encode = function(n) { |
| if (n < 0) { |
| |
| } else if (n < 26) { |
| return 0x41 + n; |
| } else if (n < 52) { |
| return 0x61 + (n - 26); |
| } else if (n < 62) { |
| return 0x30 + (n - 52); |
| } else if (n == 62) { |
| return 0x2b; |
| } else if (n == 63) { |
| return 0x2f; |
| } |
| throw 'n:' + n; |
| }; |
| |
| _this.writeByte = function(n) { |
| |
| _buffer = (_buffer << 8) | (n & 0xff); |
| _buflen += 8; |
| _length += 1; |
| |
| while (_buflen >= 6) { |
| writeEncoded(_buffer >>> (_buflen - 6) ); |
| _buflen -= 6; |
| } |
| }; |
| |
| _this.flush = function() { |
| |
| if (_buflen > 0) { |
| writeEncoded(_buffer << (6 - _buflen) ); |
| _buffer = 0; |
| _buflen = 0; |
| } |
| |
| if (_length % 3 != 0) { |
| |
| var padlen = 3 - _length % 3; |
| for (var i = 0; i < padlen; i += 1) { |
| _base64 += '='; |
| } |
| } |
| }; |
| |
| _this.toString = function() { |
| return _base64; |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var base64DecodeInputStream = function(str) { |
| |
| var _str = str; |
| var _pos = 0; |
| var _buffer = 0; |
| var _buflen = 0; |
| |
| var _this = {}; |
| |
| _this.read = function() { |
| |
| while (_buflen < 8) { |
| |
| if (_pos >= _str.length) { |
| if (_buflen == 0) { |
| return -1; |
| } |
| throw 'unexpected end of file./' + _buflen; |
| } |
| |
| var c = _str.charAt(_pos); |
| _pos += 1; |
| |
| if (c == '=') { |
| _buflen = 0; |
| return -1; |
| } else if (c.match(/^\s$/) ) { |
| |
| continue; |
| } |
| |
| _buffer = (_buffer << 6) | decode(c.charCodeAt(0) ); |
| _buflen += 6; |
| } |
| |
| var n = (_buffer >>> (_buflen - 8) ) & 0xff; |
| _buflen -= 8; |
| return n; |
| }; |
| |
| var decode = function(c) { |
| if (0x41 <= c && c <= 0x5a) { |
| return c - 0x41; |
| } else if (0x61 <= c && c <= 0x7a) { |
| return c - 0x61 + 26; |
| } else if (0x30 <= c && c <= 0x39) { |
| return c - 0x30 + 52; |
| } else if (c == 0x2b) { |
| return 62; |
| } else if (c == 0x2f) { |
| return 63; |
| } else { |
| throw 'c:' + c; |
| } |
| }; |
| |
| return _this; |
| }; |
| |
| |
| |
| |
| |
| var gifImage = function(width, height) { |
| |
| var _width = width; |
| var _height = height; |
| var _data = new Array(width * height); |
| |
| var _this = {}; |
| |
| _this.setPixel = function(x, y, pixel) { |
| _data[y * _width + x] = pixel; |
| }; |
| |
| _this.write = function(out) { |
| |
| |
| |
| |
| out.writeString('GIF87a'); |
| |
| |
| |
| |
| out.writeShort(_width); |
| out.writeShort(_height); |
| |
| out.writeByte(0x80); |
| out.writeByte(0); |
| out.writeByte(0); |
| |
| |
| |
| |
| |
| out.writeByte(0x00); |
| out.writeByte(0x00); |
| out.writeByte(0x00); |
| |
| |
| out.writeByte(0xff); |
| out.writeByte(0xff); |
| out.writeByte(0xff); |
| |
| |
| |
| |
| out.writeString(','); |
| out.writeShort(0); |
| out.writeShort(0); |
| out.writeShort(_width); |
| out.writeShort(_height); |
| out.writeByte(0); |
| |
| |
| |
| |
| |
| |
| |
| var lzwMinCodeSize = 2; |
| var raster = getLZWRaster(lzwMinCodeSize); |
| |
| out.writeByte(lzwMinCodeSize); |
| |
| var offset = 0; |
| |
| while (raster.length - offset > 255) { |
| out.writeByte(255); |
| out.writeBytes(raster, offset, 255); |
| offset += 255; |
| } |
| |
| out.writeByte(raster.length - offset); |
| out.writeBytes(raster, offset, raster.length - offset); |
| out.writeByte(0x00); |
| |
| |
| |
| out.writeString(';'); |
| }; |
| |
| var bitOutputStream = function(out) { |
| |
| var _out = out; |
| var _bitLength = 0; |
| var _bitBuffer = 0; |
| |
| var _this = {}; |
| |
| _this.write = function(data, length) { |
| |
| if ( (data >>> length) != 0) { |
| throw 'length over'; |
| } |
| |
| while (_bitLength + length >= 8) { |
| _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); |
| length -= (8 - _bitLength); |
| data >>>= (8 - _bitLength); |
| _bitBuffer = 0; |
| _bitLength = 0; |
| } |
| |
| _bitBuffer = (data << _bitLength) | _bitBuffer; |
| _bitLength = _bitLength + length; |
| }; |
| |
| _this.flush = function() { |
| if (_bitLength > 0) { |
| _out.writeByte(_bitBuffer); |
| } |
| }; |
| |
| return _this; |
| }; |
| |
| var getLZWRaster = function(lzwMinCodeSize) { |
| |
| var clearCode = 1 << lzwMinCodeSize; |
| var endCode = (1 << lzwMinCodeSize) + 1; |
| var bitLength = lzwMinCodeSize + 1; |
| |
| |
| var table = lzwTable(); |
| |
| for (var i = 0; i < clearCode; i += 1) { |
| table.add(String.fromCharCode(i) ); |
| } |
| table.add(String.fromCharCode(clearCode) ); |
| table.add(String.fromCharCode(endCode) ); |
| |
| var byteOut = byteArrayOutputStream(); |
| var bitOut = bitOutputStream(byteOut); |
| |
| |
| bitOut.write(clearCode, bitLength); |
| |
| var dataIndex = 0; |
| |
| var s = String.fromCharCode(_data[dataIndex]); |
| dataIndex += 1; |
| |
| while (dataIndex < _data.length) { |
| |
| var c = String.fromCharCode(_data[dataIndex]); |
| dataIndex += 1; |
| |
| if (table.contains(s + c) ) { |
| |
| s = s + c; |
| |
| } else { |
| |
| bitOut.write(table.indexOf(s), bitLength); |
| |
| if (table.size() < 0xfff) { |
| |
| if (table.size() == (1 << bitLength) ) { |
| bitLength += 1; |
| } |
| |
| table.add(s + c); |
| } |
| |
| s = c; |
| } |
| } |
| |
| bitOut.write(table.indexOf(s), bitLength); |
| |
| |
| bitOut.write(endCode, bitLength); |
| |
| bitOut.flush(); |
| |
| return byteOut.toByteArray(); |
| }; |
| |
| var lzwTable = function() { |
| |
| var _map = {}; |
| var _size = 0; |
| |
| var _this = {}; |
| |
| _this.add = function(key) { |
| if (_this.contains(key) ) { |
| throw 'dup key:' + key; |
| } |
| _map[key] = _size; |
| _size += 1; |
| }; |
| |
| _this.size = function() { |
| return _size; |
| }; |
| |
| _this.indexOf = function(key) { |
| return _map[key]; |
| }; |
| |
| _this.contains = function(key) { |
| return typeof _map[key] != 'undefined'; |
| }; |
| |
| return _this; |
| }; |
| |
| return _this; |
| }; |
| |
| var createDataURL = function(width, height, getPixel) { |
| var gif = gifImage(width, height); |
| for (var y = 0; y < height; y += 1) { |
| for (var x = 0; x < width; x += 1) { |
| gif.setPixel(x, y, getPixel(x, y) ); |
| } |
| } |
| |
| var b = byteArrayOutputStream(); |
| gif.write(b); |
| |
| var base64 = base64EncodeOutputStream(); |
| var bytes = b.toByteArray(); |
| for (var i = 0; i < bytes.length; i += 1) { |
| base64.writeByte(bytes[i]); |
| } |
| base64.flush(); |
| |
| return 'data:image/gif;base64,' + base64; |
| }; |
| |
| |
| |
| |
| return qrcode; |
| }(); |
| |
| |
| !function() { |
| |
| qrcode.stringToBytesFuncs['UTF-8'] = function(s) { |
| |
| function toUTF8Array(str) { |
| var utf8 = []; |
| for (var i=0; i < str.length; i++) { |
| var charcode = str.charCodeAt(i); |
| if (charcode < 0x80) utf8.push(charcode); |
| else if (charcode < 0x800) { |
| utf8.push(0xc0 | (charcode >> 6), |
| 0x80 | (charcode & 0x3f)); |
| } |
| else if (charcode < 0xd800 || charcode >= 0xe000) { |
| utf8.push(0xe0 | (charcode >> 12), |
| 0x80 | ((charcode>>6) & 0x3f), |
| 0x80 | (charcode & 0x3f)); |
| } |
| |
| else { |
| i++; |
| |
| |
| |
| charcode = 0x10000 + (((charcode & 0x3ff)<<10) |
| | (str.charCodeAt(i) & 0x3ff)); |
| utf8.push(0xf0 | (charcode >>18), |
| 0x80 | ((charcode>>12) & 0x3f), |
| 0x80 | ((charcode>>6) & 0x3f), |
| 0x80 | (charcode & 0x3f)); |
| } |
| } |
| return utf8; |
| } |
| return toUTF8Array(s); |
| }; |
| |
| }(); |
| |
| (function (factory) { |
| if (typeof define === 'function' && define.amd) { |
| define([], factory); |
| } else if (typeof exports === 'object') { |
| module.exports = factory(); |
| } |
| }(function () { |
| return qrcode; |
| })); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| !function(qrcode) { |
| |
| |
| |
| |
| |
| qrcode.stringToBytes = qrcode.stringToBytesFuncs['UTF-8']; |
| |
| }(qrcode); |
| |
| </script> |
| <script> |
| (function webpackUniversalModuleDefinition(root, factory) { |
| if(typeof exports === 'object' && typeof module === 'object') |
| module.exports = factory(); |
| else if(typeof define === 'function' && define.amd) |
| define([], factory); |
| else if(typeof exports === 'object') |
| exports["jsQR"] = factory(); |
| else |
| root["jsQR"] = factory(); |
| })(typeof self !== 'undefined' ? self : this, function() { |
| return (function(modules) { |
| |
| var installedModules = {}; |
| |
| |
| function __webpack_require__(moduleId) { |
| |
| |
| if(installedModules[moduleId]) { |
| return installedModules[moduleId].exports; |
| } |
| |
| var module = installedModules[moduleId] = { |
| i: moduleId, |
| l: false, |
| exports: {} |
| }; |
| |
| |
| modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); |
| |
| |
| module.l = true; |
| |
| |
| return module.exports; |
| } |
| |
| |
| |
| __webpack_require__.m = modules; |
| |
| |
| __webpack_require__.c = installedModules; |
| |
| |
| __webpack_require__.d = function(exports, name, getter) { |
| if(!__webpack_require__.o(exports, name)) { |
| Object.defineProperty(exports, name, { |
| configurable: false, |
| enumerable: true, |
| get: getter |
| }); |
| } |
| }; |
| |
| |
| __webpack_require__.n = function(module) { |
| var getter = module && module.__esModule ? |
| function getDefault() { return module['default']; } : |
| function getModuleExports() { return module; }; |
| __webpack_require__.d(getter, 'a', getter); |
| return getter; |
| }; |
| |
| |
| __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; |
| |
| |
| __webpack_require__.p = ""; |
| |
| |
| return __webpack_require__(__webpack_require__.s = 3); |
| }) |
| |
| ([ |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var BitMatrix = (function () { |
| function BitMatrix(data, width) { |
| this.width = width; |
| this.height = data.length / width; |
| this.data = data; |
| } |
| BitMatrix.createEmpty = function (width, height) { |
| return new BitMatrix(new Uint8ClampedArray(width * height), width); |
| }; |
| BitMatrix.prototype.get = function (x, y) { |
| if (x < 0 || x >= this.width || y < 0 || y >= this.height) { |
| return false; |
| } |
| return !!this.data[y * this.width + x]; |
| }; |
| BitMatrix.prototype.set = function (x, y, v) { |
| this.data[y * this.width + x] = v ? 1 : 0; |
| }; |
| BitMatrix.prototype.setRegion = function (left, top, width, height, v) { |
| for (var y = top; y < top + height; y++) { |
| for (var x = left; x < left + width; x++) { |
| this.set(x, y, !!v); |
| } |
| } |
| }; |
| return BitMatrix; |
| }()); |
| exports.BitMatrix = BitMatrix; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var GenericGFPoly_1 = __webpack_require__(2); |
| function addOrSubtractGF(a, b) { |
| return a ^ b; |
| } |
| exports.addOrSubtractGF = addOrSubtractGF; |
| var GenericGF = (function () { |
| function GenericGF(primitive, size, genBase) { |
| this.primitive = primitive; |
| this.size = size; |
| this.generatorBase = genBase; |
| this.expTable = new Array(this.size); |
| this.logTable = new Array(this.size); |
| var x = 1; |
| for (var i = 0; i < this.size; i++) { |
| this.expTable[i] = x; |
| x = x * 2; |
| if (x >= this.size) { |
| x = (x ^ this.primitive) & (this.size - 1); |
| } |
| } |
| for (var i = 0; i < this.size - 1; i++) { |
| this.logTable[this.expTable[i]] = i; |
| } |
| this.zero = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([0])); |
| this.one = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([1])); |
| } |
| GenericGF.prototype.multiply = function (a, b) { |
| if (a === 0 || b === 0) { |
| return 0; |
| } |
| return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)]; |
| }; |
| GenericGF.prototype.inverse = function (a) { |
| if (a === 0) { |
| throw new Error("Can't invert 0"); |
| } |
| return this.expTable[this.size - this.logTable[a] - 1]; |
| }; |
| GenericGF.prototype.buildMonomial = function (degree, coefficient) { |
| if (degree < 0) { |
| throw new Error("Invalid monomial degree less than 0"); |
| } |
| if (coefficient === 0) { |
| return this.zero; |
| } |
| var coefficients = new Uint8ClampedArray(degree + 1); |
| coefficients[0] = coefficient; |
| return new GenericGFPoly_1.default(this, coefficients); |
| }; |
| GenericGF.prototype.log = function (a) { |
| if (a === 0) { |
| throw new Error("Can't take log(0)"); |
| } |
| return this.logTable[a]; |
| }; |
| GenericGF.prototype.exp = function (a) { |
| return this.expTable[a]; |
| }; |
| return GenericGF; |
| }()); |
| exports.default = GenericGF; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var GenericGF_1 = __webpack_require__(1); |
| var GenericGFPoly = (function () { |
| function GenericGFPoly(field, coefficients) { |
| if (coefficients.length === 0) { |
| throw new Error("No coefficients."); |
| } |
| this.field = field; |
| var coefficientsLength = coefficients.length; |
| if (coefficientsLength > 1 && coefficients[0] === 0) { |
| |
| var firstNonZero = 1; |
| while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) { |
| firstNonZero++; |
| } |
| if (firstNonZero === coefficientsLength) { |
| this.coefficients = field.zero.coefficients; |
| } |
| else { |
| this.coefficients = new Uint8ClampedArray(coefficientsLength - firstNonZero); |
| for (var i = 0; i < this.coefficients.length; i++) { |
| this.coefficients[i] = coefficients[firstNonZero + i]; |
| } |
| } |
| } |
| else { |
| this.coefficients = coefficients; |
| } |
| } |
| GenericGFPoly.prototype.degree = function () { |
| return this.coefficients.length - 1; |
| }; |
| GenericGFPoly.prototype.isZero = function () { |
| return this.coefficients[0] === 0; |
| }; |
| GenericGFPoly.prototype.getCoefficient = function (degree) { |
| return this.coefficients[this.coefficients.length - 1 - degree]; |
| }; |
| GenericGFPoly.prototype.addOrSubtract = function (other) { |
| var _a; |
| if (this.isZero()) { |
| return other; |
| } |
| if (other.isZero()) { |
| return this; |
| } |
| var smallerCoefficients = this.coefficients; |
| var largerCoefficients = other.coefficients; |
| if (smallerCoefficients.length > largerCoefficients.length) { |
| _a = [largerCoefficients, smallerCoefficients], smallerCoefficients = _a[0], largerCoefficients = _a[1]; |
| } |
| var sumDiff = new Uint8ClampedArray(largerCoefficients.length); |
| var lengthDiff = largerCoefficients.length - smallerCoefficients.length; |
| for (var i = 0; i < lengthDiff; i++) { |
| sumDiff[i] = largerCoefficients[i]; |
| } |
| for (var i = lengthDiff; i < largerCoefficients.length; i++) { |
| sumDiff[i] = GenericGF_1.addOrSubtractGF(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); |
| } |
| return new GenericGFPoly(this.field, sumDiff); |
| }; |
| GenericGFPoly.prototype.multiply = function (scalar) { |
| if (scalar === 0) { |
| return this.field.zero; |
| } |
| if (scalar === 1) { |
| return this; |
| } |
| var size = this.coefficients.length; |
| var product = new Uint8ClampedArray(size); |
| for (var i = 0; i < size; i++) { |
| product[i] = this.field.multiply(this.coefficients[i], scalar); |
| } |
| return new GenericGFPoly(this.field, product); |
| }; |
| GenericGFPoly.prototype.multiplyPoly = function (other) { |
| if (this.isZero() || other.isZero()) { |
| return this.field.zero; |
| } |
| var aCoefficients = this.coefficients; |
| var aLength = aCoefficients.length; |
| var bCoefficients = other.coefficients; |
| var bLength = bCoefficients.length; |
| var product = new Uint8ClampedArray(aLength + bLength - 1); |
| for (var i = 0; i < aLength; i++) { |
| var aCoeff = aCoefficients[i]; |
| for (var j = 0; j < bLength; j++) { |
| product[i + j] = GenericGF_1.addOrSubtractGF(product[i + j], this.field.multiply(aCoeff, bCoefficients[j])); |
| } |
| } |
| return new GenericGFPoly(this.field, product); |
| }; |
| GenericGFPoly.prototype.multiplyByMonomial = function (degree, coefficient) { |
| if (degree < 0) { |
| throw new Error("Invalid degree less than 0"); |
| } |
| if (coefficient === 0) { |
| return this.field.zero; |
| } |
| var size = this.coefficients.length; |
| var product = new Uint8ClampedArray(size + degree); |
| for (var i = 0; i < size; i++) { |
| product[i] = this.field.multiply(this.coefficients[i], coefficient); |
| } |
| return new GenericGFPoly(this.field, product); |
| }; |
| GenericGFPoly.prototype.evaluateAt = function (a) { |
| var result = 0; |
| if (a === 0) { |
| |
| return this.getCoefficient(0); |
| } |
| var size = this.coefficients.length; |
| if (a === 1) { |
| |
| this.coefficients.forEach(function (coefficient) { |
| result = GenericGF_1.addOrSubtractGF(result, coefficient); |
| }); |
| return result; |
| } |
| result = this.coefficients[0]; |
| for (var i = 1; i < size; i++) { |
| result = GenericGF_1.addOrSubtractGF(this.field.multiply(a, result), this.coefficients[i]); |
| } |
| return result; |
| }; |
| return GenericGFPoly; |
| }()); |
| exports.default = GenericGFPoly; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var binarizer_1 = __webpack_require__(4); |
| var decoder_1 = __webpack_require__(5); |
| var extractor_1 = __webpack_require__(11); |
| var locator_1 = __webpack_require__(12); |
| function scan(matrix) { |
| var locations = locator_1.locate(matrix); |
| if (!locations) { |
| return null; |
| } |
| for (var _i = 0, locations_1 = locations; _i < locations_1.length; _i++) { |
| var location_1 = locations_1[_i]; |
| var extracted = extractor_1.extract(matrix, location_1); |
| var decoded = decoder_1.decode(extracted.matrix); |
| if (decoded) { |
| return { |
| binaryData: decoded.bytes, |
| data: decoded.text, |
| chunks: decoded.chunks, |
| version: decoded.version, |
| location: { |
| topRightCorner: extracted.mappingFunction(location_1.dimension, 0), |
| topLeftCorner: extracted.mappingFunction(0, 0), |
| bottomRightCorner: extracted.mappingFunction(location_1.dimension, location_1.dimension), |
| bottomLeftCorner: extracted.mappingFunction(0, location_1.dimension), |
| topRightFinderPattern: location_1.topRight, |
| topLeftFinderPattern: location_1.topLeft, |
| bottomLeftFinderPattern: location_1.bottomLeft, |
| bottomRightAlignmentPattern: location_1.alignmentPattern, |
| }, |
| }; |
| } |
| } |
| return null; |
| } |
| var defaultOptions = { |
| inversionAttempts: "attemptBoth", |
| }; |
| function jsQR(data, width, height, providedOptions) { |
| if (providedOptions === void 0) { providedOptions = {}; } |
| var options = defaultOptions; |
| Object.keys(options || {}).forEach(function (opt) { |
| options[opt] = providedOptions[opt] || options[opt]; |
| }); |
| var shouldInvert = options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst"; |
| var tryInvertedFirst = options.inversionAttempts === "onlyInvert" || options.inversionAttempts === "invertFirst"; |
| var _a = binarizer_1.binarize(data, width, height, shouldInvert), binarized = _a.binarized, inverted = _a.inverted; |
| var result = scan(tryInvertedFirst ? inverted : binarized); |
| if (!result && (options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst")) { |
| result = scan(tryInvertedFirst ? binarized : inverted); |
| } |
| return result; |
| } |
| jsQR.default = jsQR; |
| exports.default = jsQR; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var BitMatrix_1 = __webpack_require__(0); |
| var REGION_SIZE = 8; |
| var MIN_DYNAMIC_RANGE = 24; |
| function numBetween(value, min, max) { |
| return value < min ? min : value > max ? max : value; |
| } |
| |
| var Matrix = (function () { |
| function Matrix(width, height) { |
| this.width = width; |
| this.data = new Uint8ClampedArray(width * height); |
| } |
| Matrix.prototype.get = function (x, y) { |
| return this.data[y * this.width + x]; |
| }; |
| Matrix.prototype.set = function (x, y, value) { |
| this.data[y * this.width + x] = value; |
| }; |
| return Matrix; |
| }()); |
| function binarize(data, width, height, returnInverted) { |
| if (data.length !== width * height * 4) { |
| throw new Error("Malformed data passed to binarizer."); |
| } |
| |
| var greyscalePixels = new Matrix(width, height); |
| for (var x = 0; x < width; x++) { |
| for (var y = 0; y < height; y++) { |
| var r = data[((y * width + x) * 4) + 0]; |
| var g = data[((y * width + x) * 4) + 1]; |
| var b = data[((y * width + x) * 4) + 2]; |
| greyscalePixels.set(x, y, 0.2126 * r + 0.7152 * g + 0.0722 * b); |
| } |
| } |
| var horizontalRegionCount = Math.ceil(width / REGION_SIZE); |
| var verticalRegionCount = Math.ceil(height / REGION_SIZE); |
| var blackPoints = new Matrix(horizontalRegionCount, verticalRegionCount); |
| for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) { |
| for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) { |
| var sum = 0; |
| var min = Infinity; |
| var max = 0; |
| for (var y = 0; y < REGION_SIZE; y++) { |
| for (var x = 0; x < REGION_SIZE; x++) { |
| var pixelLumosity = greyscalePixels.get(hortizontalRegion * REGION_SIZE + x, verticalRegion * REGION_SIZE + y); |
| sum += pixelLumosity; |
| min = Math.min(min, pixelLumosity); |
| max = Math.max(max, pixelLumosity); |
| } |
| } |
| var average = sum / (Math.pow(REGION_SIZE, 2)); |
| if (max - min <= MIN_DYNAMIC_RANGE) { |
| |
| |
| |
| |
| |
| average = min / 2; |
| if (verticalRegion > 0 && hortizontalRegion > 0) { |
| |
| |
| |
| |
| |
| |
| var averageNeighborBlackPoint = (blackPoints.get(hortizontalRegion, verticalRegion - 1) + |
| (2 * blackPoints.get(hortizontalRegion - 1, verticalRegion)) + |
| blackPoints.get(hortizontalRegion - 1, verticalRegion - 1)) / 4; |
| if (min < averageNeighborBlackPoint) { |
| average = averageNeighborBlackPoint; |
| } |
| } |
| } |
| blackPoints.set(hortizontalRegion, verticalRegion, average); |
| } |
| } |
| var binarized = BitMatrix_1.BitMatrix.createEmpty(width, height); |
| var inverted = null; |
| if (returnInverted) { |
| inverted = BitMatrix_1.BitMatrix.createEmpty(width, height); |
| } |
| for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) { |
| for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) { |
| var left = numBetween(hortizontalRegion, 2, horizontalRegionCount - 3); |
| var top_1 = numBetween(verticalRegion, 2, verticalRegionCount - 3); |
| var sum = 0; |
| for (var xRegion = -2; xRegion <= 2; xRegion++) { |
| for (var yRegion = -2; yRegion <= 2; yRegion++) { |
| sum += blackPoints.get(left + xRegion, top_1 + yRegion); |
| } |
| } |
| var threshold = sum / 25; |
| for (var xRegion = 0; xRegion < REGION_SIZE; xRegion++) { |
| for (var yRegion = 0; yRegion < REGION_SIZE; yRegion++) { |
| var x = hortizontalRegion * REGION_SIZE + xRegion; |
| var y = verticalRegion * REGION_SIZE + yRegion; |
| var lum = greyscalePixels.get(x, y); |
| binarized.set(x, y, lum <= threshold); |
| if (returnInverted) { |
| inverted.set(x, y, !(lum <= threshold)); |
| } |
| } |
| } |
| } |
| } |
| if (returnInverted) { |
| return { binarized: binarized, inverted: inverted }; |
| } |
| return { binarized: binarized }; |
| } |
| exports.binarize = binarize; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var BitMatrix_1 = __webpack_require__(0); |
| var decodeData_1 = __webpack_require__(6); |
| var reedsolomon_1 = __webpack_require__(9); |
| var version_1 = __webpack_require__(10); |
| |
| function numBitsDiffering(x, y) { |
| var z = x ^ y; |
| var bitCount = 0; |
| while (z) { |
| bitCount++; |
| z &= z - 1; |
| } |
| return bitCount; |
| } |
| function pushBit(bit, byte) { |
| return (byte << 1) | bit; |
| } |
| |
| var FORMAT_INFO_TABLE = [ |
| { bits: 0x5412, formatInfo: { errorCorrectionLevel: 1, dataMask: 0 } }, |
| { bits: 0x5125, formatInfo: { errorCorrectionLevel: 1, dataMask: 1 } }, |
| { bits: 0x5E7C, formatInfo: { errorCorrectionLevel: 1, dataMask: 2 } }, |
| { bits: 0x5B4B, formatInfo: { errorCorrectionLevel: 1, dataMask: 3 } }, |
| { bits: 0x45F9, formatInfo: { errorCorrectionLevel: 1, dataMask: 4 } }, |
| { bits: 0x40CE, formatInfo: { errorCorrectionLevel: 1, dataMask: 5 } }, |
| { bits: 0x4F97, formatInfo: { errorCorrectionLevel: 1, dataMask: 6 } }, |
| { bits: 0x4AA0, formatInfo: { errorCorrectionLevel: 1, dataMask: 7 } }, |
| { bits: 0x77C4, formatInfo: { errorCorrectionLevel: 0, dataMask: 0 } }, |
| { bits: 0x72F3, formatInfo: { errorCorrectionLevel: 0, dataMask: 1 } }, |
| { bits: 0x7DAA, formatInfo: { errorCorrectionLevel: 0, dataMask: 2 } }, |
| { bits: 0x789D, formatInfo: { errorCorrectionLevel: 0, dataMask: 3 } }, |
| { bits: 0x662F, formatInfo: { errorCorrectionLevel: 0, dataMask: 4 } }, |
| { bits: 0x6318, formatInfo: { errorCorrectionLevel: 0, dataMask: 5 } }, |
| { bits: 0x6C41, formatInfo: { errorCorrectionLevel: 0, dataMask: 6 } }, |
| { bits: 0x6976, formatInfo: { errorCorrectionLevel: 0, dataMask: 7 } }, |
| { bits: 0x1689, formatInfo: { errorCorrectionLevel: 3, dataMask: 0 } }, |
| { bits: 0x13BE, formatInfo: { errorCorrectionLevel: 3, dataMask: 1 } }, |
| { bits: 0x1CE7, formatInfo: { errorCorrectionLevel: 3, dataMask: 2 } }, |
| { bits: 0x19D0, formatInfo: { errorCorrectionLevel: 3, dataMask: 3 } }, |
| { bits: 0x0762, formatInfo: { errorCorrectionLevel: 3, dataMask: 4 } }, |
| { bits: 0x0255, formatInfo: { errorCorrectionLevel: 3, dataMask: 5 } }, |
| { bits: 0x0D0C, formatInfo: { errorCorrectionLevel: 3, dataMask: 6 } }, |
| { bits: 0x083B, formatInfo: { errorCorrectionLevel: 3, dataMask: 7 } }, |
| { bits: 0x355F, formatInfo: { errorCorrectionLevel: 2, dataMask: 0 } }, |
| { bits: 0x3068, formatInfo: { errorCorrectionLevel: 2, dataMask: 1 } }, |
| { bits: 0x3F31, formatInfo: { errorCorrectionLevel: 2, dataMask: 2 } }, |
| { bits: 0x3A06, formatInfo: { errorCorrectionLevel: 2, dataMask: 3 } }, |
| { bits: 0x24B4, formatInfo: { errorCorrectionLevel: 2, dataMask: 4 } }, |
| { bits: 0x2183, formatInfo: { errorCorrectionLevel: 2, dataMask: 5 } }, |
| { bits: 0x2EDA, formatInfo: { errorCorrectionLevel: 2, dataMask: 6 } }, |
| { bits: 0x2BED, formatInfo: { errorCorrectionLevel: 2, dataMask: 7 } }, |
| ]; |
| var DATA_MASKS = [ |
| function (p) { return ((p.y + p.x) % 2) === 0; }, |
| function (p) { return (p.y % 2) === 0; }, |
| function (p) { return p.x % 3 === 0; }, |
| function (p) { return (p.y + p.x) % 3 === 0; }, |
| function (p) { return (Math.floor(p.y / 2) + Math.floor(p.x / 3)) % 2 === 0; }, |
| function (p) { return ((p.x * p.y) % 2) + ((p.x * p.y) % 3) === 0; }, |
| function (p) { return ((((p.y * p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; }, |
| function (p) { return ((((p.y + p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; }, |
| ]; |
| function buildFunctionPatternMask(version) { |
| var dimension = 17 + 4 * version.versionNumber; |
| var matrix = BitMatrix_1.BitMatrix.createEmpty(dimension, dimension); |
| matrix.setRegion(0, 0, 9, 9, true); |
| matrix.setRegion(dimension - 8, 0, 8, 9, true); |
| matrix.setRegion(0, dimension - 8, 9, 8, true); |
| |
| for (var _i = 0, _a = version.alignmentPatternCenters; _i < _a.length; _i++) { |
| var x = _a[_i]; |
| for (var _b = 0, _c = version.alignmentPatternCenters; _b < _c.length; _b++) { |
| var y = _c[_b]; |
| if (!(x === 6 && y === 6 || x === 6 && y === dimension - 7 || x === dimension - 7 && y === 6)) { |
| matrix.setRegion(x - 2, y - 2, 5, 5, true); |
| } |
| } |
| } |
| matrix.setRegion(6, 9, 1, dimension - 17, true); |
| matrix.setRegion(9, 6, dimension - 17, 1, true); |
| if (version.versionNumber > 6) { |
| matrix.setRegion(dimension - 11, 0, 3, 6, true); |
| matrix.setRegion(0, dimension - 11, 6, 3, true); |
| } |
| return matrix; |
| } |
| function readCodewords(matrix, version, formatInfo) { |
| var dataMask = DATA_MASKS[formatInfo.dataMask]; |
| var dimension = matrix.height; |
| var functionPatternMask = buildFunctionPatternMask(version); |
| var codewords = []; |
| var currentByte = 0; |
| var bitsRead = 0; |
| |
| var readingUp = true; |
| for (var columnIndex = dimension - 1; columnIndex > 0; columnIndex -= 2) { |
| if (columnIndex === 6) { |
| columnIndex--; |
| } |
| for (var i = 0; i < dimension; i++) { |
| var y = readingUp ? dimension - 1 - i : i; |
| for (var columnOffset = 0; columnOffset < 2; columnOffset++) { |
| var x = columnIndex - columnOffset; |
| if (!functionPatternMask.get(x, y)) { |
| bitsRead++; |
| var bit = matrix.get(x, y); |
| if (dataMask({ y: y, x: x })) { |
| bit = !bit; |
| } |
| currentByte = pushBit(bit, currentByte); |
| if (bitsRead === 8) { |
| codewords.push(currentByte); |
| bitsRead = 0; |
| currentByte = 0; |
| } |
| } |
| } |
| } |
| readingUp = !readingUp; |
| } |
| return codewords; |
| } |
| function readVersion(matrix) { |
| var dimension = matrix.height; |
| var provisionalVersion = Math.floor((dimension - 17) / 4); |
| if (provisionalVersion <= 6) { |
| return version_1.VERSIONS[provisionalVersion - 1]; |
| } |
| var topRightVersionBits = 0; |
| for (var y = 5; y >= 0; y--) { |
| for (var x = dimension - 9; x >= dimension - 11; x--) { |
| topRightVersionBits = pushBit(matrix.get(x, y), topRightVersionBits); |
| } |
| } |
| var bottomLeftVersionBits = 0; |
| for (var x = 5; x >= 0; x--) { |
| for (var y = dimension - 9; y >= dimension - 11; y--) { |
| bottomLeftVersionBits = pushBit(matrix.get(x, y), bottomLeftVersionBits); |
| } |
| } |
| var bestDifference = Infinity; |
| var bestVersion; |
| for (var _i = 0, VERSIONS_1 = version_1.VERSIONS; _i < VERSIONS_1.length; _i++) { |
| var version = VERSIONS_1[_i]; |
| if (version.infoBits === topRightVersionBits || version.infoBits === bottomLeftVersionBits) { |
| return version; |
| } |
| var difference = numBitsDiffering(topRightVersionBits, version.infoBits); |
| if (difference < bestDifference) { |
| bestVersion = version; |
| bestDifference = difference; |
| } |
| difference = numBitsDiffering(bottomLeftVersionBits, version.infoBits); |
| if (difference < bestDifference) { |
| bestVersion = version; |
| bestDifference = difference; |
| } |
| } |
| |
| |
| if (bestDifference <= 3) { |
| return bestVersion; |
| } |
| } |
| function readFormatInformation(matrix) { |
| var topLeftFormatInfoBits = 0; |
| for (var x = 0; x <= 8; x++) { |
| if (x !== 6) { |
| topLeftFormatInfoBits = pushBit(matrix.get(x, 8), topLeftFormatInfoBits); |
| } |
| } |
| for (var y = 7; y >= 0; y--) { |
| if (y !== 6) { |
| topLeftFormatInfoBits = pushBit(matrix.get(8, y), topLeftFormatInfoBits); |
| } |
| } |
| var dimension = matrix.height; |
| var topRightBottomRightFormatInfoBits = 0; |
| for (var y = dimension - 1; y >= dimension - 7; y--) { |
| topRightBottomRightFormatInfoBits = pushBit(matrix.get(8, y), topRightBottomRightFormatInfoBits); |
| } |
| for (var x = dimension - 8; x < dimension; x++) { |
| topRightBottomRightFormatInfoBits = pushBit(matrix.get(x, 8), topRightBottomRightFormatInfoBits); |
| } |
| var bestDifference = Infinity; |
| var bestFormatInfo = null; |
| for (var _i = 0, FORMAT_INFO_TABLE_1 = FORMAT_INFO_TABLE; _i < FORMAT_INFO_TABLE_1.length; _i++) { |
| var _a = FORMAT_INFO_TABLE_1[_i], bits = _a.bits, formatInfo = _a.formatInfo; |
| if (bits === topLeftFormatInfoBits || bits === topRightBottomRightFormatInfoBits) { |
| return formatInfo; |
| } |
| var difference = numBitsDiffering(topLeftFormatInfoBits, bits); |
| if (difference < bestDifference) { |
| bestFormatInfo = formatInfo; |
| bestDifference = difference; |
| } |
| if (topLeftFormatInfoBits !== topRightBottomRightFormatInfoBits) { |
| difference = numBitsDiffering(topRightBottomRightFormatInfoBits, bits); |
| if (difference < bestDifference) { |
| bestFormatInfo = formatInfo; |
| bestDifference = difference; |
| } |
| } |
| } |
| |
| if (bestDifference <= 3) { |
| return bestFormatInfo; |
| } |
| return null; |
| } |
| function getDataBlocks(codewords, version, ecLevel) { |
| var ecInfo = version.errorCorrectionLevels[ecLevel]; |
| var dataBlocks = []; |
| var totalCodewords = 0; |
| ecInfo.ecBlocks.forEach(function (block) { |
| for (var i = 0; i < block.numBlocks; i++) { |
| dataBlocks.push({ numDataCodewords: block.dataCodewordsPerBlock, codewords: [] }); |
| totalCodewords += block.dataCodewordsPerBlock + ecInfo.ecCodewordsPerBlock; |
| } |
| }); |
| |
| |
| |
| if (codewords.length < totalCodewords) { |
| return null; |
| } |
| codewords = codewords.slice(0, totalCodewords); |
| var shortBlockSize = ecInfo.ecBlocks[0].dataCodewordsPerBlock; |
| |
| for (var i = 0; i < shortBlockSize; i++) { |
| for (var _i = 0, dataBlocks_1 = dataBlocks; _i < dataBlocks_1.length; _i++) { |
| var dataBlock = dataBlocks_1[_i]; |
| dataBlock.codewords.push(codewords.shift()); |
| } |
| } |
| |
| if (ecInfo.ecBlocks.length > 1) { |
| var smallBlockCount = ecInfo.ecBlocks[0].numBlocks; |
| var largeBlockCount = ecInfo.ecBlocks[1].numBlocks; |
| for (var i = 0; i < largeBlockCount; i++) { |
| dataBlocks[smallBlockCount + i].codewords.push(codewords.shift()); |
| } |
| } |
| |
| while (codewords.length > 0) { |
| for (var _a = 0, dataBlocks_2 = dataBlocks; _a < dataBlocks_2.length; _a++) { |
| var dataBlock = dataBlocks_2[_a]; |
| dataBlock.codewords.push(codewords.shift()); |
| } |
| } |
| return dataBlocks; |
| } |
| function decodeMatrix(matrix) { |
| var version = readVersion(matrix); |
| if (!version) { |
| return null; |
| } |
| var formatInfo = readFormatInformation(matrix); |
| if (!formatInfo) { |
| return null; |
| } |
| var codewords = readCodewords(matrix, version, formatInfo); |
| var dataBlocks = getDataBlocks(codewords, version, formatInfo.errorCorrectionLevel); |
| if (!dataBlocks) { |
| return null; |
| } |
| |
| var totalBytes = dataBlocks.reduce(function (a, b) { return a + b.numDataCodewords; }, 0); |
| var resultBytes = new Uint8ClampedArray(totalBytes); |
| var resultIndex = 0; |
| for (var _i = 0, dataBlocks_3 = dataBlocks; _i < dataBlocks_3.length; _i++) { |
| var dataBlock = dataBlocks_3[_i]; |
| var correctedBytes = reedsolomon_1.decode(dataBlock.codewords, dataBlock.codewords.length - dataBlock.numDataCodewords); |
| if (!correctedBytes) { |
| return null; |
| } |
| for (var i = 0; i < dataBlock.numDataCodewords; i++) { |
| resultBytes[resultIndex++] = correctedBytes[i]; |
| } |
| } |
| try { |
| return decodeData_1.decode(resultBytes, version.versionNumber); |
| } |
| catch (_a) { |
| return null; |
| } |
| } |
| function decode(matrix) { |
| if (matrix == null) { |
| return null; |
| } |
| var result = decodeMatrix(matrix); |
| if (result) { |
| return result; |
| } |
| |
| for (var x = 0; x < matrix.width; x++) { |
| for (var y = x + 1; y < matrix.height; y++) { |
| if (matrix.get(x, y) !== matrix.get(y, x)) { |
| matrix.set(x, y, !matrix.get(x, y)); |
| matrix.set(y, x, !matrix.get(y, x)); |
| } |
| } |
| } |
| return decodeMatrix(matrix); |
| } |
| exports.decode = decode; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| |
| var BitStream_1 = __webpack_require__(7); |
| var shiftJISTable_1 = __webpack_require__(8); |
| var Mode; |
| (function (Mode) { |
| Mode["Numeric"] = "numeric"; |
| Mode["Alphanumeric"] = "alphanumeric"; |
| Mode["Byte"] = "byte"; |
| Mode["Kanji"] = "kanji"; |
| Mode["ECI"] = "eci"; |
| })(Mode = exports.Mode || (exports.Mode = {})); |
| var ModeByte; |
| (function (ModeByte) { |
| ModeByte[ModeByte["Terminator"] = 0] = "Terminator"; |
| ModeByte[ModeByte["Numeric"] = 1] = "Numeric"; |
| ModeByte[ModeByte["Alphanumeric"] = 2] = "Alphanumeric"; |
| ModeByte[ModeByte["Byte"] = 4] = "Byte"; |
| ModeByte[ModeByte["Kanji"] = 8] = "Kanji"; |
| ModeByte[ModeByte["ECI"] = 7] = "ECI"; |
| |
| |
| |
| })(ModeByte || (ModeByte = {})); |
| function decodeNumeric(stream, size) { |
| var bytes = []; |
| var text = ""; |
| var characterCountSize = [10, 12, 14][size]; |
| var length = stream.readBits(characterCountSize); |
| |
| while (length >= 3) { |
| var num = stream.readBits(10); |
| if (num >= 1000) { |
| throw new Error("Invalid numeric value above 999"); |
| } |
| var a = Math.floor(num / 100); |
| var b = Math.floor(num / 10) % 10; |
| var c = num % 10; |
| bytes.push(48 + a, 48 + b, 48 + c); |
| text += a.toString() + b.toString() + c.toString(); |
| length -= 3; |
| } |
| |
| if (length === 2) { |
| var num = stream.readBits(7); |
| if (num >= 100) { |
| throw new Error("Invalid numeric value above 99"); |
| } |
| var a = Math.floor(num / 10); |
| var b = num % 10; |
| bytes.push(48 + a, 48 + b); |
| text += a.toString() + b.toString(); |
| } |
| else if (length === 1) { |
| var num = stream.readBits(4); |
| if (num >= 10) { |
| throw new Error("Invalid numeric value above 9"); |
| } |
| bytes.push(48 + num); |
| text += num.toString(); |
| } |
| return { bytes: bytes, text: text }; |
| } |
| var AlphanumericCharacterCodes = [ |
| "0", "1", "2", "3", "4", "5", "6", "7", "8", |
| "9", "A", "B", "C", "D", "E", "F", "G", "H", |
| "I", "J", "K", "L", "M", "N", "O", "P", "Q", |
| "R", "S", "T", "U", "V", "W", "X", "Y", "Z", |
| " ", "$", "%", "*", "+", "-", ".", "/", ":", |
| ]; |
| function decodeAlphanumeric(stream, size) { |
| var bytes = []; |
| var text = ""; |
| var characterCountSize = [9, 11, 13][size]; |
| var length = stream.readBits(characterCountSize); |
| while (length >= 2) { |
| var v = stream.readBits(11); |
| var a = Math.floor(v / 45); |
| var b = v % 45; |
| bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0), AlphanumericCharacterCodes[b].charCodeAt(0)); |
| text += AlphanumericCharacterCodes[a] + AlphanumericCharacterCodes[b]; |
| length -= 2; |
| } |
| if (length === 1) { |
| var a = stream.readBits(6); |
| bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0)); |
| text += AlphanumericCharacterCodes[a]; |
| } |
| return { bytes: bytes, text: text }; |
| } |
| function decodeByte(stream, size) { |
| var bytes = []; |
| var text = ""; |
| var characterCountSize = [8, 16, 16][size]; |
| var length = stream.readBits(characterCountSize); |
| for (var i = 0; i < length; i++) { |
| var b = stream.readBits(8); |
| bytes.push(b); |
| } |
| try { |
| text += decodeURIComponent(bytes.map(function (b) { return "%" + ("0" + b.toString(16)).substr(-2); }).join("")); |
| } |
| catch (_a) { |
| |
| } |
| return { bytes: bytes, text: text }; |
| } |
| function decodeKanji(stream, size) { |
| var bytes = []; |
| var text = ""; |
| var characterCountSize = [8, 10, 12][size]; |
| var length = stream.readBits(characterCountSize); |
| for (var i = 0; i < length; i++) { |
| var k = stream.readBits(13); |
| var c = (Math.floor(k / 0xC0) << 8) | (k % 0xC0); |
| if (c < 0x1F00) { |
| c += 0x8140; |
| } |
| else { |
| c += 0xC140; |
| } |
| bytes.push(c >> 8, c & 0xFF); |
| text += String.fromCharCode(shiftJISTable_1.shiftJISTable[c]); |
| } |
| return { bytes: bytes, text: text }; |
| } |
| function decode(data, version) { |
| var _a, _b, _c, _d; |
| var stream = new BitStream_1.BitStream(data); |
| |
| var size = version <= 9 ? 0 : version <= 26 ? 1 : 2; |
| var result = { |
| text: "", |
| bytes: [], |
| chunks: [], |
| version: version, |
| }; |
| while (stream.available() >= 4) { |
| var mode = stream.readBits(4); |
| if (mode === ModeByte.Terminator) { |
| return result; |
| } |
| else if (mode === ModeByte.ECI) { |
| if (stream.readBits(1) === 0) { |
| result.chunks.push({ |
| type: Mode.ECI, |
| assignmentNumber: stream.readBits(7), |
| }); |
| } |
| else if (stream.readBits(1) === 0) { |
| result.chunks.push({ |
| type: Mode.ECI, |
| assignmentNumber: stream.readBits(14), |
| }); |
| } |
| else if (stream.readBits(1) === 0) { |
| result.chunks.push({ |
| type: Mode.ECI, |
| assignmentNumber: stream.readBits(21), |
| }); |
| } |
| else { |
| |
| result.chunks.push({ |
| type: Mode.ECI, |
| assignmentNumber: -1, |
| }); |
| } |
| } |
| else if (mode === ModeByte.Numeric) { |
| var numericResult = decodeNumeric(stream, size); |
| result.text += numericResult.text; |
| (_a = result.bytes).push.apply(_a, numericResult.bytes); |
| result.chunks.push({ |
| type: Mode.Numeric, |
| text: numericResult.text, |
| }); |
| } |
| else if (mode === ModeByte.Alphanumeric) { |
| var alphanumericResult = decodeAlphanumeric(stream, size); |
| result.text += alphanumericResult.text; |
| (_b = result.bytes).push.apply(_b, alphanumericResult.bytes); |
| result.chunks.push({ |
| type: Mode.Alphanumeric, |
| text: alphanumericResult.text, |
| }); |
| } |
| else if (mode === ModeByte.Byte) { |
| var byteResult = decodeByte(stream, size); |
| result.text += byteResult.text; |
| (_c = result.bytes).push.apply(_c, byteResult.bytes); |
| result.chunks.push({ |
| type: Mode.Byte, |
| bytes: byteResult.bytes, |
| text: byteResult.text, |
| }); |
| } |
| else if (mode === ModeByte.Kanji) { |
| var kanjiResult = decodeKanji(stream, size); |
| result.text += kanjiResult.text; |
| (_d = result.bytes).push.apply(_d, kanjiResult.bytes); |
| result.chunks.push({ |
| type: Mode.Kanji, |
| bytes: kanjiResult.bytes, |
| text: kanjiResult.text, |
| }); |
| } |
| } |
| |
| if (stream.available() === 0 || stream.readBits(stream.available()) === 0) { |
| return result; |
| } |
| } |
| exports.decode = decode; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var BitStream = (function () { |
| function BitStream(bytes) { |
| this.byteOffset = 0; |
| this.bitOffset = 0; |
| this.bytes = bytes; |
| } |
| BitStream.prototype.readBits = function (numBits) { |
| if (numBits < 1 || numBits > 32 || numBits > this.available()) { |
| throw new Error("Cannot read " + numBits.toString() + " bits"); |
| } |
| var result = 0; |
| |
| if (this.bitOffset > 0) { |
| var bitsLeft = 8 - this.bitOffset; |
| var toRead = numBits < bitsLeft ? numBits : bitsLeft; |
| var bitsToNotRead = bitsLeft - toRead; |
| var mask = (0xFF >> (8 - toRead)) << bitsToNotRead; |
| result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead; |
| numBits -= toRead; |
| this.bitOffset += toRead; |
| if (this.bitOffset === 8) { |
| this.bitOffset = 0; |
| this.byteOffset++; |
| } |
| } |
| |
| if (numBits > 0) { |
| while (numBits >= 8) { |
| result = (result << 8) | (this.bytes[this.byteOffset] & 0xFF); |
| this.byteOffset++; |
| numBits -= 8; |
| } |
| |
| if (numBits > 0) { |
| var bitsToNotRead = 8 - numBits; |
| var mask = (0xFF >> bitsToNotRead) << bitsToNotRead; |
| result = (result << numBits) | ((this.bytes[this.byteOffset] & mask) >> bitsToNotRead); |
| this.bitOffset += numBits; |
| } |
| } |
| return result; |
| }; |
| BitStream.prototype.available = function () { |
| return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset; |
| }; |
| return BitStream; |
| }()); |
| exports.BitStream = BitStream; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.shiftJISTable = { |
| 0x20: 0x0020, |
| 0x21: 0x0021, |
| 0x22: 0x0022, |
| 0x23: 0x0023, |
| 0x24: 0x0024, |
| 0x25: 0x0025, |
| 0x26: 0x0026, |
| 0x27: 0x0027, |
| 0x28: 0x0028, |
| 0x29: 0x0029, |
| 0x2A: 0x002A, |
| 0x2B: 0x002B, |
| 0x2C: 0x002C, |
| 0x2D: 0x002D, |
| 0x2E: 0x002E, |
| 0x2F: 0x002F, |
| 0x30: 0x0030, |
| 0x31: 0x0031, |
| 0x32: 0x0032, |
| 0x33: 0x0033, |
| 0x34: 0x0034, |
| 0x35: 0x0035, |
| 0x36: 0x0036, |
| 0x37: 0x0037, |
| 0x38: 0x0038, |
| 0x39: 0x0039, |
| 0x3A: 0x003A, |
| 0x3B: 0x003B, |
| 0x3C: 0x003C, |
| 0x3D: 0x003D, |
| 0x3E: 0x003E, |
| 0x3F: 0x003F, |
| 0x40: 0x0040, |
| 0x41: 0x0041, |
| 0x42: 0x0042, |
| 0x43: 0x0043, |
| 0x44: 0x0044, |
| 0x45: 0x0045, |
| 0x46: 0x0046, |
| 0x47: 0x0047, |
| 0x48: 0x0048, |
| 0x49: 0x0049, |
| 0x4A: 0x004A, |
| 0x4B: 0x004B, |
| 0x4C: 0x004C, |
| 0x4D: 0x004D, |
| 0x4E: 0x004E, |
| 0x4F: 0x004F, |
| 0x50: 0x0050, |
| 0x51: 0x0051, |
| 0x52: 0x0052, |
| 0x53: 0x0053, |
| 0x54: 0x0054, |
| 0x55: 0x0055, |
| 0x56: 0x0056, |
| 0x57: 0x0057, |
| 0x58: 0x0058, |
| 0x59: 0x0059, |
| 0x5A: 0x005A, |
| 0x5B: 0x005B, |
| 0x5C: 0x00A5, |
| 0x5D: 0x005D, |
| 0x5E: 0x005E, |
| 0x5F: 0x005F, |
| 0x60: 0x0060, |
| 0x61: 0x0061, |
| 0x62: 0x0062, |
| 0x63: 0x0063, |
| 0x64: 0x0064, |
| 0x65: 0x0065, |
| 0x66: 0x0066, |
| 0x67: 0x0067, |
| 0x68: 0x0068, |
| 0x69: 0x0069, |
| 0x6A: 0x006A, |
| 0x6B: 0x006B, |
| 0x6C: 0x006C, |
| 0x6D: 0x006D, |
| 0x6E: 0x006E, |
| 0x6F: 0x006F, |
| 0x70: 0x0070, |
| 0x71: 0x0071, |
| 0x72: 0x0072, |
| 0x73: 0x0073, |
| 0x74: 0x0074, |
| 0x75: 0x0075, |
| 0x76: 0x0076, |
| 0x77: 0x0077, |
| 0x78: 0x0078, |
| 0x79: 0x0079, |
| 0x7A: 0x007A, |
| 0x7B: 0x007B, |
| 0x7C: 0x007C, |
| 0x7D: 0x007D, |
| 0x7E: 0x203E, |
| 0x8140: 0x3000, |
| 0x8141: 0x3001, |
| 0x8142: 0x3002, |
| 0x8143: 0xFF0C, |
| 0x8144: 0xFF0E, |
| 0x8145: 0x30FB, |
| 0x8146: 0xFF1A, |
| 0x8147: 0xFF1B, |
| 0x8148: 0xFF1F, |
| 0x8149: 0xFF01, |
| 0x814A: 0x309B, |
| 0x814B: 0x309C, |
| 0x814C: 0x00B4, |
| 0x814D: 0xFF40, |
| 0x814E: 0x00A8, |
| 0x814F: 0xFF3E, |
| 0x8150: 0xFFE3, |
| 0x8151: 0xFF3F, |
| 0x8152: 0x30FD, |
| 0x8153: 0x30FE, |
| 0x8154: 0x309D, |
| 0x8155: 0x309E, |
| 0x8156: 0x3003, |
| 0x8157: 0x4EDD, |
| 0x8158: 0x3005, |
| 0x8159: 0x3006, |
| 0x815A: 0x3007, |
| 0x815B: 0x30FC, |
| 0x815C: 0x2015, |
| 0x815D: 0x2010, |
| 0x815E: 0xFF0F, |
| 0x815F: 0x005C, |
| 0x8160: 0x301C, |
| 0x8161: 0x2016, |
| 0x8162: 0xFF5C, |
| 0x8163: 0x2026, |
| 0x8164: 0x2025, |
| 0x8165: 0x2018, |
| 0x8166: 0x2019, |
| 0x8167: 0x201C, |
| 0x8168: 0x201D, |
| 0x8169: 0xFF08, |
| 0x816A: 0xFF09, |
| 0x816B: 0x3014, |
| 0x816C: 0x3015, |
| 0x816D: 0xFF3B, |
| 0x816E: 0xFF3D, |
| 0x816F: 0xFF5B, |
| 0x8170: 0xFF5D, |
| 0x8171: 0x3008, |
| 0x8172: 0x3009, |
| 0x8173: 0x300A, |
| 0x8174: 0x300B, |
| 0x8175: 0x300C, |
| 0x8176: 0x300D, |
| 0x8177: 0x300E, |
| 0x8178: 0x300F, |
| 0x8179: 0x3010, |
| 0x817A: 0x3011, |
| 0x817B: 0xFF0B, |
| 0x817C: 0x2212, |
| 0x817D: 0x00B1, |
| 0x817E: 0x00D7, |
| 0x8180: 0x00F7, |
| 0x8181: 0xFF1D, |
| 0x8182: 0x2260, |
| 0x8183: 0xFF1C, |
| 0x8184: 0xFF1E, |
| 0x8185: 0x2266, |
| 0x8186: 0x2267, |
| 0x8187: 0x221E, |
| 0x8188: 0x2234, |
| 0x8189: 0x2642, |
| 0x818A: 0x2640, |
| 0x818B: 0x00B0, |
| 0x818C: 0x2032, |
| 0x818D: 0x2033, |
| 0x818E: 0x2103, |
| 0x818F: 0xFFE5, |
| 0x8190: 0xFF04, |
| 0x8191: 0x00A2, |
| 0x8192: 0x00A3, |
| 0x8193: 0xFF05, |
| 0x8194: 0xFF03, |
| 0x8195: 0xFF06, |
| 0x8196: 0xFF0A, |
| 0x8197: 0xFF20, |
| 0x8198: 0x00A7, |
| 0x8199: 0x2606, |
| 0x819A: 0x2605, |
| 0x819B: 0x25CB, |
| 0x819C: 0x25CF, |
| 0x819D: 0x25CE, |
| 0x819E: 0x25C7, |
| 0x819F: 0x25C6, |
| 0x81A0: 0x25A1, |
| 0x81A1: 0x25A0, |
| 0x81A2: 0x25B3, |
| 0x81A3: 0x25B2, |
| 0x81A4: 0x25BD, |
| 0x81A5: 0x25BC, |
| 0x81A6: 0x203B, |
| 0x81A7: 0x3012, |
| 0x81A8: 0x2192, |
| 0x81A9: 0x2190, |
| 0x81AA: 0x2191, |
| 0x81AB: 0x2193, |
| 0x81AC: 0x3013, |
| 0x81B8: 0x2208, |
| 0x81B9: 0x220B, |
| 0x81BA: 0x2286, |
| 0x81BB: 0x2287, |
| 0x81BC: 0x2282, |
| 0x81BD: 0x2283, |
| 0x81BE: 0x222A, |
| 0x81BF: 0x2229, |
| 0x81C8: 0x2227, |
| 0x81C9: 0x2228, |
| 0x81CA: 0x00AC, |
| 0x81CB: 0x21D2, |
| 0x81CC: 0x21D4, |
| 0x81CD: 0x2200, |
| 0x81CE: 0x2203, |
| 0x81DA: 0x2220, |
| 0x81DB: 0x22A5, |
| 0x81DC: 0x2312, |
| 0x81DD: 0x2202, |
| 0x81DE: 0x2207, |
| 0x81DF: 0x2261, |
| 0x81E0: 0x2252, |
| 0x81E1: 0x226A, |
| 0x81E2: 0x226B, |
| 0x81E3: 0x221A, |
| 0x81E4: 0x223D, |
| 0x81E5: 0x221D, |
| 0x81E6: 0x2235, |
| 0x81E7: 0x222B, |
| 0x81E8: 0x222C, |
| 0x81F0: 0x212B, |
| 0x81F1: 0x2030, |
| 0x81F2: 0x266F, |
| 0x81F3: 0x266D, |
| 0x81F4: 0x266A, |
| 0x81F5: 0x2020, |
| 0x81F6: 0x2021, |
| 0x81F7: 0x00B6, |
| 0x81FC: 0x25EF, |
| 0x824F: 0xFF10, |
| 0x8250: 0xFF11, |
| 0x8251: 0xFF12, |
| 0x8252: 0xFF13, |
| 0x8253: 0xFF14, |
| 0x8254: 0xFF15, |
| 0x8255: 0xFF16, |
| 0x8256: 0xFF17, |
| 0x8257: 0xFF18, |
| 0x8258: 0xFF19, |
| 0x8260: 0xFF21, |
| 0x8261: 0xFF22, |
| 0x8262: 0xFF23, |
| 0x8263: 0xFF24, |
| 0x8264: 0xFF25, |
| 0x8265: 0xFF26, |
| 0x8266: 0xFF27, |
| 0x8267: 0xFF28, |
| 0x8268: 0xFF29, |
| 0x8269: 0xFF2A, |
| 0x826A: 0xFF2B, |
| 0x826B: 0xFF2C, |
| 0x826C: 0xFF2D, |
| 0x826D: 0xFF2E, |
| 0x826E: 0xFF2F, |
| 0x826F: 0xFF30, |
| 0x8270: 0xFF31, |
| 0x8271: 0xFF32, |
| 0x8272: 0xFF33, |
| 0x8273: 0xFF34, |
| 0x8274: 0xFF35, |
| 0x8275: 0xFF36, |
| 0x8276: 0xFF37, |
| 0x8277: 0xFF38, |
| 0x8278: 0xFF39, |
| 0x8279: 0xFF3A, |
| 0x8281: 0xFF41, |
| 0x8282: 0xFF42, |
| 0x8283: 0xFF43, |
| 0x8284: 0xFF44, |
| 0x8285: 0xFF45, |
| 0x8286: 0xFF46, |
| 0x8287: 0xFF47, |
| 0x8288: 0xFF48, |
| 0x8289: 0xFF49, |
| 0x828A: 0xFF4A, |
| 0x828B: 0xFF4B, |
| 0x828C: 0xFF4C, |
| 0x828D: 0xFF4D, |
| 0x828E: 0xFF4E, |
| 0x828F: 0xFF4F, |
| 0x8290: 0xFF50, |
| 0x8291: 0xFF51, |
| 0x8292: 0xFF52, |
| 0x8293: 0xFF53, |
| 0x8294: 0xFF54, |
| 0x8295: 0xFF55, |
| 0x8296: 0xFF56, |
| 0x8297: 0xFF57, |
| 0x8298: 0xFF58, |
| 0x8299: 0xFF59, |
| 0x829A: 0xFF5A, |
| 0x829F: 0x3041, |
| 0x82A0: 0x3042, |
| 0x82A1: 0x3043, |
| 0x82A2: 0x3044, |
| 0x82A3: 0x3045, |
| 0x82A4: 0x3046, |
| 0x82A5: 0x3047, |
| 0x82A6: 0x3048, |
| 0x82A7: 0x3049, |
| 0x82A8: 0x304A, |
| 0x82A9: 0x304B, |
| 0x82AA: 0x304C, |
| 0x82AB: 0x304D, |
| 0x82AC: 0x304E, |
| 0x82AD: 0x304F, |
| 0x82AE: 0x3050, |
| 0x82AF: 0x3051, |
| 0x82B0: 0x3052, |
| 0x82B1: 0x3053, |
| 0x82B2: 0x3054, |
| 0x82B3: 0x3055, |
| 0x82B4: 0x3056, |
| 0x82B5: 0x3057, |
| 0x82B6: 0x3058, |
| 0x82B7: 0x3059, |
| 0x82B8: 0x305A, |
| 0x82B9: 0x305B, |
| 0x82BA: 0x305C, |
| 0x82BB: 0x305D, |
| 0x82BC: 0x305E, |
| 0x82BD: 0x305F, |
| 0x82BE: 0x3060, |
| 0x82BF: 0x3061, |
| 0x82C0: 0x3062, |
| 0x82C1: 0x3063, |
| 0x82C2: 0x3064, |
| 0x82C3: 0x3065, |
| 0x82C4: 0x3066, |
| 0x82C5: 0x3067, |
| 0x82C6: 0x3068, |
| 0x82C7: 0x3069, |
| 0x82C8: 0x306A, |
| 0x82C9: 0x306B, |
| 0x82CA: 0x306C, |
| 0x82CB: 0x306D, |
| 0x82CC: 0x306E, |
| 0x82CD: 0x306F, |
| 0x82CE: 0x3070, |
| 0x82CF: 0x3071, |
| 0x82D0: 0x3072, |
| 0x82D1: 0x3073, |
| 0x82D2: 0x3074, |
| 0x82D3: 0x3075, |
| 0x82D4: 0x3076, |
| 0x82D5: 0x3077, |
| 0x82D6: 0x3078, |
| 0x82D7: 0x3079, |
| 0x82D8: 0x307A, |
| 0x82D9: 0x307B, |
| 0x82DA: 0x307C, |
| 0x82DB: 0x307D, |
| 0x82DC: 0x307E, |
| 0x82DD: 0x307F, |
| 0x82DE: 0x3080, |
| 0x82DF: 0x3081, |
| 0x82E0: 0x3082, |
| 0x82E1: 0x3083, |
| 0x82E2: 0x3084, |
| 0x82E3: 0x3085, |
| 0x82E4: 0x3086, |
| 0x82E5: 0x3087, |
| 0x82E6: 0x3088, |
| 0x82E7: 0x3089, |
| 0x82E8: 0x308A, |
| 0x82E9: 0x308B, |
| 0x82EA: 0x308C, |
| 0x82EB: 0x308D, |
| 0x82EC: 0x308E, |
| 0x82ED: 0x308F, |
| 0x82EE: 0x3090, |
| 0x82EF: 0x3091, |
| 0x82F0: 0x3092, |
| 0x82F1: 0x3093, |
| 0x8340: 0x30A1, |
| 0x8341: 0x30A2, |
| 0x8342: 0x30A3, |
| 0x8343: 0x30A4, |
| 0x8344: 0x30A5, |
| 0x8345: 0x30A6, |
| 0x8346: 0x30A7, |
| 0x8347: 0x30A8, |
| 0x8348: 0x30A9, |
| 0x8349: 0x30AA, |
| 0x834A: 0x30AB, |
| 0x834B: 0x30AC, |
| 0x834C: 0x30AD, |
| 0x834D: 0x30AE, |
| 0x834E: 0x30AF, |
| 0x834F: 0x30B0, |
| 0x8350: 0x30B1, |
| 0x8351: 0x30B2, |
| 0x8352: 0x30B3, |
| 0x8353: 0x30B4, |
| 0x8354: 0x30B5, |
| 0x8355: 0x30B6, |
| 0x8356: 0x30B7, |
| 0x8357: 0x30B8, |
| 0x8358: 0x30B9, |
| 0x8359: 0x30BA, |
| 0x835A: 0x30BB, |
| 0x835B: 0x30BC, |
| 0x835C: 0x30BD, |
| 0x835D: 0x30BE, |
| 0x835E: 0x30BF, |
| 0x835F: 0x30C0, |
| 0x8360: 0x30C1, |
| 0x8361: 0x30C2, |
| 0x8362: 0x30C3, |
| 0x8363: 0x30C4, |
| 0x8364: 0x30C5, |
| 0x8365: 0x30C6, |
| 0x8366: 0x30C7, |
| 0x8367: 0x30C8, |
| 0x8368: 0x30C9, |
| 0x8369: 0x30CA, |
| 0x836A: 0x30CB, |
| 0x836B: 0x30CC, |
| 0x836C: 0x30CD, |
| 0x836D: 0x30CE, |
| 0x836E: 0x30CF, |
| 0x836F: 0x30D0, |
| 0x8370: 0x30D1, |
| 0x8371: 0x30D2, |
| 0x8372: 0x30D3, |
| 0x8373: 0x30D4, |
| 0x8374: 0x30D5, |
| 0x8375: 0x30D6, |
| 0x8376: 0x30D7, |
| 0x8377: 0x30D8, |
| 0x8378: 0x30D9, |
| 0x8379: 0x30DA, |
| 0x837A: 0x30DB, |
| 0x837B: 0x30DC, |
| 0x837C: 0x30DD, |
| 0x837D: 0x30DE, |
| 0x837E: 0x30DF, |
| 0x8380: 0x30E0, |
| 0x8381: 0x30E1, |
| 0x8382: 0x30E2, |
| 0x8383: 0x30E3, |
| 0x8384: 0x30E4, |
| 0x8385: 0x30E5, |
| 0x8386: 0x30E6, |
| 0x8387: 0x30E7, |
| 0x8388: 0x30E8, |
| 0x8389: 0x30E9, |
| 0x838A: 0x30EA, |
| 0x838B: 0x30EB, |
| 0x838C: 0x30EC, |
| 0x838D: 0x30ED, |
| 0x838E: 0x30EE, |
| 0x838F: 0x30EF, |
| 0x8390: 0x30F0, |
| 0x8391: 0x30F1, |
| 0x8392: 0x30F2, |
| 0x8393: 0x30F3, |
| 0x8394: 0x30F4, |
| 0x8395: 0x30F5, |
| 0x8396: 0x30F6, |
| 0x839F: 0x0391, |
| 0x83A0: 0x0392, |
| 0x83A1: 0x0393, |
| 0x83A2: 0x0394, |
| 0x83A3: 0x0395, |
| 0x83A4: 0x0396, |
| 0x83A5: 0x0397, |
| 0x83A6: 0x0398, |
| 0x83A7: 0x0399, |
| 0x83A8: 0x039A, |
| 0x83A9: 0x039B, |
| 0x83AA: 0x039C, |
| 0x83AB: 0x039D, |
| 0x83AC: 0x039E, |
| 0x83AD: 0x039F, |
| 0x83AE: 0x03A0, |
| 0x83AF: 0x03A1, |
| 0x83B0: 0x03A3, |
| 0x83B1: 0x03A4, |
| 0x83B2: 0x03A5, |
| 0x83B3: 0x03A6, |
| 0x83B4: 0x03A7, |
| 0x83B5: 0x03A8, |
| 0x83B6: 0x03A9, |
| 0x83BF: 0x03B1, |
| 0x83C0: 0x03B2, |
| 0x83C1: 0x03B3, |
| 0x83C2: 0x03B4, |
| 0x83C3: 0x03B5, |
| 0x83C4: 0x03B6, |
| 0x83C5: 0x03B7, |
| 0x83C6: 0x03B8, |
| 0x83C7: 0x03B9, |
| 0x83C8: 0x03BA, |
| 0x83C9: 0x03BB, |
| 0x83CA: 0x03BC, |
| 0x83CB: 0x03BD, |
| 0x83CC: 0x03BE, |
| 0x83CD: 0x03BF, |
| 0x83CE: 0x03C0, |
| 0x83CF: 0x03C1, |
| 0x83D0: 0x03C3, |
| 0x83D1: 0x03C4, |
| 0x83D2: 0x03C5, |
| 0x83D3: 0x03C6, |
| 0x83D4: 0x03C7, |
| 0x83D5: 0x03C8, |
| 0x83D6: 0x03C9, |
| 0x8440: 0x0410, |
| 0x8441: 0x0411, |
| 0x8442: 0x0412, |
| 0x8443: 0x0413, |
| 0x8444: 0x0414, |
| 0x8445: 0x0415, |
| 0x8446: 0x0401, |
| 0x8447: 0x0416, |
| 0x8448: 0x0417, |
| 0x8449: 0x0418, |
| 0x844A: 0x0419, |
| 0x844B: 0x041A, |
| 0x844C: 0x041B, |
| 0x844D: 0x041C, |
| 0x844E: 0x041D, |
| 0x844F: 0x041E, |
| 0x8450: 0x041F, |
| 0x8451: 0x0420, |
| 0x8452: 0x0421, |
| 0x8453: 0x0422, |
| 0x8454: 0x0423, |
| 0x8455: 0x0424, |
| 0x8456: 0x0425, |
| 0x8457: 0x0426, |
| 0x8458: 0x0427, |
| 0x8459: 0x0428, |
| 0x845A: 0x0429, |
| 0x845B: 0x042A, |
| 0x845C: 0x042B, |
| 0x845D: 0x042C, |
| 0x845E: 0x042D, |
| 0x845F: 0x042E, |
| 0x8460: 0x042F, |
| 0x8470: 0x0430, |
| 0x8471: 0x0431, |
| 0x8472: 0x0432, |
| 0x8473: 0x0433, |
| 0x8474: 0x0434, |
| 0x8475: 0x0435, |
| 0x8476: 0x0451, |
| 0x8477: 0x0436, |
| 0x8478: 0x0437, |
| 0x8479: 0x0438, |
| 0x847A: 0x0439, |
| 0x847B: 0x043A, |
| 0x847C: 0x043B, |
| 0x847D: 0x043C, |
| 0x847E: 0x043D, |
| 0x8480: 0x043E, |
| 0x8481: 0x043F, |
| 0x8482: 0x0440, |
| 0x8483: 0x0441, |
| 0x8484: 0x0442, |
| 0x8485: 0x0443, |
| 0x8486: 0x0444, |
| 0x8487: 0x0445, |
| 0x8488: 0x0446, |
| 0x8489: 0x0447, |
| 0x848A: 0x0448, |
| 0x848B: 0x0449, |
| 0x848C: 0x044A, |
| 0x848D: 0x044B, |
| 0x848E: 0x044C, |
| 0x848F: 0x044D, |
| 0x8490: 0x044E, |
| 0x8491: 0x044F, |
| 0x849F: 0x2500, |
| 0x84A0: 0x2502, |
| 0x84A1: 0x250C, |
| 0x84A2: 0x2510, |
| 0x84A3: 0x2518, |
| 0x84A4: 0x2514, |
| 0x84A5: 0x251C, |
| 0x84A6: 0x252C, |
| 0x84A7: 0x2524, |
| 0x84A8: 0x2534, |
| 0x84A9: 0x253C, |
| 0x84AA: 0x2501, |
| 0x84AB: 0x2503, |
| 0x84AC: 0x250F, |
| 0x84AD: 0x2513, |
| 0x84AE: 0x251B, |
| 0x84AF: 0x2517, |
| 0x84B0: 0x2523, |
| 0x84B1: 0x2533, |
| 0x84B2: 0x252B, |
| 0x84B3: 0x253B, |
| 0x84B4: 0x254B, |
| 0x84B5: 0x2520, |
| 0x84B6: 0x252F, |
| 0x84B7: 0x2528, |
| 0x84B8: 0x2537, |
| 0x84B9: 0x253F, |
| 0x84BA: 0x251D, |
| 0x84BB: 0x2530, |
| 0x84BC: 0x2525, |
| 0x84BD: 0x2538, |
| 0x84BE: 0x2542, |
| 0x889F: 0x4E9C, |
| 0x88A0: 0x5516, |
| 0x88A1: 0x5A03, |
| 0x88A2: 0x963F, |
| 0x88A3: 0x54C0, |
| 0x88A4: 0x611B, |
| 0x88A5: 0x6328, |
| 0x88A6: 0x59F6, |
| 0x88A7: 0x9022, |
| 0x88A8: 0x8475, |
| 0x88A9: 0x831C, |
| 0x88AA: 0x7A50, |
| 0x88AB: 0x60AA, |
| 0x88AC: 0x63E1, |
| 0x88AD: 0x6E25, |
| 0x88AE: 0x65ED, |
| 0x88AF: 0x8466, |
| 0x88B0: 0x82A6, |
| 0x88B1: 0x9BF5, |
| 0x88B2: 0x6893, |
| 0x88B3: 0x5727, |
| 0x88B4: 0x65A1, |
| 0x88B5: 0x6271, |
| 0x88B6: 0x5B9B, |
| 0x88B7: 0x59D0, |
| 0x88B8: 0x867B, |
| 0x88B9: 0x98F4, |
| 0x88BA: 0x7D62, |
| 0x88BB: 0x7DBE, |
| 0x88BC: 0x9B8E, |
| 0x88BD: 0x6216, |
| 0x88BE: 0x7C9F, |
| 0x88BF: 0x88B7, |
| 0x88C0: 0x5B89, |
| 0x88C1: 0x5EB5, |
| 0x88C2: 0x6309, |
| 0x88C3: 0x6697, |
| 0x88C4: 0x6848, |
| 0x88C5: 0x95C7, |
| 0x88C6: 0x978D, |
| 0x88C7: 0x674F, |
| 0x88C8: 0x4EE5, |
| 0x88C9: 0x4F0A, |
| 0x88CA: 0x4F4D, |
| 0x88CB: 0x4F9D, |
| 0x88CC: 0x5049, |
| 0x88CD: 0x56F2, |
| 0x88CE: 0x5937, |
| 0x88CF: 0x59D4, |
| 0x88D0: 0x5A01, |
| 0x88D1: 0x5C09, |
| 0x88D2: 0x60DF, |
| 0x88D3: 0x610F, |
| 0x88D4: 0x6170, |
| 0x88D5: 0x6613, |
| 0x88D6: 0x6905, |
| 0x88D7: 0x70BA, |
| 0x88D8: 0x754F, |
| 0x88D9: 0x7570, |
| 0x88DA: 0x79FB, |
| 0x88DB: 0x7DAD, |
| 0x88DC: 0x7DEF, |
| 0x88DD: 0x80C3, |
| 0x88DE: 0x840E, |
| 0x88DF: 0x8863, |
| 0x88E0: 0x8B02, |
| 0x88E1: 0x9055, |
| 0x88E2: 0x907A, |
| 0x88E3: 0x533B, |
| 0x88E4: 0x4E95, |
| 0x88E5: 0x4EA5, |
| 0x88E6: 0x57DF, |
| 0x88E7: 0x80B2, |
| 0x88E8: 0x90C1, |
| 0x88E9: 0x78EF, |
| 0x88EA: 0x4E00, |
| 0x88EB: 0x58F1, |
| 0x88EC: 0x6EA2, |
| 0x88ED: 0x9038, |
| 0x88EE: 0x7A32, |
| 0x88EF: 0x8328, |
| 0x88F0: 0x828B, |
| 0x88F1: 0x9C2F, |
| 0x88F2: 0x5141, |
| 0x88F3: 0x5370, |
| 0x88F4: 0x54BD, |
| 0x88F5: 0x54E1, |
| 0x88F6: 0x56E0, |
| 0x88F7: 0x59FB, |
| 0x88F8: 0x5F15, |
| 0x88F9: 0x98F2, |
| 0x88FA: 0x6DEB, |
| 0x88FB: 0x80E4, |
| 0x88FC: 0x852D, |
| 0x8940: 0x9662, |
| 0x8941: 0x9670, |
| 0x8942: 0x96A0, |
| 0x8943: 0x97FB, |
| 0x8944: 0x540B, |
| 0x8945: 0x53F3, |
| 0x8946: 0x5B87, |
| 0x8947: 0x70CF, |
| 0x8948: 0x7FBD, |
| 0x8949: 0x8FC2, |
| 0x894A: 0x96E8, |
| 0x894B: 0x536F, |
| 0x894C: 0x9D5C, |
| 0x894D: 0x7ABA, |
| 0x894E: 0x4E11, |
| 0x894F: 0x7893, |
| 0x8950: 0x81FC, |
| 0x8951: 0x6E26, |
| 0x8952: 0x5618, |
| 0x8953: 0x5504, |
| 0x8954: 0x6B1D, |
| 0x8955: 0x851A, |
| 0x8956: 0x9C3B, |
| 0x8957: 0x59E5, |
| 0x8958: 0x53A9, |
| 0x8959: 0x6D66, |
| 0x895A: 0x74DC, |
| 0x895B: 0x958F, |
| 0x895C: 0x5642, |
| 0x895D: 0x4E91, |
| 0x895E: 0x904B, |
| 0x895F: 0x96F2, |
| 0x8960: 0x834F, |
| 0x8961: 0x990C, |
| 0x8962: 0x53E1, |
| 0x8963: 0x55B6, |
| 0x8964: 0x5B30, |
| 0x8965: 0x5F71, |
| 0x8966: 0x6620, |
| 0x8967: 0x66F3, |
| 0x8968: 0x6804, |
| 0x8969: 0x6C38, |
| 0x896A: 0x6CF3, |
| 0x896B: 0x6D29, |
| 0x896C: 0x745B, |
| 0x896D: 0x76C8, |
| 0x896E: 0x7A4E, |
| 0x896F: 0x9834, |
| 0x8970: 0x82F1, |
| 0x8971: 0x885B, |
| 0x8972: 0x8A60, |
| 0x8973: 0x92ED, |
| 0x8974: 0x6DB2, |
| 0x8975: 0x75AB, |
| 0x8976: 0x76CA, |
| 0x8977: 0x99C5, |
| 0x8978: 0x60A6, |
| 0x8979: 0x8B01, |
| 0x897A: 0x8D8A, |
| 0x897B: 0x95B2, |
| 0x897C: 0x698E, |
| 0x897D: 0x53AD, |
| 0x897E: 0x5186, |
| 0x8980: 0x5712, |
| 0x8981: 0x5830, |
| 0x8982: 0x5944, |
| 0x8983: 0x5BB4, |
| 0x8984: 0x5EF6, |
| 0x8985: 0x6028, |
| 0x8986: 0x63A9, |
| 0x8987: 0x63F4, |
| 0x8988: 0x6CBF, |
| 0x8989: 0x6F14, |
| 0x898A: 0x708E, |
| 0x898B: 0x7114, |
| 0x898C: 0x7159, |
| 0x898D: 0x71D5, |
| 0x898E: 0x733F, |
| 0x898F: 0x7E01, |
| 0x8990: 0x8276, |
| 0x8991: 0x82D1, |
| 0x8992: 0x8597, |
| 0x8993: 0x9060, |
| 0x8994: 0x925B, |
| 0x8995: 0x9D1B, |
| 0x8996: 0x5869, |
| 0x8997: 0x65BC, |
| 0x8998: 0x6C5A, |
| 0x8999: 0x7525, |
| 0x899A: 0x51F9, |
| 0x899B: 0x592E, |
| 0x899C: 0x5965, |
| 0x899D: 0x5F80, |
| 0x899E: 0x5FDC, |
| 0x899F: 0x62BC, |
| 0x89A0: 0x65FA, |
| 0x89A1: 0x6A2A, |
| 0x89A2: 0x6B27, |
| 0x89A3: 0x6BB4, |
| 0x89A4: 0x738B, |
| 0x89A5: 0x7FC1, |
| 0x89A6: 0x8956, |
| 0x89A7: 0x9D2C, |
| 0x89A8: 0x9D0E, |
| 0x89A9: 0x9EC4, |
| 0x89AA: 0x5CA1, |
| 0x89AB: 0x6C96, |
| 0x89AC: 0x837B, |
| 0x89AD: 0x5104, |
| 0x89AE: 0x5C4B, |
| 0x89AF: 0x61B6, |
| 0x89B0: 0x81C6, |
| 0x89B1: 0x6876, |
| 0x89B2: 0x7261, |
| 0x89B3: 0x4E59, |
| 0x89B4: 0x4FFA, |
| 0x89B5: 0x5378, |
| 0x89B6: 0x6069, |
| 0x89B7: 0x6E29, |
| 0x89B8: 0x7A4F, |
| 0x89B9: 0x97F3, |
| 0x89BA: 0x4E0B, |
| 0x89BB: 0x5316, |
| 0x89BC: 0x4EEE, |
| 0x89BD: 0x4F55, |
| 0x89BE: 0x4F3D, |
| 0x89BF: 0x4FA1, |
| 0x89C0: 0x4F73, |
| 0x89C1: 0x52A0, |
| 0x89C2: 0x53EF, |
| 0x89C3: 0x5609, |
| 0x89C4: 0x590F, |
| 0x89C5: 0x5AC1, |
| 0x89C6: 0x5BB6, |
| 0x89C7: 0x5BE1, |
| 0x89C8: 0x79D1, |
| 0x89C9: 0x6687, |
| 0x89CA: 0x679C, |
| 0x89CB: 0x67B6, |
| 0x89CC: 0x6B4C, |
| 0x89CD: 0x6CB3, |
| 0x89CE: 0x706B, |
| 0x89CF: 0x73C2, |
| 0x89D0: 0x798D, |
| 0x89D1: 0x79BE, |
| 0x89D2: 0x7A3C, |
| 0x89D3: 0x7B87, |
| 0x89D4: 0x82B1, |
| 0x89D5: 0x82DB, |
| 0x89D6: 0x8304, |
| 0x89D7: 0x8377, |
| 0x89D8: 0x83EF, |
| 0x89D9: 0x83D3, |
| 0x89DA: 0x8766, |
| 0x89DB: 0x8AB2, |
| 0x89DC: 0x5629, |
| 0x89DD: 0x8CA8, |
| 0x89DE: 0x8FE6, |
| 0x89DF: 0x904E, |
| 0x89E0: 0x971E, |
| 0x89E1: 0x868A, |
| 0x89E2: 0x4FC4, |
| 0x89E3: 0x5CE8, |
| 0x89E4: 0x6211, |
| 0x89E5: 0x7259, |
| 0x89E6: 0x753B, |
| 0x89E7: 0x81E5, |
| 0x89E8: 0x82BD, |
| 0x89E9: 0x86FE, |
| 0x89EA: 0x8CC0, |
| 0x89EB: 0x96C5, |
| 0x89EC: 0x9913, |
| 0x89ED: 0x99D5, |
| 0x89EE: 0x4ECB, |
| 0x89EF: 0x4F1A, |
| 0x89F0: 0x89E3, |
| 0x89F1: 0x56DE, |
| 0x89F2: 0x584A, |
| 0x89F3: 0x58CA, |
| 0x89F4: 0x5EFB, |
| 0x89F5: 0x5FEB, |
| 0x89F6: 0x602A, |
| 0x89F7: 0x6094, |
| 0x89F8: 0x6062, |
| 0x89F9: 0x61D0, |
| 0x89FA: 0x6212, |
| 0x89FB: 0x62D0, |
| 0x89FC: 0x6539, |
| 0x8A40: 0x9B41, |
| 0x8A41: 0x6666, |
| 0x8A42: 0x68B0, |
| 0x8A43: 0x6D77, |
| 0x8A44: 0x7070, |
| 0x8A45: 0x754C, |
| 0x8A46: 0x7686, |
| 0x8A47: 0x7D75, |
| 0x8A48: 0x82A5, |
| 0x8A49: 0x87F9, |
| 0x8A4A: 0x958B, |
| 0x8A4B: 0x968E, |
| 0x8A4C: 0x8C9D, |
| 0x8A4D: 0x51F1, |
| 0x8A4E: 0x52BE, |
| 0x8A4F: 0x5916, |
| 0x8A50: 0x54B3, |
| 0x8A51: 0x5BB3, |
| 0x8A52: 0x5D16, |
| 0x8A53: 0x6168, |
| 0x8A54: 0x6982, |
| 0x8A55: 0x6DAF, |
| 0x8A56: 0x788D, |
| 0x8A57: 0x84CB, |
| 0x8A58: 0x8857, |
| 0x8A59: 0x8A72, |
| 0x8A5A: 0x93A7, |
| 0x8A5B: 0x9AB8, |
| 0x8A5C: 0x6D6C, |
| 0x8A5D: 0x99A8, |
| 0x8A5E: 0x86D9, |
| 0x8A5F: 0x57A3, |
| 0x8A60: 0x67FF, |
| 0x8A61: 0x86CE, |
| 0x8A62: 0x920E, |
| 0x8A63: 0x5283, |
| 0x8A64: 0x5687, |
| 0x8A65: 0x5404, |
| 0x8A66: 0x5ED3, |
| 0x8A67: 0x62E1, |
| 0x8A68: 0x64B9, |
| 0x8A69: 0x683C, |
| 0x8A6A: 0x6838, |
| 0x8A6B: 0x6BBB, |
| 0x8A6C: 0x7372, |
| 0x8A6D: 0x78BA, |
| 0x8A6E: 0x7A6B, |
| 0x8A6F: 0x899A, |
| 0x8A70: 0x89D2, |
| 0x8A71: 0x8D6B, |
| 0x8A72: 0x8F03, |
| 0x8A73: 0x90ED, |
| 0x8A74: 0x95A3, |
| 0x8A75: 0x9694, |
| 0x8A76: 0x9769, |
| 0x8A77: 0x5B66, |
| 0x8A78: 0x5CB3, |
| 0x8A79: 0x697D, |
| 0x8A7A: 0x984D, |
| 0x8A7B: 0x984E, |
| 0x8A7C: 0x639B, |
| 0x8A7D: 0x7B20, |
| 0x8A7E: 0x6A2B, |
| 0x8A80: 0x6A7F, |
| 0x8A81: 0x68B6, |
| 0x8A82: 0x9C0D, |
| 0x8A83: 0x6F5F, |
| 0x8A84: 0x5272, |
| 0x8A85: 0x559D, |
| 0x8A86: 0x6070, |
| 0x8A87: 0x62EC, |
| 0x8A88: 0x6D3B, |
| 0x8A89: 0x6E07, |
| 0x8A8A: 0x6ED1, |
| 0x8A8B: 0x845B, |
| 0x8A8C: 0x8910, |
| 0x8A8D: 0x8F44, |
| 0x8A8E: 0x4E14, |
| 0x8A8F: 0x9C39, |
| 0x8A90: 0x53F6, |
| 0x8A91: 0x691B, |
| 0x8A92: 0x6A3A, |
| 0x8A93: 0x9784, |
| 0x8A94: 0x682A, |
| 0x8A95: 0x515C, |
| 0x8A96: 0x7AC3, |
| 0x8A97: 0x84B2, |
| 0x8A98: 0x91DC, |
| 0x8A99: 0x938C, |
| 0x8A9A: 0x565B, |
| 0x8A9B: 0x9D28, |
| 0x8A9C: 0x6822, |
| 0x8A9D: 0x8305, |
| 0x8A9E: 0x8431, |
| 0x8A9F: 0x7CA5, |
| 0x8AA0: 0x5208, |
| 0x8AA1: 0x82C5, |
| 0x8AA2: 0x74E6, |
| 0x8AA3: 0x4E7E, |
| 0x8AA4: 0x4F83, |
| 0x8AA5: 0x51A0, |
| 0x8AA6: 0x5BD2, |
| 0x8AA7: 0x520A, |
| 0x8AA8: 0x52D8, |
| 0x8AA9: 0x52E7, |
| 0x8AAA: 0x5DFB, |
| 0x8AAB: 0x559A, |
| 0x8AAC: 0x582A, |
| 0x8AAD: 0x59E6, |
| 0x8AAE: 0x5B8C, |
| 0x8AAF: 0x5B98, |
| 0x8AB0: 0x5BDB, |
| 0x8AB1: 0x5E72, |
| 0x8AB2: 0x5E79, |
| 0x8AB3: 0x60A3, |
| 0x8AB4: 0x611F, |
| 0x8AB5: 0x6163, |
| 0x8AB6: 0x61BE, |
| 0x8AB7: 0x63DB, |
| 0x8AB8: 0x6562, |
| 0x8AB9: 0x67D1, |
| 0x8ABA: 0x6853, |
| 0x8ABB: 0x68FA, |
| 0x8ABC: 0x6B3E, |
| 0x8ABD: 0x6B53, |
| 0x8ABE: 0x6C57, |
| 0x8ABF: 0x6F22, |
| 0x8AC0: 0x6F97, |
| 0x8AC1: 0x6F45, |
| 0x8AC2: 0x74B0, |
| 0x8AC3: 0x7518, |
| 0x8AC4: 0x76E3, |
| 0x8AC5: 0x770B, |
| 0x8AC6: 0x7AFF, |
| 0x8AC7: 0x7BA1, |
| 0x8AC8: 0x7C21, |
| 0x8AC9: 0x7DE9, |
| 0x8ACA: 0x7F36, |
| 0x8ACB: 0x7FF0, |
| 0x8ACC: 0x809D, |
| 0x8ACD: 0x8266, |
| 0x8ACE: 0x839E, |
| 0x8ACF: 0x89B3, |
| 0x8AD0: 0x8ACC, |
| 0x8AD1: 0x8CAB, |
| 0x8AD2: 0x9084, |
| 0x8AD3: 0x9451, |
| 0x8AD4: 0x9593, |
| 0x8AD5: 0x9591, |
| 0x8AD6: 0x95A2, |
| 0x8AD7: 0x9665, |
| 0x8AD8: 0x97D3, |
| 0x8AD9: 0x9928, |
| 0x8ADA: 0x8218, |
| 0x8ADB: 0x4E38, |
| 0x8ADC: 0x542B, |
| 0x8ADD: 0x5CB8, |
| 0x8ADE: 0x5DCC, |
| 0x8ADF: 0x73A9, |
| 0x8AE0: 0x764C, |
| 0x8AE1: 0x773C, |
| 0x8AE2: 0x5CA9, |
| 0x8AE3: 0x7FEB, |
| 0x8AE4: 0x8D0B, |
| 0x8AE5: 0x96C1, |
| 0x8AE6: 0x9811, |
| 0x8AE7: 0x9854, |
| 0x8AE8: 0x9858, |
| 0x8AE9: 0x4F01, |
| 0x8AEA: 0x4F0E, |
| 0x8AEB: 0x5371, |
| 0x8AEC: 0x559C, |
| 0x8AED: 0x5668, |
| 0x8AEE: 0x57FA, |
| 0x8AEF: 0x5947, |
| 0x8AF0: 0x5B09, |
| 0x8AF1: 0x5BC4, |
| 0x8AF2: 0x5C90, |
| 0x8AF3: 0x5E0C, |
| 0x8AF4: 0x5E7E, |
| 0x8AF5: 0x5FCC, |
| 0x8AF6: 0x63EE, |
| 0x8AF7: 0x673A, |
| 0x8AF8: 0x65D7, |
| 0x8AF9: 0x65E2, |
| 0x8AFA: 0x671F, |
| 0x8AFB: 0x68CB, |
| 0x8AFC: 0x68C4, |
| 0x8B40: 0x6A5F, |
| 0x8B41: 0x5E30, |
| 0x8B42: 0x6BC5, |
| 0x8B43: 0x6C17, |
| 0x8B44: 0x6C7D, |
| 0x8B45: 0x757F, |
| 0x8B46: 0x7948, |
| 0x8B47: 0x5B63, |
| 0x8B48: 0x7A00, |
| 0x8B49: 0x7D00, |
| 0x8B4A: 0x5FBD, |
| 0x8B4B: 0x898F, |
| 0x8B4C: 0x8A18, |
| 0x8B4D: 0x8CB4, |
| 0x8B4E: 0x8D77, |
| 0x8B4F: 0x8ECC, |
| 0x8B50: 0x8F1D, |
| 0x8B51: 0x98E2, |
| 0x8B52: 0x9A0E, |
| 0x8B53: 0x9B3C, |
| 0x8B54: 0x4E80, |
| 0x8B55: 0x507D, |
| 0x8B56: 0x5100, |
| 0x8B57: 0x5993, |
| 0x8B58: 0x5B9C, |
| 0x8B59: 0x622F, |
| 0x8B5A: 0x6280, |
| 0x8B5B: 0x64EC, |
| 0x8B5C: 0x6B3A, |
| 0x8B5D: 0x72A0, |
| 0x8B5E: 0x7591, |
| 0x8B5F: 0x7947, |
| 0x8B60: 0x7FA9, |
| 0x8B61: 0x87FB, |
| 0x8B62: 0x8ABC, |
| 0x8B63: 0x8B70, |
| 0x8B64: 0x63AC, |
| 0x8B65: 0x83CA, |
| 0x8B66: 0x97A0, |
| 0x8B67: 0x5409, |
| 0x8B68: 0x5403, |
| 0x8B69: 0x55AB, |
| 0x8B6A: 0x6854, |
| 0x8B6B: 0x6A58, |
| 0x8B6C: 0x8A70, |
| 0x8B6D: 0x7827, |
| 0x8B6E: 0x6775, |
| 0x8B6F: 0x9ECD, |
| 0x8B70: 0x5374, |
| 0x8B71: 0x5BA2, |
| 0x8B72: 0x811A, |
| 0x8B73: 0x8650, |
| 0x8B74: 0x9006, |
| 0x8B75: 0x4E18, |
| 0x8B76: 0x4E45, |
| 0x8B77: 0x4EC7, |
| 0x8B78: 0x4F11, |
| 0x8B79: 0x53CA, |
| 0x8B7A: 0x5438, |
| 0x8B7B: 0x5BAE, |
| 0x8B7C: 0x5F13, |
| 0x8B7D: 0x6025, |
| 0x8B7E: 0x6551, |
| 0x8B80: 0x673D, |
| 0x8B81: 0x6C42, |
| 0x8B82: 0x6C72, |
| 0x8B83: 0x6CE3, |
| 0x8B84: 0x7078, |
| 0x8B85: 0x7403, |
| 0x8B86: 0x7A76, |
| 0x8B87: 0x7AAE, |
| 0x8B88: 0x7B08, |
| 0x8B89: 0x7D1A, |
| 0x8B8A: 0x7CFE, |
| 0x8B8B: 0x7D66, |
| 0x8B8C: 0x65E7, |
| 0x8B8D: 0x725B, |
| 0x8B8E: 0x53BB, |
| 0x8B8F: 0x5C45, |
| 0x8B90: 0x5DE8, |
| 0x8B91: 0x62D2, |
| 0x8B92: 0x62E0, |
| 0x8B93: 0x6319, |
| 0x8B94: 0x6E20, |
| 0x8B95: 0x865A, |
| 0x8B96: 0x8A31, |
| 0x8B97: 0x8DDD, |
| 0x8B98: 0x92F8, |
| 0x8B99: 0x6F01, |
| 0x8B9A: 0x79A6, |
| 0x8B9B: 0x9B5A, |
| 0x8B9C: 0x4EA8, |
| 0x8B9D: 0x4EAB, |
| 0x8B9E: 0x4EAC, |
| 0x8B9F: 0x4F9B, |
| 0x8BA0: 0x4FA0, |
| 0x8BA1: 0x50D1, |
| 0x8BA2: 0x5147, |
| 0x8BA3: 0x7AF6, |
| 0x8BA4: 0x5171, |
| 0x8BA5: 0x51F6, |
| 0x8BA6: 0x5354, |
| 0x8BA7: 0x5321, |
| 0x8BA8: 0x537F, |
| 0x8BA9: 0x53EB, |
| 0x8BAA: 0x55AC, |
| 0x8BAB: 0x5883, |
| 0x8BAC: 0x5CE1, |
| 0x8BAD: 0x5F37, |
| 0x8BAE: 0x5F4A, |
| 0x8BAF: 0x602F, |
| 0x8BB0: 0x6050, |
| 0x8BB1: 0x606D, |
| 0x8BB2: 0x631F, |
| 0x8BB3: 0x6559, |
| 0x8BB4: 0x6A4B, |
| 0x8BB5: 0x6CC1, |
| 0x8BB6: 0x72C2, |
| 0x8BB7: 0x72ED, |
| 0x8BB8: 0x77EF, |
| 0x8BB9: 0x80F8, |
| 0x8BBA: 0x8105, |
| 0x8BBB: 0x8208, |
| 0x8BBC: 0x854E, |
| 0x8BBD: 0x90F7, |
| 0x8BBE: 0x93E1, |
| 0x8BBF: 0x97FF, |
| 0x8BC0: 0x9957, |
| 0x8BC1: 0x9A5A, |
| 0x8BC2: 0x4EF0, |
| 0x8BC3: 0x51DD, |
| 0x8BC4: 0x5C2D, |
| 0x8BC5: 0x6681, |
| 0x8BC6: 0x696D, |
| 0x8BC7: 0x5C40, |
| 0x8BC8: 0x66F2, |
| 0x8BC9: 0x6975, |
| 0x8BCA: 0x7389, |
| 0x8BCB: 0x6850, |
| 0x8BCC: 0x7C81, |
| 0x8BCD: 0x50C5, |
| 0x8BCE: 0x52E4, |
| 0x8BCF: 0x5747, |
| 0x8BD0: 0x5DFE, |
| 0x8BD1: 0x9326, |
| 0x8BD2: 0x65A4, |
| 0x8BD3: 0x6B23, |
| 0x8BD4: 0x6B3D, |
| 0x8BD5: 0x7434, |
| 0x8BD6: 0x7981, |
| 0x8BD7: 0x79BD, |
| 0x8BD8: 0x7B4B, |
| 0x8BD9: 0x7DCA, |
| 0x8BDA: 0x82B9, |
| 0x8BDB: 0x83CC, |
| 0x8BDC: 0x887F, |
| 0x8BDD: 0x895F, |
| 0x8BDE: 0x8B39, |
| 0x8BDF: 0x8FD1, |
| 0x8BE0: 0x91D1, |
| 0x8BE1: 0x541F, |
| 0x8BE2: 0x9280, |
| 0x8BE3: 0x4E5D, |
| 0x8BE4: 0x5036, |
| 0x8BE5: 0x53E5, |
| 0x8BE6: 0x533A, |
| 0x8BE7: 0x72D7, |
| 0x8BE8: 0x7396, |
| 0x8BE9: 0x77E9, |
| 0x8BEA: 0x82E6, |
| 0x8BEB: 0x8EAF, |
| 0x8BEC: 0x99C6, |
| 0x8BED: 0x99C8, |
| 0x8BEE: 0x99D2, |
| 0x8BEF: 0x5177, |
| 0x8BF0: 0x611A, |
| 0x8BF1: 0x865E, |
| 0x8BF2: 0x55B0, |
| 0x8BF3: 0x7A7A, |
| 0x8BF4: 0x5076, |
| 0x8BF5: 0x5BD3, |
| 0x8BF6: 0x9047, |
| 0x8BF7: 0x9685, |
| 0x8BF8: 0x4E32, |
| 0x8BF9: 0x6ADB, |
| 0x8BFA: 0x91E7, |
| 0x8BFB: 0x5C51, |
| 0x8BFC: 0x5C48, |
| 0x8C40: 0x6398, |
| 0x8C41: 0x7A9F, |
| 0x8C42: 0x6C93, |
| 0x8C43: 0x9774, |
| 0x8C44: 0x8F61, |
| 0x8C45: 0x7AAA, |
| 0x8C46: 0x718A, |
| 0x8C47: 0x9688, |
| 0x8C48: 0x7C82, |
| 0x8C49: 0x6817, |
| 0x8C4A: 0x7E70, |
| 0x8C4B: 0x6851, |
| 0x8C4C: 0x936C, |
| 0x8C4D: 0x52F2, |
| 0x8C4E: 0x541B, |
| 0x8C4F: 0x85AB, |
| 0x8C50: 0x8A13, |
| 0x8C51: 0x7FA4, |
| 0x8C52: 0x8ECD, |
| 0x8C53: 0x90E1, |
| 0x8C54: 0x5366, |
| 0x8C55: 0x8888, |
| 0x8C56: 0x7941, |
| 0x8C57: 0x4FC2, |
| 0x8C58: 0x50BE, |
| 0x8C59: 0x5211, |
| 0x8C5A: 0x5144, |
| 0x8C5B: 0x5553, |
| 0x8C5C: 0x572D, |
| 0x8C5D: 0x73EA, |
| 0x8C5E: 0x578B, |
| 0x8C5F: 0x5951, |
| 0x8C60: 0x5F62, |
| 0x8C61: 0x5F84, |
| 0x8C62: 0x6075, |
| 0x8C63: 0x6176, |
| 0x8C64: 0x6167, |
| 0x8C65: 0x61A9, |
| 0x8C66: 0x63B2, |
| 0x8C67: 0x643A, |
| 0x8C68: 0x656C, |
| 0x8C69: 0x666F, |
| 0x8C6A: 0x6842, |
| 0x8C6B: 0x6E13, |
| 0x8C6C: 0x7566, |
| 0x8C6D: 0x7A3D, |
| 0x8C6E: 0x7CFB, |
| 0x8C6F: 0x7D4C, |
| 0x8C70: 0x7D99, |
| 0x8C71: 0x7E4B, |
| 0x8C72: 0x7F6B, |
| 0x8C73: 0x830E, |
| 0x8C74: 0x834A, |
| 0x8C75: 0x86CD, |
| 0x8C76: 0x8A08, |
| 0x8C77: 0x8A63, |
| 0x8C78: 0x8B66, |
| 0x8C79: 0x8EFD, |
| 0x8C7A: 0x981A, |
| 0x8C7B: 0x9D8F, |
| 0x8C7C: 0x82B8, |
| 0x8C7D: 0x8FCE, |
| 0x8C7E: 0x9BE8, |
| 0x8C80: 0x5287, |
| 0x8C81: 0x621F, |
| 0x8C82: 0x6483, |
| 0x8C83: 0x6FC0, |
| 0x8C84: 0x9699, |
| 0x8C85: 0x6841, |
| 0x8C86: 0x5091, |
| 0x8C87: 0x6B20, |
| 0x8C88: 0x6C7A, |
| 0x8C89: 0x6F54, |
| 0x8C8A: 0x7A74, |
| 0x8C8B: 0x7D50, |
| 0x8C8C: 0x8840, |
| 0x8C8D: 0x8A23, |
| 0x8C8E: 0x6708, |
| 0x8C8F: 0x4EF6, |
| 0x8C90: 0x5039, |
| 0x8C91: 0x5026, |
| 0x8C92: 0x5065, |
| 0x8C93: 0x517C, |
| 0x8C94: 0x5238, |
| 0x8C95: 0x5263, |
| 0x8C96: 0x55A7, |
| 0x8C97: 0x570F, |
| 0x8C98: 0x5805, |
| 0x8C99: 0x5ACC, |
| 0x8C9A: 0x5EFA, |
| 0x8C9B: 0x61B2, |
| 0x8C9C: 0x61F8, |
| 0x8C9D: 0x62F3, |
| 0x8C9E: 0x6372, |
| 0x8C9F: 0x691C, |
| 0x8CA0: 0x6A29, |
| 0x8CA1: 0x727D, |
| 0x8CA2: 0x72AC, |
| 0x8CA3: 0x732E, |
| 0x8CA4: 0x7814, |
| 0x8CA5: 0x786F, |
| 0x8CA6: 0x7D79, |
| 0x8CA7: 0x770C, |
| 0x8CA8: 0x80A9, |
| 0x8CA9: 0x898B, |
| 0x8CAA: 0x8B19, |
| 0x8CAB: 0x8CE2, |
| 0x8CAC: 0x8ED2, |
| 0x8CAD: 0x9063, |
| 0x8CAE: 0x9375, |
| 0x8CAF: 0x967A, |
| 0x8CB0: 0x9855, |
| 0x8CB1: 0x9A13, |
| 0x8CB2: 0x9E78, |
| 0x8CB3: 0x5143, |
| 0x8CB4: 0x539F, |
| 0x8CB5: 0x53B3, |
| 0x8CB6: 0x5E7B, |
| 0x8CB7: 0x5F26, |
| 0x8CB8: 0x6E1B, |
| 0x8CB9: 0x6E90, |
| 0x8CBA: 0x7384, |
| 0x8CBB: 0x73FE, |
| 0x8CBC: 0x7D43, |
| 0x8CBD: 0x8237, |
| 0x8CBE: 0x8A00, |
| 0x8CBF: 0x8AFA, |
| 0x8CC0: 0x9650, |
| 0x8CC1: 0x4E4E, |
| 0x8CC2: 0x500B, |
| 0x8CC3: 0x53E4, |
| 0x8CC4: 0x547C, |
| 0x8CC5: 0x56FA, |
| 0x8CC6: 0x59D1, |
| 0x8CC7: 0x5B64, |
| 0x8CC8: 0x5DF1, |
| 0x8CC9: 0x5EAB, |
| 0x8CCA: 0x5F27, |
| 0x8CCB: 0x6238, |
| 0x8CCC: 0x6545, |
| 0x8CCD: 0x67AF, |
| 0x8CCE: 0x6E56, |
| 0x8CCF: 0x72D0, |
| 0x8CD0: 0x7CCA, |
| 0x8CD1: 0x88B4, |
| 0x8CD2: 0x80A1, |
| 0x8CD3: 0x80E1, |
| 0x8CD4: 0x83F0, |
| 0x8CD5: 0x864E, |
| 0x8CD6: 0x8A87, |
| 0x8CD7: 0x8DE8, |
| 0x8CD8: 0x9237, |
| 0x8CD9: 0x96C7, |
| 0x8CDA: 0x9867, |
| 0x8CDB: 0x9F13, |
| 0x8CDC: 0x4E94, |
| 0x8CDD: 0x4E92, |
| 0x8CDE: 0x4F0D, |
| 0x8CDF: 0x5348, |
| 0x8CE0: 0x5449, |
| 0x8CE1: 0x543E, |
| 0x8CE2: 0x5A2F, |
| 0x8CE3: 0x5F8C, |
| 0x8CE4: 0x5FA1, |
| 0x8CE5: 0x609F, |
| 0x8CE6: 0x68A7, |
| 0x8CE7: 0x6A8E, |
| 0x8CE8: 0x745A, |
| 0x8CE9: 0x7881, |
| 0x8CEA: 0x8A9E, |
| 0x8CEB: 0x8AA4, |
| 0x8CEC: 0x8B77, |
| 0x8CED: 0x9190, |
| 0x8CEE: 0x4E5E, |
| 0x8CEF: 0x9BC9, |
| 0x8CF0: 0x4EA4, |
| 0x8CF1: 0x4F7C, |
| 0x8CF2: 0x4FAF, |
| 0x8CF3: 0x5019, |
| 0x8CF4: 0x5016, |
| 0x8CF5: 0x5149, |
| 0x8CF6: 0x516C, |
| 0x8CF7: 0x529F, |
| 0x8CF8: 0x52B9, |
| 0x8CF9: 0x52FE, |
| 0x8CFA: 0x539A, |
| 0x8CFB: 0x53E3, |
| 0x8CFC: 0x5411, |
| 0x8D40: 0x540E, |
| 0x8D41: 0x5589, |
| 0x8D42: 0x5751, |
| 0x8D43: 0x57A2, |
| 0x8D44: 0x597D, |
| 0x8D45: 0x5B54, |
| 0x8D46: 0x5B5D, |
| 0x8D47: 0x5B8F, |
| 0x8D48: 0x5DE5, |
| 0x8D49: 0x5DE7, |
| 0x8D4A: 0x5DF7, |
| 0x8D4B: 0x5E78, |
| 0x8D4C: 0x5E83, |
| 0x8D4D: 0x5E9A, |
| 0x8D4E: 0x5EB7, |
| 0x8D4F: 0x5F18, |
| 0x8D50: 0x6052, |
| 0x8D51: 0x614C, |
| 0x8D52: 0x6297, |
| 0x8D53: 0x62D8, |
| 0x8D54: 0x63A7, |
| 0x8D55: 0x653B, |
| 0x8D56: 0x6602, |
| 0x8D57: 0x6643, |
| 0x8D58: 0x66F4, |
| 0x8D59: 0x676D, |
| 0x8D5A: 0x6821, |
| 0x8D5B: 0x6897, |
| 0x8D5C: 0x69CB, |
| 0x8D5D: 0x6C5F, |
| 0x8D5E: 0x6D2A, |
| 0x8D5F: 0x6D69, |
| 0x8D60: 0x6E2F, |
| 0x8D61: 0x6E9D, |
| 0x8D62: 0x7532, |
| 0x8D63: 0x7687, |
| 0x8D64: 0x786C, |
| 0x8D65: 0x7A3F, |
| 0x8D66: 0x7CE0, |
| 0x8D67: 0x7D05, |
| 0x8D68: 0x7D18, |
| 0x8D69: 0x7D5E, |
| 0x8D6A: 0x7DB1, |
| 0x8D6B: 0x8015, |
| 0x8D6C: 0x8003, |
| 0x8D6D: 0x80AF, |
| 0x8D6E: 0x80B1, |
| 0x8D6F: 0x8154, |
| 0x8D70: 0x818F, |
| 0x8D71: 0x822A, |
| 0x8D72: 0x8352, |
| 0x8D73: 0x884C, |
| 0x8D74: 0x8861, |
| 0x8D75: 0x8B1B, |
| 0x8D76: 0x8CA2, |
| 0x8D77: 0x8CFC, |
| 0x8D78: 0x90CA, |
| 0x8D79: 0x9175, |
| 0x8D7A: 0x9271, |
| 0x8D7B: 0x783F, |
| 0x8D7C: 0x92FC, |
| 0x8D7D: 0x95A4, |
| 0x8D7E: 0x964D, |
| 0x8D80: 0x9805, |
| 0x8D81: 0x9999, |
| 0x8D82: 0x9AD8, |
| 0x8D83: 0x9D3B, |
| 0x8D84: 0x525B, |
| 0x8D85: 0x52AB, |
| 0x8D86: 0x53F7, |
| 0x8D87: 0x5408, |
| 0x8D88: 0x58D5, |
| 0x8D89: 0x62F7, |
| 0x8D8A: 0x6FE0, |
| 0x8D8B: 0x8C6A, |
| 0x8D8C: 0x8F5F, |
| 0x8D8D: 0x9EB9, |
| 0x8D8E: 0x514B, |
| 0x8D8F: 0x523B, |
| 0x8D90: 0x544A, |
| 0x8D91: 0x56FD, |
| 0x8D92: 0x7A40, |
| 0x8D93: 0x9177, |
| 0x8D94: 0x9D60, |
| 0x8D95: 0x9ED2, |
| 0x8D96: 0x7344, |
| 0x8D97: 0x6F09, |
| 0x8D98: 0x8170, |
| 0x8D99: 0x7511, |
| 0x8D9A: 0x5FFD, |
| 0x8D9B: 0x60DA, |
| 0x8D9C: 0x9AA8, |
| 0x8D9D: 0x72DB, |
| 0x8D9E: 0x8FBC, |
| 0x8D9F: 0x6B64, |
| 0x8DA0: 0x9803, |
| 0x8DA1: 0x4ECA, |
| 0x8DA2: 0x56F0, |
| 0x8DA3: 0x5764, |
| 0x8DA4: 0x58BE, |
| 0x8DA5: 0x5A5A, |
| 0x8DA6: 0x6068, |
| 0x8DA7: 0x61C7, |
| 0x8DA8: 0x660F, |
| 0x8DA9: 0x6606, |
| 0x8DAA: 0x6839, |
| 0x8DAB: 0x68B1, |
| 0x8DAC: 0x6DF7, |
| 0x8DAD: 0x75D5, |
| 0x8DAE: 0x7D3A, |
| 0x8DAF: 0x826E, |
| 0x8DB0: 0x9B42, |
| 0x8DB1: 0x4E9B, |
| 0x8DB2: 0x4F50, |
| 0x8DB3: 0x53C9, |
| 0x8DB4: 0x5506, |
| 0x8DB5: 0x5D6F, |
| 0x8DB6: 0x5DE6, |
| 0x8DB7: 0x5DEE, |
| 0x8DB8: 0x67FB, |
| 0x8DB9: 0x6C99, |
| 0x8DBA: 0x7473, |
| 0x8DBB: 0x7802, |
| 0x8DBC: 0x8A50, |
| 0x8DBD: 0x9396, |
| 0x8DBE: 0x88DF, |
| 0x8DBF: 0x5750, |
| 0x8DC0: 0x5EA7, |
| 0x8DC1: 0x632B, |
| 0x8DC2: 0x50B5, |
| 0x8DC3: 0x50AC, |
| 0x8DC4: 0x518D, |
| 0x8DC5: 0x6700, |
| 0x8DC6: 0x54C9, |
| 0x8DC7: 0x585E, |
| 0x8DC8: 0x59BB, |
| 0x8DC9: 0x5BB0, |
| 0x8DCA: 0x5F69, |
| 0x8DCB: 0x624D, |
| 0x8DCC: 0x63A1, |
| 0x8DCD: 0x683D, |
| 0x8DCE: 0x6B73, |
| 0x8DCF: 0x6E08, |
| 0x8DD0: 0x707D, |
| 0x8DD1: 0x91C7, |
| 0x8DD2: 0x7280, |
| 0x8DD3: 0x7815, |
| 0x8DD4: 0x7826, |
| 0x8DD5: 0x796D, |
| 0x8DD6: 0x658E, |
| 0x8DD7: 0x7D30, |
| 0x8DD8: 0x83DC, |
| 0x8DD9: 0x88C1, |
| 0x8DDA: 0x8F09, |
| 0x8DDB: 0x969B, |
| 0x8DDC: 0x5264, |
| 0x8DDD: 0x5728, |
| 0x8DDE: 0x6750, |
| 0x8DDF: 0x7F6A, |
| 0x8DE0: 0x8CA1, |
| 0x8DE1: 0x51B4, |
| 0x8DE2: 0x5742, |
| 0x8DE3: 0x962A, |
| 0x8DE4: 0x583A, |
| 0x8DE5: 0x698A, |
| 0x8DE6: 0x80B4, |
| 0x8DE7: 0x54B2, |
| 0x8DE8: 0x5D0E, |
| 0x8DE9: 0x57FC, |
| 0x8DEA: 0x7895, |
| 0x8DEB: 0x9DFA, |
| 0x8DEC: 0x4F5C, |
| 0x8DED: 0x524A, |
| 0x8DEE: 0x548B, |
| 0x8DEF: 0x643E, |
| 0x8DF0: 0x6628, |
| 0x8DF1: 0x6714, |
| 0x8DF2: 0x67F5, |
| 0x8DF3: 0x7A84, |
| 0x8DF4: 0x7B56, |
| 0x8DF5: 0x7D22, |
| 0x8DF6: 0x932F, |
| 0x8DF7: 0x685C, |
| 0x8DF8: 0x9BAD, |
| 0x8DF9: 0x7B39, |
| 0x8DFA: 0x5319, |
| 0x8DFB: 0x518A, |
| 0x8DFC: 0x5237, |
| 0x8E40: 0x5BDF, |
| 0x8E41: 0x62F6, |
| 0x8E42: 0x64AE, |
| 0x8E43: 0x64E6, |
| 0x8E44: 0x672D, |
| 0x8E45: 0x6BBA, |
| 0x8E46: 0x85A9, |
| 0x8E47: 0x96D1, |
| 0x8E48: 0x7690, |
| 0x8E49: 0x9BD6, |
| 0x8E4A: 0x634C, |
| 0x8E4B: 0x9306, |
| 0x8E4C: 0x9BAB, |
| 0x8E4D: 0x76BF, |
| 0x8E4E: 0x6652, |
| 0x8E4F: 0x4E09, |
| 0x8E50: 0x5098, |
| 0x8E51: 0x53C2, |
| 0x8E52: 0x5C71, |
| 0x8E53: 0x60E8, |
| 0x8E54: 0x6492, |
| 0x8E55: 0x6563, |
| 0x8E56: 0x685F, |
| 0x8E57: 0x71E6, |
| 0x8E58: 0x73CA, |
| 0x8E59: 0x7523, |
| 0x8E5A: 0x7B97, |
| 0x8E5B: 0x7E82, |
| 0x8E5C: 0x8695, |
| 0x8E5D: 0x8B83, |
| 0x8E5E: 0x8CDB, |
| 0x8E5F: 0x9178, |
| 0x8E60: 0x9910, |
| 0x8E61: 0x65AC, |
| 0x8E62: 0x66AB, |
| 0x8E63: 0x6B8B, |
| 0x8E64: 0x4ED5, |
| 0x8E65: 0x4ED4, |
| 0x8E66: 0x4F3A, |
| 0x8E67: 0x4F7F, |
| 0x8E68: 0x523A, |
| 0x8E69: 0x53F8, |
| 0x8E6A: 0x53F2, |
| 0x8E6B: 0x55E3, |
| 0x8E6C: 0x56DB, |
| 0x8E6D: 0x58EB, |
| 0x8E6E: 0x59CB, |
| 0x8E6F: 0x59C9, |
| 0x8E70: 0x59FF, |
| 0x8E71: 0x5B50, |
| 0x8E72: 0x5C4D, |
| 0x8E73: 0x5E02, |
| 0x8E74: 0x5E2B, |
| 0x8E75: 0x5FD7, |
| 0x8E76: 0x601D, |
| 0x8E77: 0x6307, |
| 0x8E78: 0x652F, |
| 0x8E79: 0x5B5C, |
| 0x8E7A: 0x65AF, |
| 0x8E7B: 0x65BD, |
| 0x8E7C: 0x65E8, |
| 0x8E7D: 0x679D, |
| 0x8E7E: 0x6B62, |
| 0x8E80: 0x6B7B, |
| 0x8E81: 0x6C0F, |
| 0x8E82: 0x7345, |
| 0x8E83: 0x7949, |
| 0x8E84: 0x79C1, |
| 0x8E85: 0x7CF8, |
| 0x8E86: 0x7D19, |
| 0x8E87: 0x7D2B, |
| 0x8E88: 0x80A2, |
| 0x8E89: 0x8102, |
| 0x8E8A: 0x81F3, |
| 0x8E8B: 0x8996, |
| 0x8E8C: 0x8A5E, |
| 0x8E8D: 0x8A69, |
| 0x8E8E: 0x8A66, |
| 0x8E8F: 0x8A8C, |
| 0x8E90: 0x8AEE, |
| 0x8E91: 0x8CC7, |
| 0x8E92: 0x8CDC, |
| 0x8E93: 0x96CC, |
| 0x8E94: 0x98FC, |
| 0x8E95: 0x6B6F, |
| 0x8E96: 0x4E8B, |
| 0x8E97: 0x4F3C, |
| 0x8E98: 0x4F8D, |
| 0x8E99: 0x5150, |
| 0x8E9A: 0x5B57, |
| 0x8E9B: 0x5BFA, |
| 0x8E9C: 0x6148, |
| 0x8E9D: 0x6301, |
| 0x8E9E: 0x6642, |
| 0x8E9F: 0x6B21, |
| 0x8EA0: 0x6ECB, |
| 0x8EA1: 0x6CBB, |
| 0x8EA2: 0x723E, |
| 0x8EA3: 0x74BD, |
| 0x8EA4: 0x75D4, |
| 0x8EA5: 0x78C1, |
| 0x8EA6: 0x793A, |
| 0x8EA7: 0x800C, |
| 0x8EA8: 0x8033, |
| 0x8EA9: 0x81EA, |
| 0x8EAA: 0x8494, |
| 0x8EAB: 0x8F9E, |
| 0x8EAC: 0x6C50, |
| 0x8EAD: 0x9E7F, |
| 0x8EAE: 0x5F0F, |
| 0x8EAF: 0x8B58, |
| 0x8EB0: 0x9D2B, |
| 0x8EB1: 0x7AFA, |
| 0x8EB2: 0x8EF8, |
| 0x8EB3: 0x5B8D, |
| 0x8EB4: 0x96EB, |
| 0x8EB5: 0x4E03, |
| 0x8EB6: 0x53F1, |
| 0x8EB7: 0x57F7, |
| 0x8EB8: 0x5931, |
| 0x8EB9: 0x5AC9, |
| 0x8EBA: 0x5BA4, |
| 0x8EBB: 0x6089, |
| 0x8EBC: 0x6E7F, |
| 0x8EBD: 0x6F06, |
| 0x8EBE: 0x75BE, |
| 0x8EBF: 0x8CEA, |
| 0x8EC0: 0x5B9F, |
| 0x8EC1: 0x8500, |
| 0x8EC2: 0x7BE0, |
| 0x8EC3: 0x5072, |
| 0x8EC4: 0x67F4, |
| 0x8EC5: 0x829D, |
| 0x8EC6: 0x5C61, |
| 0x8EC7: 0x854A, |
| 0x8EC8: 0x7E1E, |
| 0x8EC9: 0x820E, |
| 0x8ECA: 0x5199, |
| 0x8ECB: 0x5C04, |
| 0x8ECC: 0x6368, |
| 0x8ECD: 0x8D66, |
| 0x8ECE: 0x659C, |
| 0x8ECF: 0x716E, |
| 0x8ED0: 0x793E, |
| 0x8ED1: 0x7D17, |
| 0x8ED2: 0x8005, |
| 0x8ED3: 0x8B1D, |
| 0x8ED4: 0x8ECA, |
| 0x8ED5: 0x906E, |
| 0x8ED6: 0x86C7, |
| 0x8ED7: 0x90AA, |
| 0x8ED8: 0x501F, |
| 0x8ED9: 0x52FA, |
| 0x8EDA: 0x5C3A, |
| 0x8EDB: 0x6753, |
| 0x8EDC: 0x707C, |
| 0x8EDD: 0x7235, |
| 0x8EDE: 0x914C, |
| 0x8EDF: 0x91C8, |
| 0x8EE0: 0x932B, |
| 0x8EE1: 0x82E5, |
| 0x8EE2: 0x5BC2, |
| 0x8EE3: 0x5F31, |
| 0x8EE4: 0x60F9, |
| 0x8EE5: 0x4E3B, |
| 0x8EE6: 0x53D6, |
| 0x8EE7: 0x5B88, |
| 0x8EE8: 0x624B, |
| 0x8EE9: 0x6731, |
| 0x8EEA: 0x6B8A, |
| 0x8EEB: 0x72E9, |
| 0x8EEC: 0x73E0, |
| 0x8EED: 0x7A2E, |
| 0x8EEE: 0x816B, |
| 0x8EEF: 0x8DA3, |
| 0x8EF0: 0x9152, |
| 0x8EF1: 0x9996, |
| 0x8EF2: 0x5112, |
| 0x8EF3: 0x53D7, |
| 0x8EF4: 0x546A, |
| 0x8EF5: 0x5BFF, |
| 0x8EF6: 0x6388, |
| 0x8EF7: 0x6A39, |
| 0x8EF8: 0x7DAC, |
| 0x8EF9: 0x9700, |
| 0x8EFA: 0x56DA, |
| 0x8EFB: 0x53CE, |
| 0x8EFC: 0x5468, |
| 0x8F40: 0x5B97, |
| 0x8F41: 0x5C31, |
| 0x8F42: 0x5DDE, |
| 0x8F43: 0x4FEE, |
| 0x8F44: 0x6101, |
| 0x8F45: 0x62FE, |
| 0x8F46: 0x6D32, |
| 0x8F47: 0x79C0, |
| 0x8F48: 0x79CB, |
| 0x8F49: 0x7D42, |
| 0x8F4A: 0x7E4D, |
| 0x8F4B: 0x7FD2, |
| 0x8F4C: 0x81ED, |
| 0x8F4D: 0x821F, |
| 0x8F4E: 0x8490, |
| 0x8F4F: 0x8846, |
| 0x8F50: 0x8972, |
| 0x8F51: 0x8B90, |
| 0x8F52: 0x8E74, |
| 0x8F53: 0x8F2F, |
| 0x8F54: 0x9031, |
| 0x8F55: 0x914B, |
| 0x8F56: 0x916C, |
| 0x8F57: 0x96C6, |
| 0x8F58: 0x919C, |
| 0x8F59: 0x4EC0, |
| 0x8F5A: 0x4F4F, |
| 0x8F5B: 0x5145, |
| 0x8F5C: 0x5341, |
| 0x8F5D: 0x5F93, |
| 0x8F5E: 0x620E, |
| 0x8F5F: 0x67D4, |
| 0x8F60: 0x6C41, |
| 0x8F61: 0x6E0B, |
| 0x8F62: 0x7363, |
| 0x8F63: 0x7E26, |
| 0x8F64: 0x91CD, |
| 0x8F65: 0x9283, |
| 0x8F66: 0x53D4, |
| 0x8F67: 0x5919, |
| 0x8F68: 0x5BBF, |
| 0x8F69: 0x6DD1, |
| 0x8F6A: 0x795D, |
| 0x8F6B: 0x7E2E, |
| 0x8F6C: 0x7C9B, |
| 0x8F6D: 0x587E, |
| 0x8F6E: 0x719F, |
| 0x8F6F: 0x51FA, |
| 0x8F70: 0x8853, |
| 0x8F71: 0x8FF0, |
| 0x8F72: 0x4FCA, |
| 0x8F73: 0x5CFB, |
| 0x8F74: 0x6625, |
| 0x8F75: 0x77AC, |
| 0x8F76: 0x7AE3, |
| 0x8F77: 0x821C, |
| 0x8F78: 0x99FF, |
| 0x8F79: 0x51C6, |
| 0x8F7A: 0x5FAA, |
| 0x8F7B: 0x65EC, |
| 0x8F7C: 0x696F, |
| 0x8F7D: 0x6B89, |
| 0x8F7E: 0x6DF3, |
| 0x8F80: 0x6E96, |
| 0x8F81: 0x6F64, |
| 0x8F82: 0x76FE, |
| 0x8F83: 0x7D14, |
| 0x8F84: 0x5DE1, |
| 0x8F85: 0x9075, |
| 0x8F86: 0x9187, |
| 0x8F87: 0x9806, |
| 0x8F88: 0x51E6, |
| 0x8F89: 0x521D, |
| 0x8F8A: 0x6240, |
| 0x8F8B: 0x6691, |
| 0x8F8C: 0x66D9, |
| 0x8F8D: 0x6E1A, |
| 0x8F8E: 0x5EB6, |
| 0x8F8F: 0x7DD2, |
| 0x8F90: 0x7F72, |
| 0x8F91: 0x66F8, |
| 0x8F92: 0x85AF, |
| 0x8F93: 0x85F7, |
| 0x8F94: 0x8AF8, |
| 0x8F95: 0x52A9, |
| 0x8F96: 0x53D9, |
| 0x8F97: 0x5973, |
| 0x8F98: 0x5E8F, |
| 0x8F99: 0x5F90, |
| 0x8F9A: 0x6055, |
| 0x8F9B: 0x92E4, |
| 0x8F9C: 0x9664, |
| 0x8F9D: 0x50B7, |
| 0x8F9E: 0x511F, |
| 0x8F9F: 0x52DD, |
| 0x8FA0: 0x5320, |
| 0x8FA1: 0x5347, |
| 0x8FA2: 0x53EC, |
| 0x8FA3: 0x54E8, |
| 0x8FA4: 0x5546, |
| 0x8FA5: 0x5531, |
| 0x8FA6: 0x5617, |
| 0x8FA7: 0x5968, |
| 0x8FA8: 0x59BE, |
| 0x8FA9: 0x5A3C, |
| 0x8FAA: 0x5BB5, |
| 0x8FAB: 0x5C06, |
| 0x8FAC: 0x5C0F, |
| 0x8FAD: 0x5C11, |
| 0x8FAE: 0x5C1A, |
| 0x8FAF: 0x5E84, |
| 0x8FB0: 0x5E8A, |
| 0x8FB1: 0x5EE0, |
| 0x8FB2: 0x5F70, |
| 0x8FB3: 0x627F, |
| 0x8FB4: 0x6284, |
| 0x8FB5: 0x62DB, |
| 0x8FB6: 0x638C, |
| 0x8FB7: 0x6377, |
| 0x8FB8: 0x6607, |
| 0x8FB9: 0x660C, |
| 0x8FBA: 0x662D, |
| 0x8FBB: 0x6676, |
| 0x8FBC: 0x677E, |
| 0x8FBD: 0x68A2, |
| 0x8FBE: 0x6A1F, |
| 0x8FBF: 0x6A35, |
| 0x8FC0: 0x6CBC, |
| 0x8FC1: 0x6D88, |
| 0x8FC2: 0x6E09, |
| 0x8FC3: 0x6E58, |
| 0x8FC4: 0x713C, |
| 0x8FC5: 0x7126, |
| 0x8FC6: 0x7167, |
| 0x8FC7: 0x75C7, |
| 0x8FC8: 0x7701, |
| 0x8FC9: 0x785D, |
| 0x8FCA: 0x7901, |
| 0x8FCB: 0x7965, |
| 0x8FCC: 0x79F0, |
| 0x8FCD: 0x7AE0, |
| 0x8FCE: 0x7B11, |
| 0x8FCF: 0x7CA7, |
| 0x8FD0: 0x7D39, |
| 0x8FD1: 0x8096, |
| 0x8FD2: 0x83D6, |
| 0x8FD3: 0x848B, |
| 0x8FD4: 0x8549, |
| 0x8FD5: 0x885D, |
| 0x8FD6: 0x88F3, |
| 0x8FD7: 0x8A1F, |
| 0x8FD8: 0x8A3C, |
| 0x8FD9: 0x8A54, |
| 0x8FDA: 0x8A73, |
| 0x8FDB: 0x8C61, |
| 0x8FDC: 0x8CDE, |
| 0x8FDD: 0x91A4, |
| 0x8FDE: 0x9266, |
| 0x8FDF: 0x937E, |
| 0x8FE0: 0x9418, |
| 0x8FE1: 0x969C, |
| 0x8FE2: 0x9798, |
| 0x8FE3: 0x4E0A, |
| 0x8FE4: 0x4E08, |
| 0x8FE5: 0x4E1E, |
| 0x8FE6: 0x4E57, |
| 0x8FE7: 0x5197, |
| 0x8FE8: 0x5270, |
| 0x8FE9: 0x57CE, |
| 0x8FEA: 0x5834, |
| 0x8FEB: 0x58CC, |
| 0x8FEC: 0x5B22, |
| 0x8FED: 0x5E38, |
| 0x8FEE: 0x60C5, |
| 0x8FEF: 0x64FE, |
| 0x8FF0: 0x6761, |
| 0x8FF1: 0x6756, |
| 0x8FF2: 0x6D44, |
| 0x8FF3: 0x72B6, |
| 0x8FF4: 0x7573, |
| 0x8FF5: 0x7A63, |
| 0x8FF6: 0x84B8, |
| 0x8FF7: 0x8B72, |
| 0x8FF8: 0x91B8, |
| 0x8FF9: 0x9320, |
| 0x8FFA: 0x5631, |
| 0x8FFB: 0x57F4, |
| 0x8FFC: 0x98FE, |
| 0x9040: 0x62ED, |
| 0x9041: 0x690D, |
| 0x9042: 0x6B96, |
| 0x9043: 0x71ED, |
| 0x9044: 0x7E54, |
| 0x9045: 0x8077, |
| 0x9046: 0x8272, |
| 0x9047: 0x89E6, |
| 0x9048: 0x98DF, |
| 0x9049: 0x8755, |
| 0x904A: 0x8FB1, |
| 0x904B: 0x5C3B, |
| 0x904C: 0x4F38, |
| 0x904D: 0x4FE1, |
| 0x904E: 0x4FB5, |
| 0x904F: 0x5507, |
| 0x9050: 0x5A20, |
| 0x9051: 0x5BDD, |
| 0x9052: 0x5BE9, |
| 0x9053: 0x5FC3, |
| 0x9054: 0x614E, |
| 0x9055: 0x632F, |
| 0x9056: 0x65B0, |
| 0x9057: 0x664B, |
| 0x9058: 0x68EE, |
| 0x9059: 0x699B, |
| 0x905A: 0x6D78, |
| 0x905B: 0x6DF1, |
| 0x905C: 0x7533, |
| 0x905D: 0x75B9, |
| 0x905E: 0x771F, |
| 0x905F: 0x795E, |
| 0x9060: 0x79E6, |
| 0x9061: 0x7D33, |
| 0x9062: 0x81E3, |
| 0x9063: 0x82AF, |
| 0x9064: 0x85AA, |
| 0x9065: 0x89AA, |
| 0x9066: 0x8A3A, |
| 0x9067: 0x8EAB, |
| 0x9068: 0x8F9B, |
| 0x9069: 0x9032, |
| 0x906A: 0x91DD, |
| 0x906B: 0x9707, |
| 0x906C: 0x4EBA, |
| 0x906D: 0x4EC1, |
| 0x906E: 0x5203, |
| 0x906F: 0x5875, |
| 0x9070: 0x58EC, |
| 0x9071: 0x5C0B, |
| 0x9072: 0x751A, |
| 0x9073: 0x5C3D, |
| 0x9074: 0x814E, |
| 0x9075: 0x8A0A, |
| 0x9076: 0x8FC5, |
| 0x9077: 0x9663, |
| 0x9078: 0x976D, |
| 0x9079: 0x7B25, |
| 0x907A: 0x8ACF, |
| 0x907B: 0x9808, |
| 0x907C: 0x9162, |
| 0x907D: 0x56F3, |
| 0x907E: 0x53A8, |
| 0x9080: 0x9017, |
| 0x9081: 0x5439, |
| 0x9082: 0x5782, |
| 0x9083: 0x5E25, |
| 0x9084: 0x63A8, |
| 0x9085: 0x6C34, |
| 0x9086: 0x708A, |
| 0x9087: 0x7761, |
| 0x9088: 0x7C8B, |
| 0x9089: 0x7FE0, |
| 0x908A: 0x8870, |
| 0x908B: 0x9042, |
| 0x908C: 0x9154, |
| 0x908D: 0x9310, |
| 0x908E: 0x9318, |
| 0x908F: 0x968F, |
| 0x9090: 0x745E, |
| 0x9091: 0x9AC4, |
| 0x9092: 0x5D07, |
| 0x9093: 0x5D69, |
| 0x9094: 0x6570, |
| 0x9095: 0x67A2, |
| 0x9096: 0x8DA8, |
| 0x9097: 0x96DB, |
| 0x9098: 0x636E, |
| 0x9099: 0x6749, |
| 0x909A: 0x6919, |
| 0x909B: 0x83C5, |
| 0x909C: 0x9817, |
| 0x909D: 0x96C0, |
| 0x909E: 0x88FE, |
| 0x909F: 0x6F84, |
| 0x90A0: 0x647A, |
| 0x90A1: 0x5BF8, |
| 0x90A2: 0x4E16, |
| 0x90A3: 0x702C, |
| 0x90A4: 0x755D, |
| 0x90A5: 0x662F, |
| 0x90A6: 0x51C4, |
| 0x90A7: 0x5236, |
| 0x90A8: 0x52E2, |
| 0x90A9: 0x59D3, |
| 0x90AA: 0x5F81, |
| 0x90AB: 0x6027, |
| 0x90AC: 0x6210, |
| 0x90AD: 0x653F, |
| 0x90AE: 0x6574, |
| 0x90AF: 0x661F, |
| 0x90B0: 0x6674, |
| 0x90B1: 0x68F2, |
| 0x90B2: 0x6816, |
| 0x90B3: 0x6B63, |
| 0x90B4: 0x6E05, |
| 0x90B5: 0x7272, |
| 0x90B6: 0x751F, |
| 0x90B7: 0x76DB, |
| 0x90B8: 0x7CBE, |
| 0x90B9: 0x8056, |
| 0x90BA: 0x58F0, |
| 0x90BB: 0x88FD, |
| 0x90BC: 0x897F, |
| 0x90BD: 0x8AA0, |
| 0x90BE: 0x8A93, |
| 0x90BF: 0x8ACB, |
| 0x90C0: 0x901D, |
| 0x90C1: 0x9192, |
| 0x90C2: 0x9752, |
| 0x90C3: 0x9759, |
| 0x90C4: 0x6589, |
| 0x90C5: 0x7A0E, |
| 0x90C6: 0x8106, |
| 0x90C7: 0x96BB, |
| 0x90C8: 0x5E2D, |
| 0x90C9: 0x60DC, |
| 0x90CA: 0x621A, |
| 0x90CB: 0x65A5, |
| 0x90CC: 0x6614, |
| 0x90CD: 0x6790, |
| 0x90CE: 0x77F3, |
| 0x90CF: 0x7A4D, |
| 0x90D0: 0x7C4D, |
| 0x90D1: 0x7E3E, |
| 0x90D2: 0x810A, |
| 0x90D3: 0x8CAC, |
| 0x90D4: 0x8D64, |
| 0x90D5: 0x8DE1, |
| 0x90D6: 0x8E5F, |
| 0x90D7: 0x78A9, |
| 0x90D8: 0x5207, |
| 0x90D9: 0x62D9, |
| 0x90DA: 0x63A5, |
| 0x90DB: 0x6442, |
| 0x90DC: 0x6298, |
| 0x90DD: 0x8A2D, |
| 0x90DE: 0x7A83, |
| 0x90DF: 0x7BC0, |
| 0x90E0: 0x8AAC, |
| 0x90E1: 0x96EA, |
| 0x90E2: 0x7D76, |
| 0x90E3: 0x820C, |
| 0x90E4: 0x8749, |
| 0x90E5: 0x4ED9, |
| 0x90E6: 0x5148, |
| 0x90E7: 0x5343, |
| 0x90E8: 0x5360, |
| 0x90E9: 0x5BA3, |
| 0x90EA: 0x5C02, |
| 0x90EB: 0x5C16, |
| 0x90EC: 0x5DDD, |
| 0x90ED: 0x6226, |
| 0x90EE: 0x6247, |
| 0x90EF: 0x64B0, |
| 0x90F0: 0x6813, |
| 0x90F1: 0x6834, |
| 0x90F2: 0x6CC9, |
| 0x90F3: 0x6D45, |
| 0x90F4: 0x6D17, |
| 0x90F5: 0x67D3, |
| 0x90F6: 0x6F5C, |
| 0x90F7: 0x714E, |
| 0x90F8: 0x717D, |
| 0x90F9: 0x65CB, |
| 0x90FA: 0x7A7F, |
| 0x90FB: 0x7BAD, |
| 0x90FC: 0x7DDA, |
| 0x9140: 0x7E4A, |
| 0x9141: 0x7FA8, |
| 0x9142: 0x817A, |
| 0x9143: 0x821B, |
| 0x9144: 0x8239, |
| 0x9145: 0x85A6, |
| 0x9146: 0x8A6E, |
| 0x9147: 0x8CCE, |
| 0x9148: 0x8DF5, |
| 0x9149: 0x9078, |
| 0x914A: 0x9077, |
| 0x914B: 0x92AD, |
| 0x914C: 0x9291, |
| 0x914D: 0x9583, |
| 0x914E: 0x9BAE, |
| 0x914F: 0x524D, |
| 0x9150: 0x5584, |
| 0x9151: 0x6F38, |
| 0x9152: 0x7136, |
| 0x9153: 0x5168, |
| 0x9154: 0x7985, |
| 0x9155: 0x7E55, |
| 0x9156: 0x81B3, |
| 0x9157: 0x7CCE, |
| 0x9158: 0x564C, |
| 0x9159: 0x5851, |
| 0x915A: 0x5CA8, |
| 0x915B: 0x63AA, |
| 0x915C: 0x66FE, |
| 0x915D: 0x66FD, |
| 0x915E: 0x695A, |
| 0x915F: 0x72D9, |
| 0x9160: 0x758F, |
| 0x9161: 0x758E, |
| 0x9162: 0x790E, |
| 0x9163: 0x7956, |
| 0x9164: 0x79DF, |
| 0x9165: 0x7C97, |
| 0x9166: 0x7D20, |
| 0x9167: 0x7D44, |
| 0x9168: 0x8607, |
| 0x9169: 0x8A34, |
| 0x916A: 0x963B, |
| 0x916B: 0x9061, |
| 0x916C: 0x9F20, |
| 0x916D: 0x50E7, |
| 0x916E: 0x5275, |
| 0x916F: 0x53CC, |
| 0x9170: 0x53E2, |
| 0x9171: 0x5009, |
| 0x9172: 0x55AA, |
| 0x9173: 0x58EE, |
| 0x9174: 0x594F, |
| 0x9175: 0x723D, |
| 0x9176: 0x5B8B, |
| 0x9177: 0x5C64, |
| 0x9178: 0x531D, |
| 0x9179: 0x60E3, |
| 0x917A: 0x60F3, |
| 0x917B: 0x635C, |
| 0x917C: 0x6383, |
| 0x917D: 0x633F, |
| 0x917E: 0x63BB, |
| 0x9180: 0x64CD, |
| 0x9181: 0x65E9, |
| 0x9182: 0x66F9, |
| 0x9183: 0x5DE3, |
| 0x9184: 0x69CD, |
| 0x9185: 0x69FD, |
| 0x9186: 0x6F15, |
| 0x9187: 0x71E5, |
| 0x9188: 0x4E89, |
| 0x9189: 0x75E9, |
| 0x918A: 0x76F8, |
| 0x918B: 0x7A93, |
| 0x918C: 0x7CDF, |
| 0x918D: 0x7DCF, |
| 0x918E: 0x7D9C, |
| 0x918F: 0x8061, |
| 0x9190: 0x8349, |
| 0x9191: 0x8358, |
| 0x9192: 0x846C, |
| 0x9193: 0x84BC, |
| 0x9194: 0x85FB, |
| 0x9195: 0x88C5, |
| 0x9196: 0x8D70, |
| 0x9197: 0x9001, |
| 0x9198: 0x906D, |
| 0x9199: 0x9397, |
| 0x919A: 0x971C, |
| 0x919B: 0x9A12, |
| 0x919C: 0x50CF, |
| 0x919D: 0x5897, |
| 0x919E: 0x618E, |
| 0x919F: 0x81D3, |
| 0x91A0: 0x8535, |
| 0x91A1: 0x8D08, |
| 0x91A2: 0x9020, |
| 0x91A3: 0x4FC3, |
| 0x91A4: 0x5074, |
| 0x91A5: 0x5247, |
| 0x91A6: 0x5373, |
| 0x91A7: 0x606F, |
| 0x91A8: 0x6349, |
| 0x91A9: 0x675F, |
| 0x91AA: 0x6E2C, |
| 0x91AB: 0x8DB3, |
| 0x91AC: 0x901F, |
| 0x91AD: 0x4FD7, |
| 0x91AE: 0x5C5E, |
| 0x91AF: 0x8CCA, |
| 0x91B0: 0x65CF, |
| 0x91B1: 0x7D9A, |
| 0x91B2: 0x5352, |
| 0x91B3: 0x8896, |
| 0x91B4: 0x5176, |
| 0x91B5: 0x63C3, |
| 0x91B6: 0x5B58, |
| 0x91B7: 0x5B6B, |
| 0x91B8: 0x5C0A, |
| 0x91B9: 0x640D, |
| 0x91BA: 0x6751, |
| 0x91BB: 0x905C, |
| 0x91BC: 0x4ED6, |
| 0x91BD: 0x591A, |
| 0x91BE: 0x592A, |
| 0x91BF: 0x6C70, |
| 0x91C0: 0x8A51, |
| 0x91C1: 0x553E, |
| 0x91C2: 0x5815, |
| 0x91C3: 0x59A5, |
| 0x91C4: 0x60F0, |
| 0x91C5: 0x6253, |
| 0x91C6: 0x67C1, |
| 0x91C7: 0x8235, |
| 0x91C8: 0x6955, |
| 0x91C9: 0x9640, |
| 0x91CA: 0x99C4, |
| 0x91CB: 0x9A28, |
| 0x91CC: 0x4F53, |
| 0x91CD: 0x5806, |
| 0x91CE: 0x5BFE, |
| 0x91CF: 0x8010, |
| 0x91D0: 0x5CB1, |
| 0x91D1: 0x5E2F, |
| 0x91D2: 0x5F85, |
| 0x91D3: 0x6020, |
| 0x91D4: 0x614B, |
| 0x91D5: 0x6234, |
| 0x91D6: 0x66FF, |
| 0x91D7: 0x6CF0, |
| 0x91D8: 0x6EDE, |
| 0x91D9: 0x80CE, |
| 0x91DA: 0x817F, |
| 0x91DB: 0x82D4, |
| 0x91DC: 0x888B, |
| 0x91DD: 0x8CB8, |
| 0x91DE: 0x9000, |
| 0x91DF: 0x902E, |
| 0x91E0: 0x968A, |
| 0x91E1: 0x9EDB, |
| 0x91E2: 0x9BDB, |
| 0x91E3: 0x4EE3, |
| 0x91E4: 0x53F0, |
| 0x91E5: 0x5927, |
| 0x91E6: 0x7B2C, |
| 0x91E7: 0x918D, |
| 0x91E8: 0x984C, |
| 0x91E9: 0x9DF9, |
| 0x91EA: 0x6EDD, |
| 0x91EB: 0x7027, |
| 0x91EC: 0x5353, |
| 0x91ED: 0x5544, |
| 0x91EE: 0x5B85, |
| 0x91EF: 0x6258, |
| 0x91F0: 0x629E, |
| 0x91F1: 0x62D3, |
| 0x91F2: 0x6CA2, |
| 0x91F3: 0x6FEF, |
| 0x91F4: 0x7422, |
| 0x91F5: 0x8A17, |
| 0x91F6: 0x9438, |
| 0x91F7: 0x6FC1, |
| 0x91F8: 0x8AFE, |
| 0x91F9: 0x8338, |
| 0x91FA: 0x51E7, |
| 0x91FB: 0x86F8, |
| 0x91FC: 0x53EA, |
| 0x9240: 0x53E9, |
| 0x9241: 0x4F46, |
| 0x9242: 0x9054, |
| 0x9243: 0x8FB0, |
| 0x9244: 0x596A, |
| 0x9245: 0x8131, |
| 0x9246: 0x5DFD, |
| 0x9247: 0x7AEA, |
| 0x9248: 0x8FBF, |
| 0x9249: 0x68DA, |
| 0x924A: 0x8C37, |
| 0x924B: 0x72F8, |
| 0x924C: 0x9C48, |
| 0x924D: 0x6A3D, |
| 0x924E: 0x8AB0, |
| 0x924F: 0x4E39, |
| 0x9250: 0x5358, |
| 0x9251: 0x5606, |
| 0x9252: 0x5766, |
| 0x9253: 0x62C5, |
| 0x9254: 0x63A2, |
| 0x9255: 0x65E6, |
| 0x9256: 0x6B4E, |
| 0x9257: 0x6DE1, |
| 0x9258: 0x6E5B, |
| 0x9259: 0x70AD, |
| 0x925A: 0x77ED, |
| 0x925B: 0x7AEF, |
| 0x925C: 0x7BAA, |
| 0x925D: 0x7DBB, |
| 0x925E: 0x803D, |
| 0x925F: 0x80C6, |
| 0x9260: 0x86CB, |
| 0x9261: 0x8A95, |
| 0x9262: 0x935B, |
| 0x9263: 0x56E3, |
| 0x9264: 0x58C7, |
| 0x9265: 0x5F3E, |
| 0x9266: 0x65AD, |
| 0x9267: 0x6696, |
| 0x9268: 0x6A80, |
| 0x9269: 0x6BB5, |
| 0x926A: 0x7537, |
| 0x926B: 0x8AC7, |
| 0x926C: 0x5024, |
| 0x926D: 0x77E5, |
| 0x926E: 0x5730, |
| 0x926F: 0x5F1B, |
| 0x9270: 0x6065, |
| 0x9271: 0x667A, |
| 0x9272: 0x6C60, |
| 0x9273: 0x75F4, |
| 0x9274: 0x7A1A, |
| 0x9275: 0x7F6E, |
| 0x9276: 0x81F4, |
| 0x9277: 0x8718, |
| 0x9278: 0x9045, |
| 0x9279: 0x99B3, |
| 0x927A: 0x7BC9, |
| 0x927B: 0x755C, |
| 0x927C: 0x7AF9, |
| 0x927D: 0x7B51, |
| 0x927E: 0x84C4, |
| 0x9280: 0x9010, |
| 0x9281: 0x79E9, |
| 0x9282: 0x7A92, |
| 0x9283: 0x8336, |
| 0x9284: 0x5AE1, |
| 0x9285: 0x7740, |
| 0x9286: 0x4E2D, |
| 0x9287: 0x4EF2, |
| 0x9288: 0x5B99, |
| 0x9289: 0x5FE0, |
| 0x928A: 0x62BD, |
| 0x928B: 0x663C, |
| 0x928C: 0x67F1, |
| 0x928D: 0x6CE8, |
| 0x928E: 0x866B, |
| 0x928F: 0x8877, |
| 0x9290: 0x8A3B, |
| 0x9291: 0x914E, |
| 0x9292: 0x92F3, |
| 0x9293: 0x99D0, |
| 0x9294: 0x6A17, |
| 0x9295: 0x7026, |
| 0x9296: 0x732A, |
| 0x9297: 0x82E7, |
| 0x9298: 0x8457, |
| 0x9299: 0x8CAF, |
| 0x929A: 0x4E01, |
| 0x929B: 0x5146, |
| 0x929C: 0x51CB, |
| 0x929D: 0x558B, |
| 0x929E: 0x5BF5, |
| 0x929F: 0x5E16, |
| 0x92A0: 0x5E33, |
| 0x92A1: 0x5E81, |
| 0x92A2: 0x5F14, |
| 0x92A3: 0x5F35, |
| 0x92A4: 0x5F6B, |
| 0x92A5: 0x5FB4, |
| 0x92A6: 0x61F2, |
| 0x92A7: 0x6311, |
| 0x92A8: 0x66A2, |
| 0x92A9: 0x671D, |
| 0x92AA: 0x6F6E, |
| 0x92AB: 0x7252, |
| 0x92AC: 0x753A, |
| 0x92AD: 0x773A, |
| 0x92AE: 0x8074, |
| 0x92AF: 0x8139, |
| 0x92B0: 0x8178, |
| 0x92B1: 0x8776, |
| 0x92B2: 0x8ABF, |
| 0x92B3: 0x8ADC, |
| 0x92B4: 0x8D85, |
| 0x92B5: 0x8DF3, |
| 0x92B6: 0x929A, |
| 0x92B7: 0x9577, |
| 0x92B8: 0x9802, |
| 0x92B9: 0x9CE5, |
| 0x92BA: 0x52C5, |
| 0x92BB: 0x6357, |
| 0x92BC: 0x76F4, |
| 0x92BD: 0x6715, |
| 0x92BE: 0x6C88, |
| 0x92BF: 0x73CD, |
| 0x92C0: 0x8CC3, |
| 0x92C1: 0x93AE, |
| 0x92C2: 0x9673, |
| 0x92C3: 0x6D25, |
| 0x92C4: 0x589C, |
| 0x92C5: 0x690E, |
| 0x92C6: 0x69CC, |
| 0x92C7: 0x8FFD, |
| 0x92C8: 0x939A, |
| 0x92C9: 0x75DB, |
| 0x92CA: 0x901A, |
| 0x92CB: 0x585A, |
| 0x92CC: 0x6802, |
| 0x92CD: 0x63B4, |
| 0x92CE: 0x69FB, |
| 0x92CF: 0x4F43, |
| 0x92D0: 0x6F2C, |
| 0x92D1: 0x67D8, |
| 0x92D2: 0x8FBB, |
| 0x92D3: 0x8526, |
| 0x92D4: 0x7DB4, |
| 0x92D5: 0x9354, |
| 0x92D6: 0x693F, |
| 0x92D7: 0x6F70, |
| 0x92D8: 0x576A, |
| 0x92D9: 0x58F7, |
| 0x92DA: 0x5B2C, |
| 0x92DB: 0x7D2C, |
| 0x92DC: 0x722A, |
| 0x92DD: 0x540A, |
| 0x92DE: 0x91E3, |
| 0x92DF: 0x9DB4, |
| 0x92E0: 0x4EAD, |
| 0x92E1: 0x4F4E, |
| 0x92E2: 0x505C, |
| 0x92E3: 0x5075, |
| 0x92E4: 0x5243, |
| 0x92E5: 0x8C9E, |
| 0x92E6: 0x5448, |
| 0x92E7: 0x5824, |
| 0x92E8: 0x5B9A, |
| 0x92E9: 0x5E1D, |
| 0x92EA: 0x5E95, |
| 0x92EB: 0x5EAD, |
| 0x92EC: 0x5EF7, |
| 0x92ED: 0x5F1F, |
| 0x92EE: 0x608C, |
| 0x92EF: 0x62B5, |
| 0x92F0: 0x633A, |
| 0x92F1: 0x63D0, |
| 0x92F2: 0x68AF, |
| 0x92F3: 0x6C40, |
| 0x92F4: 0x7887, |
| 0x92F5: 0x798E, |
| 0x92F6: 0x7A0B, |
| 0x92F7: 0x7DE0, |
| 0x92F8: 0x8247, |
| 0x92F9: 0x8A02, |
| 0x92FA: 0x8AE6, |
| 0x92FB: 0x8E44, |
| 0x92FC: 0x9013, |
| 0x9340: 0x90B8, |
| 0x9341: 0x912D, |
| 0x9342: 0x91D8, |
| 0x9343: 0x9F0E, |
| 0x9344: 0x6CE5, |
| 0x9345: 0x6458, |
| 0x9346: 0x64E2, |
| 0x9347: 0x6575, |
| 0x9348: 0x6EF4, |
| 0x9349: 0x7684, |
| 0x934A: 0x7B1B, |
| 0x934B: 0x9069, |
| 0x934C: 0x93D1, |
| 0x934D: 0x6EBA, |
| 0x934E: 0x54F2, |
| 0x934F: 0x5FB9, |
| 0x9350: 0x64A4, |
| 0x9351: 0x8F4D, |
| 0x9352: 0x8FED, |
| 0x9353: 0x9244, |
| 0x9354: 0x5178, |
| 0x9355: 0x586B, |
| 0x9356: 0x5929, |
| 0x9357: 0x5C55, |
| 0x9358: 0x5E97, |
| 0x9359: 0x6DFB, |
| 0x935A: 0x7E8F, |
| 0x935B: 0x751C, |
| 0x935C: 0x8CBC, |
| 0x935D: 0x8EE2, |
| 0x935E: 0x985B, |
| 0x935F: 0x70B9, |
| 0x9360: 0x4F1D, |
| 0x9361: 0x6BBF, |
| 0x9362: 0x6FB1, |
| 0x9363: 0x7530, |
| 0x9364: 0x96FB, |
| 0x9365: 0x514E, |
| 0x9366: 0x5410, |
| 0x9367: 0x5835, |
| 0x9368: 0x5857, |
| 0x9369: 0x59AC, |
| 0x936A: 0x5C60, |
| 0x936B: 0x5F92, |
| 0x936C: 0x6597, |
| 0x936D: 0x675C, |
| 0x936E: 0x6E21, |
| 0x936F: 0x767B, |
| 0x9370: 0x83DF, |
| 0x9371: 0x8CED, |
| 0x9372: 0x9014, |
| 0x9373: 0x90FD, |
| 0x9374: 0x934D, |
| 0x9375: 0x7825, |
| 0x9376: 0x783A, |
| 0x9377: 0x52AA, |
| 0x9378: 0x5EA6, |
| 0x9379: 0x571F, |
| 0x937A: 0x5974, |
| 0x937B: 0x6012, |
| 0x937C: 0x5012, |
| 0x937D: 0x515A, |
| 0x937E: 0x51AC, |
| 0x9380: 0x51CD, |
| 0x9381: 0x5200, |
| 0x9382: 0x5510, |
| 0x9383: 0x5854, |
| 0x9384: 0x5858, |
| 0x9385: 0x5957, |
| 0x9386: 0x5B95, |
| 0x9387: 0x5CF6, |
| 0x9388: 0x5D8B, |
| 0x9389: 0x60BC, |
| 0x938A: 0x6295, |
| 0x938B: 0x642D, |
| 0x938C: 0x6771, |
| 0x938D: 0x6843, |
| 0x938E: 0x68BC, |
| 0x938F: 0x68DF, |
| 0x9390: 0x76D7, |
| 0x9391: 0x6DD8, |
| 0x9392: 0x6E6F, |
| 0x9393: 0x6D9B, |
| 0x9394: 0x706F, |
| 0x9395: 0x71C8, |
| 0x9396: 0x5F53, |
| 0x9397: 0x75D8, |
| 0x9398: 0x7977, |
| 0x9399: 0x7B49, |
| 0x939A: 0x7B54, |
| 0x939B: 0x7B52, |
| 0x939C: 0x7CD6, |
| 0x939D: 0x7D71, |
| 0x939E: 0x5230, |
| 0x939F: 0x8463, |
| 0x93A0: 0x8569, |
| 0x93A1: 0x85E4, |
| 0x93A2: 0x8A0E, |
| 0x93A3: 0x8B04, |
| 0x93A4: 0x8C46, |
| 0x93A5: 0x8E0F, |
| 0x93A6: 0x9003, |
| 0x93A7: 0x900F, |
| 0x93A8: 0x9419, |
| 0x93A9: 0x9676, |
| 0x93AA: 0x982D, |
| 0x93AB: 0x9A30, |
| 0x93AC: 0x95D8, |
| 0x93AD: 0x50CD, |
| 0x93AE: 0x52D5, |
| 0x93AF: 0x540C, |
| 0x93B0: 0x5802, |
| 0x93B1: 0x5C0E, |
| 0x93B2: 0x61A7, |
| 0x93B3: 0x649E, |
| 0x93B4: 0x6D1E, |
| 0x93B5: 0x77B3, |
| 0x93B6: 0x7AE5, |
| 0x93B7: 0x80F4, |
| 0x93B8: 0x8404, |
| 0x93B9: 0x9053, |
| 0x93BA: 0x9285, |
| 0x93BB: 0x5CE0, |
| 0x93BC: 0x9D07, |
| 0x93BD: 0x533F, |
| 0x93BE: 0x5F97, |
| 0x93BF: 0x5FB3, |
| 0x93C0: 0x6D9C, |
| 0x93C1: 0x7279, |
| 0x93C2: 0x7763, |
| 0x93C3: 0x79BF, |
| 0x93C4: 0x7BE4, |
| 0x93C5: 0x6BD2, |
| 0x93C6: 0x72EC, |
| 0x93C7: 0x8AAD, |
| 0x93C8: 0x6803, |
| 0x93C9: 0x6A61, |
| 0x93CA: 0x51F8, |
| 0x93CB: 0x7A81, |
| 0x93CC: 0x6934, |
| 0x93CD: 0x5C4A, |
| 0x93CE: 0x9CF6, |
| 0x93CF: 0x82EB, |
| 0x93D0: 0x5BC5, |
| 0x93D1: 0x9149, |
| 0x93D2: 0x701E, |
| 0x93D3: 0x5678, |
| 0x93D4: 0x5C6F, |
| 0x93D5: 0x60C7, |
| 0x93D6: 0x6566, |
| 0x93D7: 0x6C8C, |
| 0x93D8: 0x8C5A, |
| 0x93D9: 0x9041, |
| 0x93DA: 0x9813, |
| 0x93DB: 0x5451, |
| 0x93DC: 0x66C7, |
| 0x93DD: 0x920D, |
| 0x93DE: 0x5948, |
| 0x93DF: 0x90A3, |
| 0x93E0: 0x5185, |
| 0x93E1: 0x4E4D, |
| 0x93E2: 0x51EA, |
| 0x93E3: 0x8599, |
| 0x93E4: 0x8B0E, |
| 0x93E5: 0x7058, |
| 0x93E6: 0x637A, |
| 0x93E7: 0x934B, |
| 0x93E8: 0x6962, |
| 0x93E9: 0x99B4, |
| 0x93EA: 0x7E04, |
| 0x93EB: 0x7577, |
| 0x93EC: 0x5357, |
| 0x93ED: 0x6960, |
| 0x93EE: 0x8EDF, |
| 0x93EF: 0x96E3, |
| 0x93F0: 0x6C5D, |
| 0x93F1: 0x4E8C, |
| 0x93F2: 0x5C3C, |
| 0x93F3: 0x5F10, |
| 0x93F4: 0x8FE9, |
| 0x93F5: 0x5302, |
| 0x93F6: 0x8CD1, |
| 0x93F7: 0x8089, |
| 0x93F8: 0x8679, |
| 0x93F9: 0x5EFF, |
| 0x93FA: 0x65E5, |
| 0x93FB: 0x4E73, |
| 0x93FC: 0x5165, |
| 0x9440: 0x5982, |
| 0x9441: 0x5C3F, |
| 0x9442: 0x97EE, |
| 0x9443: 0x4EFB, |
| 0x9444: 0x598A, |
| 0x9445: 0x5FCD, |
| 0x9446: 0x8A8D, |
| 0x9447: 0x6FE1, |
| 0x9448: 0x79B0, |
| 0x9449: 0x7962, |
| 0x944A: 0x5BE7, |
| 0x944B: 0x8471, |
| 0x944C: 0x732B, |
| 0x944D: 0x71B1, |
| 0x944E: 0x5E74, |
| 0x944F: 0x5FF5, |
| 0x9450: 0x637B, |
| 0x9451: 0x649A, |
| 0x9452: 0x71C3, |
| 0x9453: 0x7C98, |
| 0x9454: 0x4E43, |
| 0x9455: 0x5EFC, |
| 0x9456: 0x4E4B, |
| 0x9457: 0x57DC, |
| 0x9458: 0x56A2, |
| 0x9459: 0x60A9, |
| 0x945A: 0x6FC3, |
| 0x945B: 0x7D0D, |
| 0x945C: 0x80FD, |
| 0x945D: 0x8133, |
| 0x945E: 0x81BF, |
| 0x945F: 0x8FB2, |
| 0x9460: 0x8997, |
| 0x9461: 0x86A4, |
| 0x9462: 0x5DF4, |
| 0x9463: 0x628A, |
| 0x9464: 0x64AD, |
| 0x9465: 0x8987, |
| 0x9466: 0x6777, |
| 0x9467: 0x6CE2, |
| 0x9468: 0x6D3E, |
| 0x9469: 0x7436, |
| 0x946A: 0x7834, |
| 0x946B: 0x5A46, |
| 0x946C: 0x7F75, |
| 0x946D: 0x82AD, |
| 0x946E: 0x99AC, |
| 0x946F: 0x4FF3, |
| 0x9470: 0x5EC3, |
| 0x9471: 0x62DD, |
| 0x9472: 0x6392, |
| 0x9473: 0x6557, |
| 0x9474: 0x676F, |
| 0x9475: 0x76C3, |
| 0x9476: 0x724C, |
| 0x9477: 0x80CC, |
| 0x9478: 0x80BA, |
| 0x9479: 0x8F29, |
| 0x947A: 0x914D, |
| 0x947B: 0x500D, |
| 0x947C: 0x57F9, |
| 0x947D: 0x5A92, |
| 0x947E: 0x6885, |
| 0x9480: 0x6973, |
| 0x9481: 0x7164, |
| 0x9482: 0x72FD, |
| 0x9483: 0x8CB7, |
| 0x9484: 0x58F2, |
| 0x9485: 0x8CE0, |
| 0x9486: 0x966A, |
| 0x9487: 0x9019, |
| 0x9488: 0x877F, |
| 0x9489: 0x79E4, |
| 0x948A: 0x77E7, |
| 0x948B: 0x8429, |
| 0x948C: 0x4F2F, |
| 0x948D: 0x5265, |
| 0x948E: 0x535A, |
| 0x948F: 0x62CD, |
| 0x9490: 0x67CF, |
| 0x9491: 0x6CCA, |
| 0x9492: 0x767D, |
| 0x9493: 0x7B94, |
| 0x9494: 0x7C95, |
| 0x9495: 0x8236, |
| 0x9496: 0x8584, |
| 0x9497: 0x8FEB, |
| 0x9498: 0x66DD, |
| 0x9499: 0x6F20, |
| 0x949A: 0x7206, |
| 0x949B: 0x7E1B, |
| 0x949C: 0x83AB, |
| 0x949D: 0x99C1, |
| 0x949E: 0x9EA6, |
| 0x949F: 0x51FD, |
| 0x94A0: 0x7BB1, |
| 0x94A1: 0x7872, |
| 0x94A2: 0x7BB8, |
| 0x94A3: 0x8087, |
| 0x94A4: 0x7B48, |
| 0x94A5: 0x6AE8, |
| 0x94A6: 0x5E61, |
| 0x94A7: 0x808C, |
| 0x94A8: 0x7551, |
| 0x94A9: 0x7560, |
| 0x94AA: 0x516B, |
| 0x94AB: 0x9262, |
| 0x94AC: 0x6E8C, |
| 0x94AD: 0x767A, |
| 0x94AE: 0x9197, |
| 0x94AF: 0x9AEA, |
| 0x94B0: 0x4F10, |
| 0x94B1: 0x7F70, |
| 0x94B2: 0x629C, |
| 0x94B3: 0x7B4F, |
| 0x94B4: 0x95A5, |
| 0x94B5: 0x9CE9, |
| 0x94B6: 0x567A, |
| 0x94B7: 0x5859, |
| 0x94B8: 0x86E4, |
| 0x94B9: 0x96BC, |
| 0x94BA: 0x4F34, |
| 0x94BB: 0x5224, |
| 0x94BC: 0x534A, |
| 0x94BD: 0x53CD, |
| 0x94BE: 0x53DB, |
| 0x94BF: 0x5E06, |
| 0x94C0: 0x642C, |
| 0x94C1: 0x6591, |
| 0x94C2: 0x677F, |
| 0x94C3: 0x6C3E, |
| 0x94C4: 0x6C4E, |
| 0x94C5: 0x7248, |
| 0x94C6: 0x72AF, |
| 0x94C7: 0x73ED, |
| 0x94C8: 0x7554, |
| 0x94C9: 0x7E41, |
| 0x94CA: 0x822C, |
| 0x94CB: 0x85E9, |
| 0x94CC: 0x8CA9, |
| 0x94CD: 0x7BC4, |
| 0x94CE: 0x91C6, |
| 0x94CF: 0x7169, |
| 0x94D0: 0x9812, |
| 0x94D1: 0x98EF, |
| 0x94D2: 0x633D, |
| 0x94D3: 0x6669, |
| 0x94D4: 0x756A, |
| 0x94D5: 0x76E4, |
| 0x94D6: 0x78D0, |
| 0x94D7: 0x8543, |
| 0x94D8: 0x86EE, |
| 0x94D9: 0x532A, |
| 0x94DA: 0x5351, |
| 0x94DB: 0x5426, |
| 0x94DC: 0x5983, |
| 0x94DD: 0x5E87, |
| 0x94DE: 0x5F7C, |
| 0x94DF: 0x60B2, |
| 0x94E0: 0x6249, |
| 0x94E1: 0x6279, |
| 0x94E2: 0x62AB, |
| 0x94E3: 0x6590, |
| 0x94E4: 0x6BD4, |
| 0x94E5: 0x6CCC, |
| 0x94E6: 0x75B2, |
| 0x94E7: 0x76AE, |
| 0x94E8: 0x7891, |
| 0x94E9: 0x79D8, |
| 0x94EA: 0x7DCB, |
| 0x94EB: 0x7F77, |
| 0x94EC: 0x80A5, |
| 0x94ED: 0x88AB, |
| 0x94EE: 0x8AB9, |
| 0x94EF: 0x8CBB, |
| 0x94F0: 0x907F, |
| 0x94F1: 0x975E, |
| 0x94F2: 0x98DB, |
| 0x94F3: 0x6A0B, |
| 0x94F4: 0x7C38, |
| 0x94F5: 0x5099, |
| 0x94F6: 0x5C3E, |
| 0x94F7: 0x5FAE, |
| 0x94F8: 0x6787, |
| 0x94F9: 0x6BD8, |
| 0x94FA: 0x7435, |
| 0x94FB: 0x7709, |
| 0x94FC: 0x7F8E, |
| 0x9540: 0x9F3B, |
| 0x9541: 0x67CA, |
| 0x9542: 0x7A17, |
| 0x9543: 0x5339, |
| 0x9544: 0x758B, |
| 0x9545: 0x9AED, |
| 0x9546: 0x5F66, |
| 0x9547: 0x819D, |
| 0x9548: 0x83F1, |
| 0x9549: 0x8098, |
| 0x954A: 0x5F3C, |
| 0x954B: 0x5FC5, |
| 0x954C: 0x7562, |
| 0x954D: 0x7B46, |
| 0x954E: 0x903C, |
| 0x954F: 0x6867, |
| 0x9550: 0x59EB, |
| 0x9551: 0x5A9B, |
| 0x9552: 0x7D10, |
| 0x9553: 0x767E, |
| 0x9554: 0x8B2C, |
| 0x9555: 0x4FF5, |
| 0x9556: 0x5F6A, |
| 0x9557: 0x6A19, |
| 0x9558: 0x6C37, |
| 0x9559: 0x6F02, |
| 0x955A: 0x74E2, |
| 0x955B: 0x7968, |
| 0x955C: 0x8868, |
| 0x955D: 0x8A55, |
| 0x955E: 0x8C79, |
| 0x955F: 0x5EDF, |
| 0x9560: 0x63CF, |
| 0x9561: 0x75C5, |
| 0x9562: 0x79D2, |
| 0x9563: 0x82D7, |
| 0x9564: 0x9328, |
| 0x9565: 0x92F2, |
| 0x9566: 0x849C, |
| 0x9567: 0x86ED, |
| 0x9568: 0x9C2D, |
| 0x9569: 0x54C1, |
| 0x956A: 0x5F6C, |
| 0x956B: 0x658C, |
| 0x956C: 0x6D5C, |
| 0x956D: 0x7015, |
| 0x956E: 0x8CA7, |
| 0x956F: 0x8CD3, |
| 0x9570: 0x983B, |
| 0x9571: 0x654F, |
| 0x9572: 0x74F6, |
| 0x9573: 0x4E0D, |
| 0x9574: 0x4ED8, |
| 0x9575: 0x57E0, |
| 0x9576: 0x592B, |
| 0x9577: 0x5A66, |
| 0x9578: 0x5BCC, |
| 0x9579: 0x51A8, |
| 0x957A: 0x5E03, |
| 0x957B: 0x5E9C, |
| 0x957C: 0x6016, |
| 0x957D: 0x6276, |
| 0x957E: 0x6577, |
| 0x9580: 0x65A7, |
| 0x9581: 0x666E, |
| 0x9582: 0x6D6E, |
| 0x9583: 0x7236, |
| 0x9584: 0x7B26, |
| 0x9585: 0x8150, |
| 0x9586: 0x819A, |
| 0x9587: 0x8299, |
| 0x9588: 0x8B5C, |
| 0x9589: 0x8CA0, |
| 0x958A: 0x8CE6, |
| 0x958B: 0x8D74, |
| 0x958C: 0x961C, |
| 0x958D: 0x9644, |
| 0x958E: 0x4FAE, |
| 0x958F: 0x64AB, |
| 0x9590: 0x6B66, |
| 0x9591: 0x821E, |
| 0x9592: 0x8461, |
| 0x9593: 0x856A, |
| 0x9594: 0x90E8, |
| 0x9595: 0x5C01, |
| 0x9596: 0x6953, |
| 0x9597: 0x98A8, |
| 0x9598: 0x847A, |
| 0x9599: 0x8557, |
| 0x959A: 0x4F0F, |
| 0x959B: 0x526F, |
| 0x959C: 0x5FA9, |
| 0x959D: 0x5E45, |
| 0x959E: 0x670D, |
| 0x959F: 0x798F, |
| 0x95A0: 0x8179, |
| 0x95A1: 0x8907, |
| 0x95A2: 0x8986, |
| 0x95A3: 0x6DF5, |
| 0x95A4: 0x5F17, |
| 0x95A5: 0x6255, |
| 0x95A6: 0x6CB8, |
| 0x95A7: 0x4ECF, |
| 0x95A8: 0x7269, |
| 0x95A9: 0x9B92, |
| 0x95AA: 0x5206, |
| 0x95AB: 0x543B, |
| 0x95AC: 0x5674, |
| 0x95AD: 0x58B3, |
| 0x95AE: 0x61A4, |
| 0x95AF: 0x626E, |
| 0x95B0: 0x711A, |
| 0x95B1: 0x596E, |
| 0x95B2: 0x7C89, |
| 0x95B3: 0x7CDE, |
| 0x95B4: 0x7D1B, |
| 0x95B5: 0x96F0, |
| 0x95B6: 0x6587, |
| 0x95B7: 0x805E, |
| 0x95B8: 0x4E19, |
| 0x95B9: 0x4F75, |
| 0x95BA: 0x5175, |
| 0x95BB: 0x5840, |
| 0x95BC: 0x5E63, |
| 0x95BD: 0x5E73, |
| 0x95BE: 0x5F0A, |
| 0x95BF: 0x67C4, |
| 0x95C0: 0x4E26, |
| 0x95C1: 0x853D, |
| 0x95C2: 0x9589, |
| 0x95C3: 0x965B, |
| 0x95C4: 0x7C73, |
| 0x95C5: 0x9801, |
| 0x95C6: 0x50FB, |
| 0x95C7: 0x58C1, |
| 0x95C8: 0x7656, |
| 0x95C9: 0x78A7, |
| 0x95CA: 0x5225, |
| 0x95CB: 0x77A5, |
| 0x95CC: 0x8511, |
| 0x95CD: 0x7B86, |
| 0x95CE: 0x504F, |
| 0x95CF: 0x5909, |
| 0x95D0: 0x7247, |
| 0x95D1: 0x7BC7, |
| 0x95D2: 0x7DE8, |
| 0x95D3: 0x8FBA, |
| 0x95D4: 0x8FD4, |
| 0x95D5: 0x904D, |
| 0x95D6: 0x4FBF, |
| 0x95D7: 0x52C9, |
| 0x95D8: 0x5A29, |
| 0x95D9: 0x5F01, |
| 0x95DA: 0x97AD, |
| 0x95DB: 0x4FDD, |
| 0x95DC: 0x8217, |
| 0x95DD: 0x92EA, |
| 0x95DE: 0x5703, |
| 0x95DF: 0x6355, |
| 0x95E0: 0x6B69, |
| 0x95E1: 0x752B, |
| 0x95E2: 0x88DC, |
| 0x95E3: 0x8F14, |
| 0x95E4: 0x7A42, |
| 0x95E5: 0x52DF, |
| 0x95E6: 0x5893, |
| 0x95E7: 0x6155, |
| 0x95E8: 0x620A, |
| 0x95E9: 0x66AE, |
| 0x95EA: 0x6BCD, |
| 0x95EB: 0x7C3F, |
| 0x95EC: 0x83E9, |
| 0x95ED: 0x5023, |
| 0x95EE: 0x4FF8, |
| 0x95EF: 0x5305, |
| 0x95F0: 0x5446, |
| 0x95F1: 0x5831, |
| 0x95F2: 0x5949, |
| 0x95F3: 0x5B9D, |
| 0x95F4: 0x5CF0, |
| 0x95F5: 0x5CEF, |
| 0x95F6: 0x5D29, |
| 0x95F7: 0x5E96, |
| 0x95F8: 0x62B1, |
| 0x95F9: 0x6367, |
| 0x95FA: 0x653E, |
| 0x95FB: 0x65B9, |
| 0x95FC: 0x670B, |
| 0x9640: 0x6CD5, |
| 0x9641: 0x6CE1, |
| 0x9642: 0x70F9, |
| 0x9643: 0x7832, |
| 0x9644: 0x7E2B, |
| 0x9645: 0x80DE, |
| 0x9646: 0x82B3, |
| 0x9647: 0x840C, |
| 0x9648: 0x84EC, |
| 0x9649: 0x8702, |
| 0x964A: 0x8912, |
| 0x964B: 0x8A2A, |
| 0x964C: 0x8C4A, |
| 0x964D: 0x90A6, |
| 0x964E: 0x92D2, |
| 0x964F: 0x98FD, |
| 0x9650: 0x9CF3, |
| 0x9651: 0x9D6C, |
| 0x9652: 0x4E4F, |
| 0x9653: 0x4EA1, |
| 0x9654: 0x508D, |
| 0x9655: 0x5256, |
| 0x9656: 0x574A, |
| 0x9657: 0x59A8, |
| 0x9658: 0x5E3D, |
| 0x9659: 0x5FD8, |
| 0x965A: 0x5FD9, |
| 0x965B: 0x623F, |
| 0x965C: 0x66B4, |
| 0x965D: 0x671B, |
| 0x965E: 0x67D0, |
| 0x965F: 0x68D2, |
| 0x9660: 0x5192, |
| 0x9661: 0x7D21, |
| 0x9662: 0x80AA, |
| 0x9663: 0x81A8, |
| 0x9664: 0x8B00, |
| 0x9665: 0x8C8C, |
| 0x9666: 0x8CBF, |
| 0x9667: 0x927E, |
| 0x9668: 0x9632, |
| 0x9669: 0x5420, |
| 0x966A: 0x982C, |
| 0x966B: 0x5317, |
| 0x966C: 0x50D5, |
| 0x966D: 0x535C, |
| 0x966E: 0x58A8, |
| 0x966F: 0x64B2, |
| 0x9670: 0x6734, |
| 0x9671: 0x7267, |
| 0x9672: 0x7766, |
| 0x9673: 0x7A46, |
| 0x9674: 0x91E6, |
| 0x9675: 0x52C3, |
| 0x9676: 0x6CA1, |
| 0x9677: 0x6B86, |
| 0x9678: 0x5800, |
| 0x9679: 0x5E4C, |
| 0x967A: 0x5954, |
| 0x967B: 0x672C, |
| 0x967C: 0x7FFB, |
| 0x967D: 0x51E1, |
| 0x967E: 0x76C6, |
| 0x9680: 0x6469, |
| 0x9681: 0x78E8, |
| 0x9682: 0x9B54, |
| 0x9683: 0x9EBB, |
| 0x9684: 0x57CB, |
| 0x9685: 0x59B9, |
| 0x9686: 0x6627, |
| 0x9687: 0x679A, |
| 0x9688: 0x6BCE, |
| 0x9689: 0x54E9, |
| 0x968A: 0x69D9, |
| 0x968B: 0x5E55, |
| 0x968C: 0x819C, |
| 0x968D: 0x6795, |
| 0x968E: 0x9BAA, |
| 0x968F: 0x67FE, |
| 0x9690: 0x9C52, |
| 0x9691: 0x685D, |
| 0x9692: 0x4EA6, |
| 0x9693: 0x4FE3, |
| 0x9694: 0x53C8, |
| 0x9695: 0x62B9, |
| 0x9696: 0x672B, |
| 0x9697: 0x6CAB, |
| 0x9698: 0x8FC4, |
| 0x9699: 0x4FAD, |
| 0x969A: 0x7E6D, |
| 0x969B: 0x9EBF, |
| 0x969C: 0x4E07, |
| 0x969D: 0x6162, |
| 0x969E: 0x6E80, |
| 0x969F: 0x6F2B, |
| 0x96A0: 0x8513, |
| 0x96A1: 0x5473, |
| 0x96A2: 0x672A, |
| 0x96A3: 0x9B45, |
| 0x96A4: 0x5DF3, |
| 0x96A5: 0x7B95, |
| 0x96A6: 0x5CAC, |
| 0x96A7: 0x5BC6, |
| 0x96A8: 0x871C, |
| 0x96A9: 0x6E4A, |
| 0x96AA: 0x84D1, |
| 0x96AB: 0x7A14, |
| 0x96AC: 0x8108, |
| 0x96AD: 0x5999, |
| 0x96AE: 0x7C8D, |
| 0x96AF: 0x6C11, |
| 0x96B0: 0x7720, |
| 0x96B1: 0x52D9, |
| 0x96B2: 0x5922, |
| 0x96B3: 0x7121, |
| 0x96B4: 0x725F, |
| 0x96B5: 0x77DB, |
| 0x96B6: 0x9727, |
| 0x96B7: 0x9D61, |
| 0x96B8: 0x690B, |
| 0x96B9: 0x5A7F, |
| 0x96BA: 0x5A18, |
| 0x96BB: 0x51A5, |
| 0x96BC: 0x540D, |
| 0x96BD: 0x547D, |
| 0x96BE: 0x660E, |
| 0x96BF: 0x76DF, |
| 0x96C0: 0x8FF7, |
| 0x96C1: 0x9298, |
| 0x96C2: 0x9CF4, |
| 0x96C3: 0x59EA, |
| 0x96C4: 0x725D, |
| 0x96C5: 0x6EC5, |
| 0x96C6: 0x514D, |
| 0x96C7: 0x68C9, |
| 0x96C8: 0x7DBF, |
| 0x96C9: 0x7DEC, |
| 0x96CA: 0x9762, |
| 0x96CB: 0x9EBA, |
| 0x96CC: 0x6478, |
| 0x96CD: 0x6A21, |
| 0x96CE: 0x8302, |
| 0x96CF: 0x5984, |
| 0x96D0: 0x5B5F, |
| 0x96D1: 0x6BDB, |
| 0x96D2: 0x731B, |
| 0x96D3: 0x76F2, |
| 0x96D4: 0x7DB2, |
| 0x96D5: 0x8017, |
| 0x96D6: 0x8499, |
| 0x96D7: 0x5132, |
| 0x96D8: 0x6728, |
| 0x96D9: 0x9ED9, |
| 0x96DA: 0x76EE, |
| 0x96DB: 0x6762, |
| 0x96DC: 0x52FF, |
| 0x96DD: 0x9905, |
| 0x96DE: 0x5C24, |
| 0x96DF: 0x623B, |
| 0x96E0: 0x7C7E, |
| 0x96E1: 0x8CB0, |
| 0x96E2: 0x554F, |
| 0x96E3: 0x60B6, |
| 0x96E4: 0x7D0B, |
| 0x96E5: 0x9580, |
| 0x96E6: 0x5301, |
| 0x96E7: 0x4E5F, |
| 0x96E8: 0x51B6, |
| 0x96E9: 0x591C, |
| 0x96EA: 0x723A, |
| 0x96EB: 0x8036, |
| 0x96EC: 0x91CE, |
| 0x96ED: 0x5F25, |
| 0x96EE: 0x77E2, |
| 0x96EF: 0x5384, |
| 0x96F0: 0x5F79, |
| 0x96F1: 0x7D04, |
| 0x96F2: 0x85AC, |
| 0x96F3: 0x8A33, |
| 0x96F4: 0x8E8D, |
| 0x96F5: 0x9756, |
| 0x96F6: 0x67F3, |
| 0x96F7: 0x85AE, |
| 0x96F8: 0x9453, |
| 0x96F9: 0x6109, |
| 0x96FA: 0x6108, |
| 0x96FB: 0x6CB9, |
| 0x96FC: 0x7652, |
| 0x9740: 0x8AED, |
| 0x9741: 0x8F38, |
| 0x9742: 0x552F, |
| 0x9743: 0x4F51, |
| 0x9744: 0x512A, |
| 0x9745: 0x52C7, |
| 0x9746: 0x53CB, |
| 0x9747: 0x5BA5, |
| 0x9748: 0x5E7D, |
| 0x9749: 0x60A0, |
| 0x974A: 0x6182, |
| 0x974B: 0x63D6, |
| 0x974C: 0x6709, |
| 0x974D: 0x67DA, |
| 0x974E: 0x6E67, |
| 0x974F: 0x6D8C, |
| 0x9750: 0x7336, |
| 0x9751: 0x7337, |
| 0x9752: 0x7531, |
| 0x9753: 0x7950, |
| 0x9754: 0x88D5, |
| 0x9755: 0x8A98, |
| 0x9756: 0x904A, |
| 0x9757: 0x9091, |
| 0x9758: 0x90F5, |
| 0x9759: 0x96C4, |
| 0x975A: 0x878D, |
| 0x975B: 0x5915, |
| 0x975C: 0x4E88, |
| 0x975D: 0x4F59, |
| 0x975E: 0x4E0E, |
| 0x975F: 0x8A89, |
| 0x9760: 0x8F3F, |
| 0x9761: 0x9810, |
| 0x9762: 0x50AD, |
| 0x9763: 0x5E7C, |
| 0x9764: 0x5996, |
| 0x9765: 0x5BB9, |
| 0x9766: 0x5EB8, |
| 0x9767: 0x63DA, |
| 0x9768: 0x63FA, |
| 0x9769: 0x64C1, |
| 0x976A: 0x66DC, |
| 0x976B: 0x694A, |
| 0x976C: 0x69D8, |
| 0x976D: 0x6D0B, |
| 0x976E: 0x6EB6, |
| 0x976F: 0x7194, |
| 0x9770: 0x7528, |
| 0x9771: 0x7AAF, |
| 0x9772: 0x7F8A, |
| 0x9773: 0x8000, |
| 0x9774: 0x8449, |
| 0x9775: 0x84C9, |
| 0x9776: 0x8981, |
| 0x9777: 0x8B21, |
| 0x9778: 0x8E0A, |
| 0x9779: 0x9065, |
| 0x977A: 0x967D, |
| 0x977B: 0x990A, |
| 0x977C: 0x617E, |
| 0x977D: 0x6291, |
| 0x977E: 0x6B32, |
| 0x9780: 0x6C83, |
| 0x9781: 0x6D74, |
| 0x9782: 0x7FCC, |
| 0x9783: 0x7FFC, |
| 0x9784: 0x6DC0, |
| 0x9785: 0x7F85, |
| 0x9786: 0x87BA, |
| 0x9787: 0x88F8, |
| 0x9788: 0x6765, |
| 0x9789: 0x83B1, |
| 0x978A: 0x983C, |
| 0x978B: 0x96F7, |
| 0x978C: 0x6D1B, |
| 0x978D: 0x7D61, |
| 0x978E: 0x843D, |
| 0x978F: 0x916A, |
| 0x9790: 0x4E71, |
| 0x9791: 0x5375, |
| 0x9792: 0x5D50, |
| 0x9793: 0x6B04, |
| 0x9794: 0x6FEB, |
| 0x9795: 0x85CD, |
| 0x9796: 0x862D, |
| 0x9797: 0x89A7, |
| 0x9798: 0x5229, |
| 0x9799: 0x540F, |
| 0x979A: 0x5C65, |
| 0x979B: 0x674E, |
| 0x979C: 0x68A8, |
| 0x979D: 0x7406, |
| 0x979E: 0x7483, |
| 0x979F: 0x75E2, |
| 0x97A0: 0x88CF, |
| 0x97A1: 0x88E1, |
| 0x97A2: 0x91CC, |
| 0x97A3: 0x96E2, |
| 0x97A4: 0x9678, |
| 0x97A5: 0x5F8B, |
| 0x97A6: 0x7387, |
| 0x97A7: 0x7ACB, |
| 0x97A8: 0x844E, |
| 0x97A9: 0x63A0, |
| 0x97AA: 0x7565, |
| 0x97AB: 0x5289, |
| 0x97AC: 0x6D41, |
| 0x97AD: 0x6E9C, |
| 0x97AE: 0x7409, |
| 0x97AF: 0x7559, |
| 0x97B0: 0x786B, |
| 0x97B1: 0x7C92, |
| 0x97B2: 0x9686, |
| 0x97B3: 0x7ADC, |
| 0x97B4: 0x9F8D, |
| 0x97B5: 0x4FB6, |
| 0x97B6: 0x616E, |
| 0x97B7: 0x65C5, |
| 0x97B8: 0x865C, |
| 0x97B9: 0x4E86, |
| 0x97BA: 0x4EAE, |
| 0x97BB: 0x50DA, |
| 0x97BC: 0x4E21, |
| 0x97BD: 0x51CC, |
| 0x97BE: 0x5BEE, |
| 0x97BF: 0x6599, |
| 0x97C0: 0x6881, |
| 0x97C1: 0x6DBC, |
| 0x97C2: 0x731F, |
| 0x97C3: 0x7642, |
| 0x97C4: 0x77AD, |
| 0x97C5: 0x7A1C, |
| 0x97C6: 0x7CE7, |
| 0x97C7: 0x826F, |
| 0x97C8: 0x8AD2, |
| 0x97C9: 0x907C, |
| 0x97CA: 0x91CF, |
| 0x97CB: 0x9675, |
| 0x97CC: 0x9818, |
| 0x97CD: 0x529B, |
| 0x97CE: 0x7DD1, |
| 0x97CF: 0x502B, |
| 0x97D0: 0x5398, |
| 0x97D1: 0x6797, |
| 0x97D2: 0x6DCB, |
| 0x97D3: 0x71D0, |
| 0x97D4: 0x7433, |
| 0x97D5: 0x81E8, |
| 0x97D6: 0x8F2A, |
| 0x97D7: 0x96A3, |
| 0x97D8: 0x9C57, |
| 0x97D9: 0x9E9F, |
| 0x97DA: 0x7460, |
| 0x97DB: 0x5841, |
| 0x97DC: 0x6D99, |
| 0x97DD: 0x7D2F, |
| 0x97DE: 0x985E, |
| 0x97DF: 0x4EE4, |
| 0x97E0: 0x4F36, |
| 0x97E1: 0x4F8B, |
| 0x97E2: 0x51B7, |
| 0x97E3: 0x52B1, |
| 0x97E4: 0x5DBA, |
| 0x97E5: 0x601C, |
| 0x97E6: 0x73B2, |
| 0x97E7: 0x793C, |
| 0x97E8: 0x82D3, |
| 0x97E9: 0x9234, |
| 0x97EA: 0x96B7, |
| 0x97EB: 0x96F6, |
| 0x97EC: 0x970A, |
| 0x97ED: 0x9E97, |
| 0x97EE: 0x9F62, |
| 0x97EF: 0x66A6, |
| 0x97F0: 0x6B74, |
| 0x97F1: 0x5217, |
| 0x97F2: 0x52A3, |
| 0x97F3: 0x70C8, |
| 0x97F4: 0x88C2, |
| 0x97F5: 0x5EC9, |
| 0x97F6: 0x604B, |
| 0x97F7: 0x6190, |
| 0x97F8: 0x6F23, |
| 0x97F9: 0x7149, |
| 0x97FA: 0x7C3E, |
| 0x97FB: 0x7DF4, |
| 0x97FC: 0x806F, |
| 0x9840: 0x84EE, |
| 0x9841: 0x9023, |
| 0x9842: 0x932C, |
| 0x9843: 0x5442, |
| 0x9844: 0x9B6F, |
| 0x9845: 0x6AD3, |
| 0x9846: 0x7089, |
| 0x9847: 0x8CC2, |
| 0x9848: 0x8DEF, |
| 0x9849: 0x9732, |
| 0x984A: 0x52B4, |
| 0x984B: 0x5A41, |
| 0x984C: 0x5ECA, |
| 0x984D: 0x5F04, |
| 0x984E: 0x6717, |
| 0x984F: 0x697C, |
| 0x9850: 0x6994, |
| 0x9851: 0x6D6A, |
| 0x9852: 0x6F0F, |
| 0x9853: 0x7262, |
| 0x9854: 0x72FC, |
| 0x9855: 0x7BED, |
| 0x9856: 0x8001, |
| 0x9857: 0x807E, |
| 0x9858: 0x874B, |
| 0x9859: 0x90CE, |
| 0x985A: 0x516D, |
| 0x985B: 0x9E93, |
| 0x985C: 0x7984, |
| 0x985D: 0x808B, |
| 0x985E: 0x9332, |
| 0x985F: 0x8AD6, |
| 0x9860: 0x502D, |
| 0x9861: 0x548C, |
| 0x9862: 0x8A71, |
| 0x9863: 0x6B6A, |
| 0x9864: 0x8CC4, |
| 0x9865: 0x8107, |
| 0x9866: 0x60D1, |
| 0x9867: 0x67A0, |
| 0x9868: 0x9DF2, |
| 0x9869: 0x4E99, |
| 0x986A: 0x4E98, |
| 0x986B: 0x9C10, |
| 0x986C: 0x8A6B, |
| 0x986D: 0x85C1, |
| 0x986E: 0x8568, |
| 0x986F: 0x6900, |
| 0x9870: 0x6E7E, |
| 0x9871: 0x7897, |
| 0x9872: 0x8155, |
| 0x989F: 0x5F0C, |
| 0x98A0: 0x4E10, |
| 0x98A1: 0x4E15, |
| 0x98A2: 0x4E2A, |
| 0x98A3: 0x4E31, |
| 0x98A4: 0x4E36, |
| 0x98A5: 0x4E3C, |
| 0x98A6: 0x4E3F, |
| 0x98A7: 0x4E42, |
| 0x98A8: 0x4E56, |
| 0x98A9: 0x4E58, |
| 0x98AA: 0x4E82, |
| 0x98AB: 0x4E85, |
| 0x98AC: 0x8C6B, |
| 0x98AD: 0x4E8A, |
| 0x98AE: 0x8212, |
| 0x98AF: 0x5F0D, |
| 0x98B0: 0x4E8E, |
| 0x98B1: 0x4E9E, |
| 0x98B2: 0x4E9F, |
| 0x98B3: 0x4EA0, |
| 0x98B4: 0x4EA2, |
| 0x98B5: 0x4EB0, |
| 0x98B6: 0x4EB3, |
| 0x98B7: 0x4EB6, |
| 0x98B8: 0x4ECE, |
| 0x98B9: 0x4ECD, |
| 0x98BA: 0x4EC4, |
| 0x98BB: 0x4EC6, |
| 0x98BC: 0x4EC2, |
| 0x98BD: 0x4ED7, |
| 0x98BE: 0x4EDE, |
| 0x98BF: 0x4EED, |
| 0x98C0: 0x4EDF, |
| 0x98C1: 0x4EF7, |
| 0x98C2: 0x4F09, |
| 0x98C3: 0x4F5A, |
| 0x98C4: 0x4F30, |
| 0x98C5: 0x4F5B, |
| 0x98C6: 0x4F5D, |
| 0x98C7: 0x4F57, |
| 0x98C8: 0x4F47, |
| 0x98C9: 0x4F76, |
| 0x98CA: 0x4F88, |
| 0x98CB: 0x4F8F, |
| 0x98CC: 0x4F98, |
| 0x98CD: 0x4F7B, |
| 0x98CE: 0x4F69, |
| 0x98CF: 0x4F70, |
| 0x98D0: 0x4F91, |
| 0x98D1: 0x4F6F, |
| 0x98D2: 0x4F86, |
| 0x98D3: 0x4F96, |
| 0x98D4: 0x5118, |
| 0x98D5: 0x4FD4, |
| 0x98D6: 0x4FDF, |
| 0x98D7: 0x4FCE, |
| 0x98D8: 0x4FD8, |
| 0x98D9: 0x4FDB, |
| 0x98DA: 0x4FD1, |
| 0x98DB: 0x4FDA, |
| 0x98DC: 0x4FD0, |
| 0x98DD: 0x4FE4, |
| 0x98DE: 0x4FE5, |
| 0x98DF: 0x501A, |
| 0x98E0: 0x5028, |
| 0x98E1: 0x5014, |
| 0x98E2: 0x502A, |
| 0x98E3: 0x5025, |
| 0x98E4: 0x5005, |
| 0x98E5: 0x4F1C, |
| 0x98E6: 0x4FF6, |
| 0x98E7: 0x5021, |
| 0x98E8: 0x5029, |
| 0x98E9: 0x502C, |
| 0x98EA: 0x4FFE, |
| 0x98EB: 0x4FEF, |
| 0x98EC: 0x5011, |
| 0x98ED: 0x5006, |
| 0x98EE: 0x5043, |
| 0x98EF: 0x5047, |
| 0x98F0: 0x6703, |
| 0x98F1: 0x5055, |
| 0x98F2: 0x5050, |
| 0x98F3: 0x5048, |
| 0x98F4: 0x505A, |
| 0x98F5: 0x5056, |
| 0x98F6: 0x506C, |
| 0x98F7: 0x5078, |
| 0x98F8: 0x5080, |
| 0x98F9: 0x509A, |
| 0x98FA: 0x5085, |
| 0x98FB: 0x50B4, |
| 0x98FC: 0x50B2, |
| 0x9940: 0x50C9, |
| 0x9941: 0x50CA, |
| 0x9942: 0x50B3, |
| 0x9943: 0x50C2, |
| 0x9944: 0x50D6, |
| 0x9945: 0x50DE, |
| 0x9946: 0x50E5, |
| 0x9947: 0x50ED, |
| 0x9948: 0x50E3, |
| 0x9949: 0x50EE, |
| 0x994A: 0x50F9, |
| 0x994B: 0x50F5, |
| 0x994C: 0x5109, |
| 0x994D: 0x5101, |
| 0x994E: 0x5102, |
| 0x994F: 0x5116, |
| 0x9950: 0x5115, |
| 0x9951: 0x5114, |
| 0x9952: 0x511A, |
| 0x9953: 0x5121, |
| 0x9954: 0x513A, |
| 0x9955: 0x5137, |
| 0x9956: 0x513C, |
| 0x9957: 0x513B, |
| 0x9958: 0x513F, |
| 0x9959: 0x5140, |
| 0x995A: 0x5152, |
| 0x995B: 0x514C, |
| 0x995C: 0x5154, |
| 0x995D: 0x5162, |
| 0x995E: 0x7AF8, |
| 0x995F: 0x5169, |
| 0x9960: 0x516A, |
| 0x9961: 0x516E, |
| 0x9962: 0x5180, |
| 0x9963: 0x5182, |
| 0x9964: 0x56D8, |
| 0x9965: 0x518C, |
| 0x9966: 0x5189, |
| 0x9967: 0x518F, |
| 0x9968: 0x5191, |
| 0x9969: 0x5193, |
| 0x996A: 0x5195, |
| 0x996B: 0x5196, |
| 0x996C: 0x51A4, |
| 0x996D: 0x51A6, |
| 0x996E: 0x51A2, |
| 0x996F: 0x51A9, |
| 0x9970: 0x51AA, |
| 0x9971: 0x51AB, |
| 0x9972: 0x51B3, |
| 0x9973: 0x51B1, |
| 0x9974: 0x51B2, |
| 0x9975: 0x51B0, |
| 0x9976: 0x51B5, |
| 0x9977: 0x51BD, |
| 0x9978: 0x51C5, |
| 0x9979: 0x51C9, |
| 0x997A: 0x51DB, |
| 0x997B: 0x51E0, |
| 0x997C: 0x8655, |
| 0x997D: 0x51E9, |
| 0x997E: 0x51ED, |
| 0x9980: 0x51F0, |
| 0x9981: 0x51F5, |
| 0x9982: 0x51FE, |
| 0x9983: 0x5204, |
| 0x9984: 0x520B, |
| 0x9985: 0x5214, |
| 0x9986: 0x520E, |
| 0x9987: 0x5227, |
| 0x9988: 0x522A, |
| 0x9989: 0x522E, |
| 0x998A: 0x5233, |
| 0x998B: 0x5239, |
| 0x998C: 0x524F, |
| 0x998D: 0x5244, |
| 0x998E: 0x524B, |
| 0x998F: 0x524C, |
| 0x9990: 0x525E, |
| 0x9991: 0x5254, |
| 0x9992: 0x526A, |
| 0x9993: 0x5274, |
| 0x9994: 0x5269, |
| 0x9995: 0x5273, |
| 0x9996: 0x527F, |
| 0x9997: 0x527D, |
| 0x9998: 0x528D, |
| 0x9999: 0x5294, |
| 0x999A: 0x5292, |
| 0x999B: 0x5271, |
| 0x999C: 0x5288, |
| 0x999D: 0x5291, |
| 0x999E: 0x8FA8, |
| 0x999F: 0x8FA7, |
| 0x99A0: 0x52AC, |
| 0x99A1: 0x52AD, |
| 0x99A2: 0x52BC, |
| 0x99A3: 0x52B5, |
| 0x99A4: 0x52C1, |
| 0x99A5: 0x52CD, |
| 0x99A6: 0x52D7, |
| 0x99A7: 0x52DE, |
| 0x99A8: 0x52E3, |
| 0x99A9: 0x52E6, |
| 0x99AA: 0x98ED, |
| 0x99AB: 0x52E0, |
| 0x99AC: 0x52F3, |
| 0x99AD: 0x52F5, |
| 0x99AE: 0x52F8, |
| 0x99AF: 0x52F9, |
| 0x99B0: 0x5306, |
| 0x99B1: 0x5308, |
| 0x99B2: 0x7538, |
| 0x99B3: 0x530D, |
| 0x99B4: 0x5310, |
| 0x99B5: 0x530F, |
| 0x99B6: 0x5315, |
| 0x99B7: 0x531A, |
| 0x99B8: 0x5323, |
| 0x99B9: 0x532F, |
| 0x99BA: 0x5331, |
| 0x99BB: 0x5333, |
| 0x99BC: 0x5338, |
| 0x99BD: 0x5340, |
| 0x99BE: 0x5346, |
| 0x99BF: 0x5345, |
| 0x99C0: 0x4E17, |
| 0x99C1: 0x5349, |
| 0x99C2: 0x534D, |
| 0x99C3: 0x51D6, |
| 0x99C4: 0x535E, |
| 0x99C5: 0x5369, |
| 0x99C6: 0x536E, |
| 0x99C7: 0x5918, |
| 0x99C8: 0x537B, |
| 0x99C9: 0x5377, |
| 0x99CA: 0x5382, |
| 0x99CB: 0x5396, |
| 0x99CC: 0x53A0, |
| 0x99CD: 0x53A6, |
| 0x99CE: 0x53A5, |
| 0x99CF: 0x53AE, |
| 0x99D0: 0x53B0, |
| 0x99D1: 0x53B6, |
| 0x99D2: 0x53C3, |
| 0x99D3: 0x7C12, |
| 0x99D4: 0x96D9, |
| 0x99D5: 0x53DF, |
| 0x99D6: 0x66FC, |
| 0x99D7: 0x71EE, |
| 0x99D8: 0x53EE, |
| 0x99D9: 0x53E8, |
| 0x99DA: 0x53ED, |
| 0x99DB: 0x53FA, |
| 0x99DC: 0x5401, |
| 0x99DD: 0x543D, |
| 0x99DE: 0x5440, |
| 0x99DF: 0x542C, |
| 0x99E0: 0x542D, |
| 0x99E1: 0x543C, |
| 0x99E2: 0x542E, |
| 0x99E3: 0x5436, |
| 0x99E4: 0x5429, |
| 0x99E5: 0x541D, |
| 0x99E6: 0x544E, |
| 0x99E7: 0x548F, |
| 0x99E8: 0x5475, |
| 0x99E9: 0x548E, |
| 0x99EA: 0x545F, |
| 0x99EB: 0x5471, |
| 0x99EC: 0x5477, |
| 0x99ED: 0x5470, |
| 0x99EE: 0x5492, |
| 0x99EF: 0x547B, |
| 0x99F0: 0x5480, |
| 0x99F1: 0x5476, |
| 0x99F2: 0x5484, |
| 0x99F3: 0x5490, |
| 0x99F4: 0x5486, |
| 0x99F5: 0x54C7, |
| 0x99F6: 0x54A2, |
| 0x99F7: 0x54B8, |
| 0x99F8: 0x54A5, |
| 0x99F9: 0x54AC, |
| 0x99FA: 0x54C4, |
| 0x99FB: 0x54C8, |
| 0x99FC: 0x54A8, |
| 0x9A40: 0x54AB, |
| 0x9A41: 0x54C2, |
| 0x9A42: 0x54A4, |
| 0x9A43: 0x54BE, |
| 0x9A44: 0x54BC, |
| 0x9A45: 0x54D8, |
| 0x9A46: 0x54E5, |
| 0x9A47: 0x54E6, |
| 0x9A48: 0x550F, |
| 0x9A49: 0x5514, |
| 0x9A4A: 0x54FD, |
| 0x9A4B: 0x54EE, |
| 0x9A4C: 0x54ED, |
| 0x9A4D: 0x54FA, |
| 0x9A4E: 0x54E2, |
| 0x9A4F: 0x5539, |
| 0x9A50: 0x5540, |
| 0x9A51: 0x5563, |
| 0x9A52: 0x554C, |
| 0x9A53: 0x552E, |
| 0x9A54: 0x555C, |
| 0x9A55: 0x5545, |
| 0x9A56: 0x5556, |
| 0x9A57: 0x5557, |
| 0x9A58: 0x5538, |
| 0x9A59: 0x5533, |
| 0x9A5A: 0x555D, |
| 0x9A5B: 0x5599, |
| 0x9A5C: 0x5580, |
| 0x9A5D: 0x54AF, |
| 0x9A5E: 0x558A, |
| 0x9A5F: 0x559F, |
| 0x9A60: 0x557B, |
| 0x9A61: 0x557E, |
| 0x9A62: 0x5598, |
| 0x9A63: 0x559E, |
| 0x9A64: 0x55AE, |
| 0x9A65: 0x557C, |
| 0x9A66: 0x5583, |
| 0x9A67: 0x55A9, |
| 0x9A68: 0x5587, |
| 0x9A69: 0x55A8, |
| 0x9A6A: 0x55DA, |
| 0x9A6B: 0x55C5, |
| 0x9A6C: 0x55DF, |
| 0x9A6D: 0x55C4, |
| 0x9A6E: 0x55DC, |
| 0x9A6F: 0x55E4, |
| 0x9A70: 0x55D4, |
| 0x9A71: 0x5614, |
| 0x9A72: 0x55F7, |
| 0x9A73: 0x5616, |
| 0x9A74: 0x55FE, |
| 0x9A75: 0x55FD, |
| 0x9A76: 0x561B, |
| 0x9A77: 0x55F9, |
| 0x9A78: 0x564E, |
| 0x9A79: 0x5650, |
| 0x9A7A: 0x71DF, |
| 0x9A7B: 0x5634, |
| 0x9A7C: 0x5636, |
| 0x9A7D: 0x5632, |
| 0x9A7E: 0x5638, |
| 0x9A80: 0x566B, |
| 0x9A81: 0x5664, |
| 0x9A82: 0x562F, |
| 0x9A83: 0x566C, |
| 0x9A84: 0x566A, |
| 0x9A85: 0x5686, |
| 0x9A86: 0x5680, |
| 0x9A87: 0x568A, |
| 0x9A88: 0x56A0, |
| 0x9A89: 0x5694, |
| 0x9A8A: 0x568F, |
| 0x9A8B: 0x56A5, |
| 0x9A8C: 0x56AE, |
| 0x9A8D: 0x56B6, |
| 0x9A8E: 0x56B4, |
| 0x9A8F: 0x56C2, |
| 0x9A90: 0x56BC, |
| 0x9A91: 0x56C1, |
| 0x9A92: 0x56C3, |
| 0x9A93: 0x56C0, |
| 0x9A94: 0x56C8, |
| 0x9A95: 0x56CE, |
| 0x9A96: 0x56D1, |
| 0x9A97: 0x56D3, |
| 0x9A98: 0x56D7, |
| 0x9A99: 0x56EE, |
| 0x9A9A: 0x56F9, |
| 0x9A9B: 0x5700, |
| 0x9A9C: 0x56FF, |
| 0x9A9D: 0x5704, |
| 0x9A9E: 0x5709, |
| 0x9A9F: 0x5708, |
| 0x9AA0: 0x570B, |
| 0x9AA1: 0x570D, |
| 0x9AA2: 0x5713, |
| 0x9AA3: 0x5718, |
| 0x9AA4: 0x5716, |
| 0x9AA5: 0x55C7, |
| 0x9AA6: 0x571C, |
| 0x9AA7: 0x5726, |
| 0x9AA8: 0x5737, |
| 0x9AA9: 0x5738, |
| 0x9AAA: 0x574E, |
| 0x9AAB: 0x573B, |
| 0x9AAC: 0x5740, |
| 0x9AAD: 0x574F, |
| 0x9AAE: 0x5769, |
| 0x9AAF: 0x57C0, |
| 0x9AB0: 0x5788, |
| 0x9AB1: 0x5761, |
| 0x9AB2: 0x577F, |
| 0x9AB3: 0x5789, |
| 0x9AB4: 0x5793, |
| 0x9AB5: 0x57A0, |
| 0x9AB6: 0x57B3, |
| 0x9AB7: 0x57A4, |
| 0x9AB8: 0x57AA, |
| 0x9AB9: 0x57B0, |
| 0x9ABA: 0x57C3, |
| 0x9ABB: 0x57C6, |
| 0x9ABC: 0x57D4, |
| 0x9ABD: 0x57D2, |
| 0x9ABE: 0x57D3, |
| 0x9ABF: 0x580A, |
| 0x9AC0: 0x57D6, |
| 0x9AC1: 0x57E3, |
| 0x9AC2: 0x580B, |
| 0x9AC3: 0x5819, |
| 0x9AC4: 0x581D, |
| 0x9AC5: 0x5872, |
| 0x9AC6: 0x5821, |
| 0x9AC7: 0x5862, |
| 0x9AC8: 0x584B, |
| 0x9AC9: 0x5870, |
| 0x9ACA: 0x6BC0, |
| 0x9ACB: 0x5852, |
| 0x9ACC: 0x583D, |
| 0x9ACD: 0x5879, |
| 0x9ACE: 0x5885, |
| 0x9ACF: 0x58B9, |
| 0x9AD0: 0x589F, |
| 0x9AD1: 0x58AB, |
| 0x9AD2: 0x58BA, |
| 0x9AD3: 0x58DE, |
| 0x9AD4: 0x58BB, |
| 0x9AD5: 0x58B8, |
| 0x9AD6: 0x58AE, |
| 0x9AD7: 0x58C5, |
| 0x9AD8: 0x58D3, |
| 0x9AD9: 0x58D1, |
| 0x9ADA: 0x58D7, |
| 0x9ADB: 0x58D9, |
| 0x9ADC: 0x58D8, |
| 0x9ADD: 0x58E5, |
| 0x9ADE: 0x58DC, |
| 0x9ADF: 0x58E4, |
| 0x9AE0: 0x58DF, |
| 0x9AE1: 0x58EF, |
| 0x9AE2: 0x58FA, |
| 0x9AE3: 0x58F9, |
| 0x9AE4: 0x58FB, |
| 0x9AE5: 0x58FC, |
| 0x9AE6: 0x58FD, |
| 0x9AE7: 0x5902, |
| 0x9AE8: 0x590A, |
| 0x9AE9: 0x5910, |
| 0x9AEA: 0x591B, |
| 0x9AEB: 0x68A6, |
| 0x9AEC: 0x5925, |
| 0x9AED: 0x592C, |
| 0x9AEE: 0x592D, |
| 0x9AEF: 0x5932, |
| 0x9AF0: 0x5938, |
| 0x9AF1: 0x593E, |
| 0x9AF2: 0x7AD2, |
| 0x9AF3: 0x5955, |
| 0x9AF4: 0x5950, |
| 0x9AF5: 0x594E, |
| 0x9AF6: 0x595A, |
| 0x9AF7: 0x5958, |
| 0x9AF8: 0x5962, |
| 0x9AF9: 0x5960, |
| 0x9AFA: 0x5967, |
| 0x9AFB: 0x596C, |
| 0x9AFC: 0x5969, |
| 0x9B40: 0x5978, |
| 0x9B41: 0x5981, |
| 0x9B42: 0x599D, |
| 0x9B43: 0x4F5E, |
| 0x9B44: 0x4FAB, |
| 0x9B45: 0x59A3, |
| 0x9B46: 0x59B2, |
| 0x9B47: 0x59C6, |
| 0x9B48: 0x59E8, |
| 0x9B49: 0x59DC, |
| 0x9B4A: 0x598D, |
| 0x9B4B: 0x59D9, |
| 0x9B4C: 0x59DA, |
| 0x9B4D: 0x5A25, |
| 0x9B4E: 0x5A1F, |
| 0x9B4F: 0x5A11, |
| 0x9B50: 0x5A1C, |
| 0x9B51: 0x5A09, |
| 0x9B52: 0x5A1A, |
| 0x9B53: 0x5A40, |
| 0x9B54: 0x5A6C, |
| 0x9B55: 0x5A49, |
| 0x9B56: 0x5A35, |
| 0x9B57: 0x5A36, |
| 0x9B58: 0x5A62, |
| 0x9B59: 0x5A6A, |
| 0x9B5A: 0x5A9A, |
| 0x9B5B: 0x5ABC, |
| 0x9B5C: 0x5ABE, |
| 0x9B5D: 0x5ACB, |
| 0x9B5E: 0x5AC2, |
| 0x9B5F: 0x5ABD, |
| 0x9B60: 0x5AE3, |
| 0x9B61: 0x5AD7, |
| 0x9B62: 0x5AE6, |
| 0x9B63: 0x5AE9, |
| 0x9B64: 0x5AD6, |
| 0x9B65: 0x5AFA, |
| 0x9B66: 0x5AFB, |
| 0x9B67: 0x5B0C, |
| 0x9B68: 0x5B0B, |
| 0x9B69: 0x5B16, |
| 0x9B6A: 0x5B32, |
| 0x9B6B: 0x5AD0, |
| 0x9B6C: 0x5B2A, |
| 0x9B6D: 0x5B36, |
| 0x9B6E: 0x5B3E, |
| 0x9B6F: 0x5B43, |
| 0x9B70: 0x5B45, |
| 0x9B71: 0x5B40, |
| 0x9B72: 0x5B51, |
| 0x9B73: 0x5B55, |
| 0x9B74: 0x5B5A, |
| 0x9B75: 0x5B5B, |
| 0x9B76: 0x5B65, |
| 0x9B77: 0x5B69, |
| 0x9B78: 0x5B70, |
| 0x9B79: 0x5B73, |
| 0x9B7A: 0x5B75, |
| 0x9B7B: 0x5B78, |
| 0x9B7C: 0x6588, |
| 0x9B7D: 0x5B7A, |
| 0x9B7E: 0x5B80, |
| 0x9B80: 0x5B83, |
| 0x9B81: 0x5BA6, |
| 0x9B82: 0x5BB8, |
| 0x9B83: 0x5BC3, |
| 0x9B84: 0x5BC7, |
| 0x9B85: 0x5BC9, |
| 0x9B86: 0x5BD4, |
| 0x9B87: 0x5BD0, |
| 0x9B88: 0x5BE4, |
| 0x9B89: 0x5BE6, |
| 0x9B8A: 0x5BE2, |
| 0x9B8B: 0x5BDE, |
| 0x9B8C: 0x5BE5, |
| 0x9B8D: 0x5BEB, |
| 0x9B8E: 0x5BF0, |
| 0x9B8F: 0x5BF6, |
| 0x9B90: 0x5BF3, |
| 0x9B91: 0x5C05, |
| 0x9B92: 0x5C07, |
| 0x9B93: 0x5C08, |
| 0x9B94: 0x5C0D, |
| 0x9B95: 0x5C13, |
| 0x9B96: 0x5C20, |
| 0x9B97: 0x5C22, |
| 0x9B98: 0x5C28, |
| 0x9B99: 0x5C38, |
| 0x9B9A: 0x5C39, |
| 0x9B9B: 0x5C41, |
| 0x9B9C: 0x5C46, |
| 0x9B9D: 0x5C4E, |
| 0x9B9E: 0x5C53, |
| 0x9B9F: 0x5C50, |
| 0x9BA0: 0x5C4F, |
| 0x9BA1: 0x5B71, |
| 0x9BA2: 0x5C6C, |
| 0x9BA3: 0x5C6E, |
| 0x9BA4: 0x4E62, |
| 0x9BA5: 0x5C76, |
| 0x9BA6: 0x5C79, |
| 0x9BA7: 0x5C8C, |
| 0x9BA8: 0x5C91, |
| 0x9BA9: 0x5C94, |
| 0x9BAA: 0x599B, |
| 0x9BAB: 0x5CAB, |
| 0x9BAC: 0x5CBB, |
| 0x9BAD: 0x5CB6, |
| 0x9BAE: 0x5CBC, |
| 0x9BAF: 0x5CB7, |
| 0x9BB0: 0x5CC5, |
| 0x9BB1: 0x5CBE, |
| 0x9BB2: 0x5CC7, |
| 0x9BB3: 0x5CD9, |
| 0x9BB4: 0x5CE9, |
| 0x9BB5: 0x5CFD, |
| 0x9BB6: 0x5CFA, |
| 0x9BB7: 0x5CED, |
| 0x9BB8: 0x5D8C, |
| 0x9BB9: 0x5CEA, |
| 0x9BBA: 0x5D0B, |
| 0x9BBB: 0x5D15, |
| 0x9BBC: 0x5D17, |
| 0x9BBD: 0x5D5C, |
| 0x9BBE: 0x5D1F, |
| 0x9BBF: 0x5D1B, |
| 0x9BC0: 0x5D11, |
| 0x9BC1: 0x5D14, |
| 0x9BC2: 0x5D22, |
| 0x9BC3: 0x5D1A, |
| 0x9BC4: 0x5D19, |
| 0x9BC5: 0x5D18, |
| 0x9BC6: 0x5D4C, |
| 0x9BC7: 0x5D52, |
| 0x9BC8: 0x5D4E, |
| 0x9BC9: 0x5D4B, |
| 0x9BCA: 0x5D6C, |
| 0x9BCB: 0x5D73, |
| 0x9BCC: 0x5D76, |
| 0x9BCD: 0x5D87, |
| 0x9BCE: 0x5D84, |
| 0x9BCF: 0x5D82, |
| 0x9BD0: 0x5DA2, |
| 0x9BD1: 0x5D9D, |
| 0x9BD2: 0x5DAC, |
| 0x9BD3: 0x5DAE, |
| 0x9BD4: 0x5DBD, |
| 0x9BD5: 0x5D90, |
| 0x9BD6: 0x5DB7, |
| 0x9BD7: 0x5DBC, |
| 0x9BD8: 0x5DC9, |
| 0x9BD9: 0x5DCD, |
| 0x9BDA: 0x5DD3, |
| 0x9BDB: 0x5DD2, |
| 0x9BDC: 0x5DD6, |
| 0x9BDD: 0x5DDB, |
| 0x9BDE: 0x5DEB, |
| 0x9BDF: 0x5DF2, |
| 0x9BE0: 0x5DF5, |
| 0x9BE1: 0x5E0B, |
| 0x9BE2: 0x5E1A, |
| 0x9BE3: 0x5E19, |
| 0x9BE4: 0x5E11, |
| 0x9BE5: 0x5E1B, |
| 0x9BE6: 0x5E36, |
| 0x9BE7: 0x5E37, |
| 0x9BE8: 0x5E44, |
| 0x9BE9: 0x5E43, |
| 0x9BEA: 0x5E40, |
| 0x9BEB: 0x5E4E, |
| 0x9BEC: 0x5E57, |
| 0x9BED: 0x5E54, |
| 0x9BEE: 0x5E5F, |
| 0x9BEF: 0x5E62, |
| 0x9BF0: 0x5E64, |
| 0x9BF1: 0x5E47, |
| 0x9BF2: 0x5E75, |
| 0x9BF3: 0x5E76, |
| 0x9BF4: 0x5E7A, |
| 0x9BF5: 0x9EBC, |
| 0x9BF6: 0x5E7F, |
| 0x9BF7: 0x5EA0, |
| 0x9BF8: 0x5EC1, |
| 0x9BF9: 0x5EC2, |
| 0x9BFA: 0x5EC8, |
| 0x9BFB: 0x5ED0, |
| 0x9BFC: 0x5ECF, |
| 0x9C40: 0x5ED6, |
| 0x9C41: 0x5EE3, |
| 0x9C42: 0x5EDD, |
| 0x9C43: 0x5EDA, |
| 0x9C44: 0x5EDB, |
| 0x9C45: 0x5EE2, |
| 0x9C46: 0x5EE1, |
| 0x9C47: 0x5EE8, |
| 0x9C48: 0x5EE9, |
| 0x9C49: 0x5EEC, |
| 0x9C4A: 0x5EF1, |
| 0x9C4B: 0x5EF3, |
| 0x9C4C: 0x5EF0, |
| 0x9C4D: 0x5EF4, |
| 0x9C4E: 0x5EF8, |
| 0x9C4F: 0x5EFE, |
| 0x9C50: 0x5F03, |
| 0x9C51: 0x5F09, |
| 0x9C52: 0x5F5D, |
| 0x9C53: 0x5F5C, |
| 0x9C54: 0x5F0B, |
| 0x9C55: 0x5F11, |
| 0x9C56: 0x5F16, |
| 0x9C57: 0x5F29, |
| 0x9C58: 0x5F2D, |
| 0x9C59: 0x5F38, |
| 0x9C5A: 0x5F41, |
| 0x9C5B: 0x5F48, |
| 0x9C5C: 0x5F4C, |
| 0x9C5D: 0x5F4E, |
| 0x9C5E: 0x5F2F, |
| 0x9C5F: 0x5F51, |
| 0x9C60: 0x5F56, |
| 0x9C61: 0x5F57, |
| 0x9C62: 0x5F59, |
| 0x9C63: 0x5F61, |
| 0x9C64: 0x5F6D, |
| 0x9C65: 0x5F73, |
| 0x9C66: 0x5F77, |
| 0x9C67: 0x5F83, |
| 0x9C68: 0x5F82, |
| 0x9C69: 0x5F7F, |
| 0x9C6A: 0x5F8A, |
| 0x9C6B: 0x5F88, |
| 0x9C6C: 0x5F91, |
| 0x9C6D: 0x5F87, |
| 0x9C6E: 0x5F9E, |
| 0x9C6F: 0x5F99, |
| 0x9C70: 0x5F98, |
| 0x9C71: 0x5FA0, |
| 0x9C72: 0x5FA8, |
| 0x9C73: 0x5FAD, |
| 0x9C74: 0x5FBC, |
| 0x9C75: 0x5FD6, |
| 0x9C76: 0x5FFB, |
| 0x9C77: 0x5FE4, |
| 0x9C78: 0x5FF8, |
| 0x9C79: 0x5FF1, |
| 0x9C7A: 0x5FDD, |
| 0x9C7B: 0x60B3, |
| 0x9C7C: 0x5FFF, |
| 0x9C7D: 0x6021, |
| 0x9C7E: 0x6060, |
| 0x9C80: 0x6019, |
| 0x9C81: 0x6010, |
| 0x9C82: 0x6029, |
| 0x9C83: 0x600E, |
| 0x9C84: 0x6031, |
| 0x9C85: 0x601B, |
| 0x9C86: 0x6015, |
| 0x9C87: 0x602B, |
| 0x9C88: 0x6026, |
| 0x9C89: 0x600F, |
| 0x9C8A: 0x603A, |
| 0x9C8B: 0x605A, |
| 0x9C8C: 0x6041, |
| 0x9C8D: 0x606A, |
| 0x9C8E: 0x6077, |
| 0x9C8F: 0x605F, |
| 0x9C90: 0x604A, |
| 0x9C91: 0x6046, |
| 0x9C92: 0x604D, |
| 0x9C93: 0x6063, |
| 0x9C94: 0x6043, |
| 0x9C95: 0x6064, |
| 0x9C96: 0x6042, |
| 0x9C97: 0x606C, |
| 0x9C98: 0x606B, |
| 0x9C99: 0x6059, |
| 0x9C9A: 0x6081, |
| 0x9C9B: 0x608D, |
| 0x9C9C: 0x60E7, |
| 0x9C9D: 0x6083, |
| 0x9C9E: 0x609A, |
| 0x9C9F: 0x6084, |
| 0x9CA0: 0x609B, |
| 0x9CA1: 0x6096, |
| 0x9CA2: 0x6097, |
| 0x9CA3: 0x6092, |
| 0x9CA4: 0x60A7, |
| 0x9CA5: 0x608B, |
| 0x9CA6: 0x60E1, |
| 0x9CA7: 0x60B8, |
| 0x9CA8: 0x60E0, |
| 0x9CA9: 0x60D3, |
| 0x9CAA: 0x60B4, |
| 0x9CAB: 0x5FF0, |
| 0x9CAC: 0x60BD, |
| 0x9CAD: 0x60C6, |
| 0x9CAE: 0x60B5, |
| 0x9CAF: 0x60D8, |
| 0x9CB0: 0x614D, |
| 0x9CB1: 0x6115, |
| 0x9CB2: 0x6106, |
| 0x9CB3: 0x60F6, |
| 0x9CB4: 0x60F7, |
| 0x9CB5: 0x6100, |
| 0x9CB6: 0x60F4, |
| 0x9CB7: 0x60FA, |
| 0x9CB8: 0x6103, |
| 0x9CB9: 0x6121, |
| 0x9CBA: 0x60FB, |
| 0x9CBB: 0x60F1, |
| 0x9CBC: 0x610D, |
| 0x9CBD: 0x610E, |
| 0x9CBE: 0x6147, |
| 0x9CBF: 0x613E, |
| 0x9CC0: 0x6128, |
| 0x9CC1: 0x6127, |
| 0x9CC2: 0x614A, |
| 0x9CC3: 0x613F, |
| 0x9CC4: 0x613C, |
| 0x9CC5: 0x612C, |
| 0x9CC6: 0x6134, |
| 0x9CC7: 0x613D, |
| 0x9CC8: 0x6142, |
| 0x9CC9: 0x6144, |
| 0x9CCA: 0x6173, |
| 0x9CCB: 0x6177, |
| 0x9CCC: 0x6158, |
| 0x9CCD: 0x6159, |
| 0x9CCE: 0x615A, |
| 0x9CCF: 0x616B, |
| 0x9CD0: 0x6174, |
| 0x9CD1: 0x616F, |
| 0x9CD2: 0x6165, |
| 0x9CD3: 0x6171, |
| 0x9CD4: 0x615F, |
| 0x9CD5: 0x615D, |
| 0x9CD6: 0x6153, |
| 0x9CD7: 0x6175, |
| 0x9CD8: 0x6199, |
| 0x9CD9: 0x6196, |
| 0x9CDA: 0x6187, |
| 0x9CDB: 0x61AC, |
| 0x9CDC: 0x6194, |
| 0x9CDD: 0x619A, |
| 0x9CDE: 0x618A, |
| 0x9CDF: 0x6191, |
| 0x9CE0: 0x61AB, |
| 0x9CE1: 0x61AE, |
| 0x9CE2: 0x61CC, |
| 0x9CE3: 0x61CA, |
| 0x9CE4: 0x61C9, |
| 0x9CE5: 0x61F7, |
| 0x9CE6: 0x61C8, |
| 0x9CE7: 0x61C3, |
| 0x9CE8: 0x61C6, |
| 0x9CE9: 0x61BA, |
| 0x9CEA: 0x61CB, |
| 0x9CEB: 0x7F79, |
| 0x9CEC: 0x61CD, |
| 0x9CED: 0x61E6, |
| 0x9CEE: 0x61E3, |
| 0x9CEF: 0x61F6, |
| 0x9CF0: 0x61FA, |
| 0x9CF1: 0x61F4, |
| 0x9CF2: 0x61FF, |
| 0x9CF3: 0x61FD, |
| 0x9CF4: 0x61FC, |
| 0x9CF5: 0x61FE, |
| 0x9CF6: 0x6200, |
| 0x9CF7: 0x6208, |
| 0x9CF8: 0x6209, |
| 0x9CF9: 0x620D, |
| 0x9CFA: 0x620C, |
| 0x9CFB: 0x6214, |
| 0x9CFC: 0x621B, |
| 0x9D40: 0x621E, |
| 0x9D41: 0x6221, |
| 0x9D42: 0x622A, |
| 0x9D43: 0x622E, |
| 0x9D44: 0x6230, |
| 0x9D45: 0x6232, |
| 0x9D46: 0x6233, |
| 0x9D47: 0x6241, |
| 0x9D48: 0x624E, |
| 0x9D49: 0x625E, |
| 0x9D4A: 0x6263, |
| 0x9D4B: 0x625B, |
| 0x9D4C: 0x6260, |
| 0x9D4D: 0x6268, |
| 0x9D4E: 0x627C, |
| 0x9D4F: 0x6282, |
| 0x9D50: 0x6289, |
| 0x9D51: 0x627E, |
| 0x9D52: 0x6292, |
| 0x9D53: 0x6293, |
| 0x9D54: 0x6296, |
| 0x9D55: 0x62D4, |
| 0x9D56: 0x6283, |
| 0x9D57: 0x6294, |
| 0x9D58: 0x62D7, |
| 0x9D59: 0x62D1, |
| 0x9D5A: 0x62BB, |
| 0x9D5B: 0x62CF, |
| 0x9D5C: 0x62FF, |
| 0x9D5D: 0x62C6, |
| 0x9D5E: 0x64D4, |
| 0x9D5F: 0x62C8, |
| 0x9D60: 0x62DC, |
| 0x9D61: 0x62CC, |
| 0x9D62: 0x62CA, |
| 0x9D63: 0x62C2, |
| 0x9D64: 0x62C7, |
| 0x9D65: 0x629B, |
| 0x9D66: 0x62C9, |
| 0x9D67: 0x630C, |
| 0x9D68: 0x62EE, |
| 0x9D69: 0x62F1, |
| 0x9D6A: 0x6327, |
| 0x9D6B: 0x6302, |
| 0x9D6C: 0x6308, |
| 0x9D6D: 0x62EF, |
| 0x9D6E: 0x62F5, |
| 0x9D6F: 0x6350, |
| 0x9D70: 0x633E, |
| 0x9D71: 0x634D, |
| 0x9D72: 0x641C, |
| 0x9D73: 0x634F, |
| 0x9D74: 0x6396, |
| 0x9D75: 0x638E, |
| 0x9D76: 0x6380, |
| 0x9D77: 0x63AB, |
| 0x9D78: 0x6376, |
| 0x9D79: 0x63A3, |
| 0x9D7A: 0x638F, |
| 0x9D7B: 0x6389, |
| 0x9D7C: 0x639F, |
| 0x9D7D: 0x63B5, |
| 0x9D7E: 0x636B, |
| 0x9D80: 0x6369, |
| 0x9D81: 0x63BE, |
| 0x9D82: 0x63E9, |
| 0x9D83: 0x63C0, |
| 0x9D84: 0x63C6, |
| 0x9D85: 0x63E3, |
| 0x9D86: 0x63C9, |
| 0x9D87: 0x63D2, |
| 0x9D88: 0x63F6, |
| 0x9D89: 0x63C4, |
| 0x9D8A: 0x6416, |
| 0x9D8B: 0x6434, |
| 0x9D8C: 0x6406, |
| 0x9D8D: 0x6413, |
| 0x9D8E: 0x6426, |
| 0x9D8F: 0x6436, |
| 0x9D90: 0x651D, |
| 0x9D91: 0x6417, |
| 0x9D92: 0x6428, |
| 0x9D93: 0x640F, |
| 0x9D94: 0x6467, |
| 0x9D95: 0x646F, |
| 0x9D96: 0x6476, |
| 0x9D97: 0x644E, |
| 0x9D98: 0x652A, |
| 0x9D99: 0x6495, |
| 0x9D9A: 0x6493, |
| 0x9D9B: 0x64A5, |
| 0x9D9C: 0x64A9, |
| 0x9D9D: 0x6488, |
| 0x9D9E: 0x64BC, |
| 0x9D9F: 0x64DA, |
| 0x9DA0: 0x64D2, |
| 0x9DA1: 0x64C5, |
| 0x9DA2: 0x64C7, |
| 0x9DA3: 0x64BB, |
| 0x9DA4: 0x64D8, |
| 0x9DA5: 0x64C2, |
| 0x9DA6: 0x64F1, |
| 0x9DA7: 0x64E7, |
| 0x9DA8: 0x8209, |
| 0x9DA9: 0x64E0, |
| 0x9DAA: 0x64E1, |
| 0x9DAB: 0x62AC, |
| 0x9DAC: 0x64E3, |
| 0x9DAD: 0x64EF, |
| 0x9DAE: 0x652C, |
| 0x9DAF: 0x64F6, |
| 0x9DB0: 0x64F4, |
| 0x9DB1: 0x64F2, |
| 0x9DB2: 0x64FA, |
| 0x9DB3: 0x6500, |
| 0x9DB4: 0x64FD, |
| 0x9DB5: 0x6518, |
| 0x9DB6: 0x651C, |
| 0x9DB7: 0x6505, |
| 0x9DB8: 0x6524, |
| 0x9DB9: 0x6523, |
| 0x9DBA: 0x652B, |
| 0x9DBB: 0x6534, |
| 0x9DBC: 0x6535, |
| 0x9DBD: 0x6537, |
| 0x9DBE: 0x6536, |
| 0x9DBF: 0x6538, |
| 0x9DC0: 0x754B, |
| 0x9DC1: 0x6548, |
| 0x9DC2: 0x6556, |
| 0x9DC3: 0x6555, |
| 0x9DC4: 0x654D, |
| 0x9DC5: 0x6558, |
| 0x9DC6: 0x655E, |
| 0x9DC7: 0x655D, |
| 0x9DC8: 0x6572, |
| 0x9DC9: 0x6578, |
| 0x9DCA: 0x6582, |
| 0x9DCB: 0x6583, |
| 0x9DCC: 0x8B8A, |
| 0x9DCD: 0x659B, |
| 0x9DCE: 0x659F, |
| 0x9DCF: 0x65AB, |
| 0x9DD0: 0x65B7, |
| 0x9DD1: 0x65C3, |
| 0x9DD2: 0x65C6, |
| 0x9DD3: 0x65C1, |
| 0x9DD4: 0x65C4, |
| 0x9DD5: 0x65CC, |
| 0x9DD6: 0x65D2, |
| 0x9DD7: 0x65DB, |
| 0x9DD8: 0x65D9, |
| 0x9DD9: 0x65E0, |
| 0x9DDA: 0x65E1, |
| 0x9DDB: 0x65F1, |
| 0x9DDC: 0x6772, |
| 0x9DDD: 0x660A, |
| 0x9DDE: 0x6603, |
| 0x9DDF: 0x65FB, |
| 0x9DE0: 0x6773, |
| 0x9DE1: 0x6635, |
| 0x9DE2: 0x6636, |
| 0x9DE3: 0x6634, |
| 0x9DE4: 0x661C, |
| 0x9DE5: 0x664F, |
| 0x9DE6: 0x6644, |
| 0x9DE7: 0x6649, |
| 0x9DE8: 0x6641, |
| 0x9DE9: 0x665E, |
| 0x9DEA: 0x665D, |
| 0x9DEB: 0x6664, |
| 0x9DEC: 0x6667, |
| 0x9DED: 0x6668, |
| 0x9DEE: 0x665F, |
| 0x9DEF: 0x6662, |
| 0x9DF0: 0x6670, |
| 0x9DF1: 0x6683, |
| 0x9DF2: 0x6688, |
| 0x9DF3: 0x668E, |
| 0x9DF4: 0x6689, |
| 0x9DF5: 0x6684, |
| 0x9DF6: 0x6698, |
| 0x9DF7: 0x669D, |
| 0x9DF8: 0x66C1, |
| 0x9DF9: 0x66B9, |
| 0x9DFA: 0x66C9, |
| 0x9DFB: 0x66BE, |
| 0x9DFC: 0x66BC, |
| 0x9E40: 0x66C4, |
| 0x9E41: 0x66B8, |
| 0x9E42: 0x66D6, |
| 0x9E43: 0x66DA, |
| 0x9E44: 0x66E0, |
| 0x9E45: 0x663F, |
| 0x9E46: 0x66E6, |
| 0x9E47: 0x66E9, |
| 0x9E48: 0x66F0, |
| 0x9E49: 0x66F5, |
| 0x9E4A: 0x66F7, |
| 0x9E4B: 0x670F, |
| 0x9E4C: 0x6716, |
| 0x9E4D: 0x671E, |
| 0x9E4E: 0x6726, |
| 0x9E4F: 0x6727, |
| 0x9E50: 0x9738, |
| 0x9E51: 0x672E, |
| 0x9E52: 0x673F, |
| 0x9E53: 0x6736, |
| 0x9E54: 0x6741, |
| 0x9E55: 0x6738, |
| 0x9E56: 0x6737, |
| 0x9E57: 0x6746, |
| 0x9E58: 0x675E, |
| 0x9E59: 0x6760, |
| 0x9E5A: 0x6759, |
| 0x9E5B: 0x6763, |
| 0x9E5C: 0x6764, |
| 0x9E5D: 0x6789, |
| 0x9E5E: 0x6770, |
| 0x9E5F: 0x67A9, |
| 0x9E60: 0x677C, |
| 0x9E61: 0x676A, |
| 0x9E62: 0x678C, |
| 0x9E63: 0x678B, |
| 0x9E64: 0x67A6, |
| 0x9E65: 0x67A1, |
| 0x9E66: 0x6785, |
| 0x9E67: 0x67B7, |
| 0x9E68: 0x67EF, |
| 0x9E69: 0x67B4, |
| 0x9E6A: 0x67EC, |
| 0x9E6B: 0x67B3, |
| 0x9E6C: 0x67E9, |
| 0x9E6D: 0x67B8, |
| 0x9E6E: 0x67E4, |
| 0x9E6F: 0x67DE, |
| 0x9E70: 0x67DD, |
| 0x9E71: 0x67E2, |
| 0x9E72: 0x67EE, |
| 0x9E73: 0x67B9, |
| 0x9E74: 0x67CE, |
| 0x9E75: 0x67C6, |
| 0x9E76: 0x67E7, |
| 0x9E77: 0x6A9C, |
| 0x9E78: 0x681E, |
| 0x9E79: 0x6846, |
| 0x9E7A: 0x6829, |
| 0x9E7B: 0x6840, |
| 0x9E7C: 0x684D, |
| 0x9E7D: 0x6832, |
| 0x9E7E: 0x684E, |
| 0x9E80: 0x68B3, |
| 0x9E81: 0x682B, |
| 0x9E82: 0x6859, |
| 0x9E83: 0x6863, |
| 0x9E84: 0x6877, |
| 0x9E85: 0x687F, |
| 0x9E86: 0x689F, |
| 0x9E87: 0x688F, |
| 0x9E88: 0x68AD, |
| 0x9E89: 0x6894, |
| 0x9E8A: 0x689D, |
| 0x9E8B: 0x689B, |
| 0x9E8C: 0x6883, |
| 0x9E8D: 0x6AAE, |
| 0x9E8E: 0x68B9, |
| 0x9E8F: 0x6874, |
| 0x9E90: 0x68B5, |
| 0x9E91: 0x68A0, |
| 0x9E92: 0x68BA, |
| 0x9E93: 0x690F, |
| 0x9E94: 0x688D, |
| 0x9E95: 0x687E, |
| 0x9E96: 0x6901, |
| 0x9E97: 0x68CA, |
| 0x9E98: 0x6908, |
| 0x9E99: 0x68D8, |
| 0x9E9A: 0x6922, |
| 0x9E9B: 0x6926, |
| 0x9E9C: 0x68E1, |
| 0x9E9D: 0x690C, |
| 0x9E9E: 0x68CD, |
| 0x9E9F: 0x68D4, |
| 0x9EA0: 0x68E7, |
| 0x9EA1: 0x68D5, |
| 0x9EA2: 0x6936, |
| 0x9EA3: 0x6912, |
| 0x9EA4: 0x6904, |
| 0x9EA5: 0x68D7, |
| 0x9EA6: 0x68E3, |
| 0x9EA7: 0x6925, |
| 0x9EA8: 0x68F9, |
| 0x9EA9: 0x68E0, |
| 0x9EAA: 0x68EF, |
| 0x9EAB: 0x6928, |
| 0x9EAC: 0x692A, |
| 0x9EAD: 0x691A, |
| 0x9EAE: 0x6923, |
| 0x9EAF: 0x6921, |
| 0x9EB0: 0x68C6, |
| 0x9EB1: 0x6979, |
| 0x9EB2: 0x6977, |
| 0x9EB3: 0x695C, |
| 0x9EB4: 0x6978, |
| 0x9EB5: 0x696B, |
| 0x9EB6: 0x6954, |
| 0x9EB7: 0x697E, |
| 0x9EB8: 0x696E, |
| 0x9EB9: 0x6939, |
| 0x9EBA: 0x6974, |
| 0x9EBB: 0x693D, |
| 0x9EBC: 0x6959, |
| 0x9EBD: 0x6930, |
| 0x9EBE: 0x6961, |
| 0x9EBF: 0x695E, |
| 0x9EC0: 0x695D, |
| 0x9EC1: 0x6981, |
| 0x9EC2: 0x696A, |
| 0x9EC3: 0x69B2, |
| 0x9EC4: 0x69AE, |
| 0x9EC5: 0x69D0, |
| 0x9EC6: 0x69BF, |
| 0x9EC7: 0x69C1, |
| 0x9EC8: 0x69D3, |
| 0x9EC9: 0x69BE, |
| 0x9ECA: 0x69CE, |
| 0x9ECB: 0x5BE8, |
| 0x9ECC: 0x69CA, |
| 0x9ECD: 0x69DD, |
| 0x9ECE: 0x69BB, |
| 0x9ECF: 0x69C3, |
| 0x9ED0: 0x69A7, |
| 0x9ED1: 0x6A2E, |
| 0x9ED2: 0x6991, |
| 0x9ED3: 0x69A0, |
| 0x9ED4: 0x699C, |
| 0x9ED5: 0x6995, |
| 0x9ED6: 0x69B4, |
| 0x9ED7: 0x69DE, |
| 0x9ED8: 0x69E8, |
| 0x9ED9: 0x6A02, |
| 0x9EDA: 0x6A1B, |
| 0x9EDB: 0x69FF, |
| 0x9EDC: 0x6B0A, |
| 0x9EDD: 0x69F9, |
| 0x9EDE: 0x69F2, |
| 0x9EDF: 0x69E7, |
| 0x9EE0: 0x6A05, |
| 0x9EE1: 0x69B1, |
| 0x9EE2: 0x6A1E, |
| 0x9EE3: 0x69ED, |
| 0x9EE4: 0x6A14, |
| 0x9EE5: 0x69EB, |
| 0x9EE6: 0x6A0A, |
| 0x9EE7: 0x6A12, |
| 0x9EE8: 0x6AC1, |
| 0x9EE9: 0x6A23, |
| 0x9EEA: 0x6A13, |
| 0x9EEB: 0x6A44, |
| 0x9EEC: 0x6A0C, |
| 0x9EED: 0x6A72, |
| 0x9EEE: 0x6A36, |
| 0x9EEF: 0x6A78, |
| 0x9EF0: 0x6A47, |
| 0x9EF1: 0x6A62, |
| 0x9EF2: 0x6A59, |
| 0x9EF3: 0x6A66, |
| 0x9EF4: 0x6A48, |
| 0x9EF5: 0x6A38, |
| 0x9EF6: 0x6A22, |
| 0x9EF7: 0x6A90, |
| 0x9EF8: 0x6A8D, |
| 0x9EF9: 0x6AA0, |
| 0x9EFA: 0x6A84, |
| 0x9EFB: 0x6AA2, |
| 0x9EFC: 0x6AA3, |
| 0x9F40: 0x6A97, |
| 0x9F41: 0x8617, |
| 0x9F42: 0x6ABB, |
| 0x9F43: 0x6AC3, |
| 0x9F44: 0x6AC2, |
| 0x9F45: 0x6AB8, |
| 0x9F46: 0x6AB3, |
| 0x9F47: 0x6AAC, |
| 0x9F48: 0x6ADE, |
| 0x9F49: 0x6AD1, |
| 0x9F4A: 0x6ADF, |
| 0x9F4B: 0x6AAA, |
| 0x9F4C: 0x6ADA, |
| 0x9F4D: 0x6AEA, |
| 0x9F4E: 0x6AFB, |
| 0x9F4F: 0x6B05, |
| 0x9F50: 0x8616, |
| 0x9F51: 0x6AFA, |
| 0x9F52: 0x6B12, |
| 0x9F53: 0x6B16, |
| 0x9F54: 0x9B31, |
| 0x9F55: 0x6B1F, |
| 0x9F56: 0x6B38, |
| 0x9F57: 0x6B37, |
| 0x9F58: 0x76DC, |
| 0x9F59: 0x6B39, |
| 0x9F5A: 0x98EE, |
| 0x9F5B: 0x6B47, |
| 0x9F5C: 0x6B43, |
| 0x9F5D: 0x6B49, |
| 0x9F5E: 0x6B50, |
| 0x9F5F: 0x6B59, |
| 0x9F60: 0x6B54, |
| 0x9F61: 0x6B5B, |
| 0x9F62: 0x6B5F, |
| 0x9F63: 0x6B61, |
| 0x9F64: 0x6B78, |
| 0x9F65: 0x6B79, |
| 0x9F66: 0x6B7F, |
| 0x9F67: 0x6B80, |
| 0x9F68: 0x6B84, |
| 0x9F69: 0x6B83, |
| 0x9F6A: 0x6B8D, |
| 0x9F6B: 0x6B98, |
| 0x9F6C: 0x6B95, |
| 0x9F6D: 0x6B9E, |
| 0x9F6E: 0x6BA4, |
| 0x9F6F: 0x6BAA, |
| 0x9F70: 0x6BAB, |
| 0x9F71: 0x6BAF, |
| 0x9F72: 0x6BB2, |
| 0x9F73: 0x6BB1, |
| 0x9F74: 0x6BB3, |
| 0x9F75: 0x6BB7, |
| 0x9F76: 0x6BBC, |
| 0x9F77: 0x6BC6, |
| 0x9F78: 0x6BCB, |
| 0x9F79: 0x6BD3, |
| 0x9F7A: 0x6BDF, |
| 0x9F7B: 0x6BEC, |
| 0x9F7C: 0x6BEB, |
| 0x9F7D: 0x6BF3, |
| 0x9F7E: 0x6BEF, |
| 0x9F80: 0x9EBE, |
| 0x9F81: 0x6C08, |
| 0x9F82: 0x6C13, |
| 0x9F83: 0x6C14, |
| 0x9F84: 0x6C1B, |
| 0x9F85: 0x6C24, |
| 0x9F86: 0x6C23, |
| 0x9F87: 0x6C5E, |
| 0x9F88: 0x6C55, |
| 0x9F89: 0x6C62, |
| 0x9F8A: 0x6C6A, |
| 0x9F8B: 0x6C82, |
| 0x9F8C: 0x6C8D, |
| 0x9F8D: 0x6C9A, |
| 0x9F8E: 0x6C81, |
| 0x9F8F: 0x6C9B, |
| 0x9F90: 0x6C7E, |
| 0x9F91: 0x6C68, |
| 0x9F92: 0x6C73, |
| 0x9F93: 0x6C92, |
| 0x9F94: 0x6C90, |
| 0x9F95: 0x6CC4, |
| 0x9F96: 0x6CF1, |
| 0x9F97: 0x6CD3, |
| 0x9F98: 0x6CBD, |
| 0x9F99: 0x6CD7, |
| 0x9F9A: 0x6CC5, |
| 0x9F9B: 0x6CDD, |
| 0x9F9C: 0x6CAE, |
| 0x9F9D: 0x6CB1, |
| 0x9F9E: 0x6CBE, |
| 0x9F9F: 0x6CBA, |
| 0x9FA0: 0x6CDB, |
| 0x9FA1: 0x6CEF, |
| 0x9FA2: 0x6CD9, |
| 0x9FA3: 0x6CEA, |
| 0x9FA4: 0x6D1F, |
| 0x9FA5: 0x884D, |
| 0x9FA6: 0x6D36, |
| 0x9FA7: 0x6D2B, |
| 0x9FA8: 0x6D3D, |
| 0x9FA9: 0x6D38, |
| 0x9FAA: 0x6D19, |
| 0x9FAB: 0x6D35, |
| 0x9FAC: 0x6D33, |
| 0x9FAD: 0x6D12, |
| 0x9FAE: 0x6D0C, |
| 0x9FAF: 0x6D63, |
| 0x9FB0: 0x6D93, |
| 0x9FB1: 0x6D64, |
| 0x9FB2: 0x6D5A, |
| 0x9FB3: 0x6D79, |
| 0x9FB4: 0x6D59, |
| 0x9FB5: 0x6D8E, |
| 0x9FB6: 0x6D95, |
| 0x9FB7: 0x6FE4, |
| 0x9FB8: 0x6D85, |
| 0x9FB9: 0x6DF9, |
| 0x9FBA: 0x6E15, |
| 0x9FBB: 0x6E0A, |
| 0x9FBC: 0x6DB5, |
| 0x9FBD: 0x6DC7, |
| 0x9FBE: 0x6DE6, |
| 0x9FBF: 0x6DB8, |
| 0x9FC0: 0x6DC6, |
| 0x9FC1: 0x6DEC, |
| 0x9FC2: 0x6DDE, |
| 0x9FC3: 0x6DCC, |
| 0x9FC4: 0x6DE8, |
| 0x9FC5: 0x6DD2, |
| 0x9FC6: 0x6DC5, |
| 0x9FC7: 0x6DFA, |
| 0x9FC8: 0x6DD9, |
| 0x9FC9: 0x6DE4, |
| 0x9FCA: 0x6DD5, |
| 0x9FCB: 0x6DEA, |
| 0x9FCC: 0x6DEE, |
| 0x9FCD: 0x6E2D, |
| 0x9FCE: 0x6E6E, |
| 0x9FCF: 0x6E2E, |
| 0x9FD0: 0x6E19, |
| 0x9FD1: 0x6E72, |
| 0x9FD2: 0x6E5F, |
| 0x9FD3: 0x6E3E, |
| 0x9FD4: 0x6E23, |
| 0x9FD5: 0x6E6B, |
| 0x9FD6: 0x6E2B, |
| 0x9FD7: 0x6E76, |
| 0x9FD8: 0x6E4D, |
| 0x9FD9: 0x6E1F, |
| 0x9FDA: 0x6E43, |
| 0x9FDB: 0x6E3A, |
| 0x9FDC: 0x6E4E, |
| 0x9FDD: 0x6E24, |
| 0x9FDE: 0x6EFF, |
| 0x9FDF: 0x6E1D, |
| 0x9FE0: 0x6E38, |
| 0x9FE1: 0x6E82, |
| 0x9FE2: 0x6EAA, |
| 0x9FE3: 0x6E98, |
| 0x9FE4: 0x6EC9, |
| 0x9FE5: 0x6EB7, |
| 0x9FE6: 0x6ED3, |
| 0x9FE7: 0x6EBD, |
| 0x9FE8: 0x6EAF, |
| 0x9FE9: 0x6EC4, |
| 0x9FEA: 0x6EB2, |
| 0x9FEB: 0x6ED4, |
| 0x9FEC: 0x6ED5, |
| 0x9FED: 0x6E8F, |
| 0x9FEE: 0x6EA5, |
| 0x9FEF: 0x6EC2, |
| 0x9FF0: 0x6E9F, |
| 0x9FF1: 0x6F41, |
| 0x9FF2: 0x6F11, |
| 0x9FF3: 0x704C, |
| 0x9FF4: 0x6EEC, |
| 0x9FF5: 0x6EF8, |
| 0x9FF6: 0x6EFE, |
| 0x9FF7: 0x6F3F, |
| 0x9FF8: 0x6EF2, |
| 0x9FF9: 0x6F31, |
| 0x9FFA: 0x6EEF, |
| 0x9FFB: 0x6F32, |
| 0x9FFC: 0x6ECC, |
| 0xA1: 0xFF61, |
| 0xA2: 0xFF62, |
| 0xA3: 0xFF63, |
| 0xA4: 0xFF64, |
| 0xA5: 0xFF65, |
| 0xA6: 0xFF66, |
| 0xA7: 0xFF67, |
| 0xA8: 0xFF68, |
| 0xA9: 0xFF69, |
| 0xAA: 0xFF6A, |
| 0xAB: 0xFF6B, |
| 0xAC: 0xFF6C, |
| 0xAD: 0xFF6D, |
| 0xAE: 0xFF6E, |
| 0xAF: 0xFF6F, |
| 0xB0: 0xFF70, |
| 0xB1: 0xFF71, |
| 0xB2: 0xFF72, |
| 0xB3: 0xFF73, |
| 0xB4: 0xFF74, |
| 0xB5: 0xFF75, |
| 0xB6: 0xFF76, |
| 0xB7: 0xFF77, |
| 0xB8: 0xFF78, |
| 0xB9: 0xFF79, |
| 0xBA: 0xFF7A, |
| 0xBB: 0xFF7B, |
| 0xBC: 0xFF7C, |
| 0xBD: 0xFF7D, |
| 0xBE: 0xFF7E, |
| 0xBF: 0xFF7F, |
| 0xC0: 0xFF80, |
| 0xC1: 0xFF81, |
| 0xC2: 0xFF82, |
| 0xC3: 0xFF83, |
| 0xC4: 0xFF84, |
| 0xC5: 0xFF85, |
| 0xC6: 0xFF86, |
| 0xC7: 0xFF87, |
| 0xC8: 0xFF88, |
| 0xC9: 0xFF89, |
| 0xCA: 0xFF8A, |
| 0xCB: 0xFF8B, |
| 0xCC: 0xFF8C, |
| 0xCD: 0xFF8D, |
| 0xCE: 0xFF8E, |
| 0xCF: 0xFF8F, |
| 0xD0: 0xFF90, |
| 0xD1: 0xFF91, |
| 0xD2: 0xFF92, |
| 0xD3: 0xFF93, |
| 0xD4: 0xFF94, |
| 0xD5: 0xFF95, |
| 0xD6: 0xFF96, |
| 0xD7: 0xFF97, |
| 0xD8: 0xFF98, |
| 0xD9: 0xFF99, |
| 0xDA: 0xFF9A, |
| 0xDB: 0xFF9B, |
| 0xDC: 0xFF9C, |
| 0xDD: 0xFF9D, |
| 0xDE: 0xFF9E, |
| 0xDF: 0xFF9F, |
| 0xE040: 0x6F3E, |
| 0xE041: 0x6F13, |
| 0xE042: 0x6EF7, |
| 0xE043: 0x6F86, |
| 0xE044: 0x6F7A, |
| 0xE045: 0x6F78, |
| 0xE046: 0x6F81, |
| 0xE047: 0x6F80, |
| 0xE048: 0x6F6F, |
| 0xE049: 0x6F5B, |
| 0xE04A: 0x6FF3, |
| 0xE04B: 0x6F6D, |
| 0xE04C: 0x6F82, |
| 0xE04D: 0x6F7C, |
| 0xE04E: 0x6F58, |
| 0xE04F: 0x6F8E, |
| 0xE050: 0x6F91, |
| 0xE051: 0x6FC2, |
| 0xE052: 0x6F66, |
| 0xE053: 0x6FB3, |
| 0xE054: 0x6FA3, |
| 0xE055: 0x6FA1, |
| 0xE056: 0x6FA4, |
| 0xE057: 0x6FB9, |
| 0xE058: 0x6FC6, |
| 0xE059: 0x6FAA, |
| 0xE05A: 0x6FDF, |
| 0xE05B: 0x6FD5, |
| 0xE05C: 0x6FEC, |
| 0xE05D: 0x6FD4, |
| 0xE05E: 0x6FD8, |
| 0xE05F: 0x6FF1, |
| 0xE060: 0x6FEE, |
| 0xE061: 0x6FDB, |
| 0xE062: 0x7009, |
| 0xE063: 0x700B, |
| 0xE064: 0x6FFA, |
| 0xE065: 0x7011, |
| 0xE066: 0x7001, |
| 0xE067: 0x700F, |
| 0xE068: 0x6FFE, |
| 0xE069: 0x701B, |
| 0xE06A: 0x701A, |
| 0xE06B: 0x6F74, |
| 0xE06C: 0x701D, |
| 0xE06D: 0x7018, |
| 0xE06E: 0x701F, |
| 0xE06F: 0x7030, |
| 0xE070: 0x703E, |
| 0xE071: 0x7032, |
| 0xE072: 0x7051, |
| 0xE073: 0x7063, |
| 0xE074: 0x7099, |
| 0xE075: 0x7092, |
| 0xE076: 0x70AF, |
| 0xE077: 0x70F1, |
| 0xE078: 0x70AC, |
| 0xE079: 0x70B8, |
| 0xE07A: 0x70B3, |
| 0xE07B: 0x70AE, |
| 0xE07C: 0x70DF, |
| 0xE07D: 0x70CB, |
| 0xE07E: 0x70DD, |
| 0xE080: 0x70D9, |
| 0xE081: 0x7109, |
| 0xE082: 0x70FD, |
| 0xE083: 0x711C, |
| 0xE084: 0x7119, |
| 0xE085: 0x7165, |
| 0xE086: 0x7155, |
| 0xE087: 0x7188, |
| 0xE088: 0x7166, |
| 0xE089: 0x7162, |
| 0xE08A: 0x714C, |
| 0xE08B: 0x7156, |
| 0xE08C: 0x716C, |
| 0xE08D: 0x718F, |
| 0xE08E: 0x71FB, |
| 0xE08F: 0x7184, |
| 0xE090: 0x7195, |
| 0xE091: 0x71A8, |
| 0xE092: 0x71AC, |
| 0xE093: 0x71D7, |
| 0xE094: 0x71B9, |
| 0xE095: 0x71BE, |
| 0xE096: 0x71D2, |
| 0xE097: 0x71C9, |
| 0xE098: 0x71D4, |
| 0xE099: 0x71CE, |
| 0xE09A: 0x71E0, |
| 0xE09B: 0x71EC, |
| 0xE09C: 0x71E7, |
| 0xE09D: 0x71F5, |
| 0xE09E: 0x71FC, |
| 0xE09F: 0x71F9, |
| 0xE0A0: 0x71FF, |
| 0xE0A1: 0x720D, |
| 0xE0A2: 0x7210, |
| 0xE0A3: 0x721B, |
| 0xE0A4: 0x7228, |
| 0xE0A5: 0x722D, |
| 0xE0A6: 0x722C, |
| 0xE0A7: 0x7230, |
| 0xE0A8: 0x7232, |
| 0xE0A9: 0x723B, |
| 0xE0AA: 0x723C, |
| 0xE0AB: 0x723F, |
| 0xE0AC: 0x7240, |
| 0xE0AD: 0x7246, |
| 0xE0AE: 0x724B, |
| 0xE0AF: 0x7258, |
| 0xE0B0: 0x7274, |
| 0xE0B1: 0x727E, |
| 0xE0B2: 0x7282, |
| 0xE0B3: 0x7281, |
| 0xE0B4: 0x7287, |
| 0xE0B5: 0x7292, |
| 0xE0B6: 0x7296, |
| 0xE0B7: 0x72A2, |
| 0xE0B8: 0x72A7, |
| 0xE0B9: 0x72B9, |
| 0xE0BA: 0x72B2, |
| 0xE0BB: 0x72C3, |
| 0xE0BC: 0x72C6, |
| 0xE0BD: 0x72C4, |
| 0xE0BE: 0x72CE, |
| 0xE0BF: 0x72D2, |
| 0xE0C0: 0x72E2, |
| 0xE0C1: 0x72E0, |
| 0xE0C2: 0x72E1, |
| 0xE0C3: 0x72F9, |
| 0xE0C4: 0x72F7, |
| 0xE0C5: 0x500F, |
| 0xE0C6: 0x7317, |
| 0xE0C7: 0x730A, |
| 0xE0C8: 0x731C, |
| 0xE0C9: 0x7316, |
| 0xE0CA: 0x731D, |
| 0xE0CB: 0x7334, |
| 0xE0CC: 0x732F, |
| 0xE0CD: 0x7329, |
| 0xE0CE: 0x7325, |
| 0xE0CF: 0x733E, |
| 0xE0D0: 0x734E, |
| 0xE0D1: 0x734F, |
| 0xE0D2: 0x9ED8, |
| 0xE0D3: 0x7357, |
| 0xE0D4: 0x736A, |
| 0xE0D5: 0x7368, |
| 0xE0D6: 0x7370, |
| 0xE0D7: 0x7378, |
| 0xE0D8: 0x7375, |
| 0xE0D9: 0x737B, |
| 0xE0DA: 0x737A, |
| 0xE0DB: 0x73C8, |
| 0xE0DC: 0x73B3, |
| 0xE0DD: 0x73CE, |
| 0xE0DE: 0x73BB, |
| 0xE0DF: 0x73C0, |
| 0xE0E0: 0x73E5, |
| 0xE0E1: 0x73EE, |
| 0xE0E2: 0x73DE, |
| 0xE0E3: 0x74A2, |
| 0xE0E4: 0x7405, |
| 0xE0E5: 0x746F, |
| 0xE0E6: 0x7425, |
| 0xE0E7: 0x73F8, |
| 0xE0E8: 0x7432, |
| 0xE0E9: 0x743A, |
| 0xE0EA: 0x7455, |
| 0xE0EB: 0x743F, |
| 0xE0EC: 0x745F, |
| 0xE0ED: 0x7459, |
| 0xE0EE: 0x7441, |
| 0xE0EF: 0x745C, |
| 0xE0F0: 0x7469, |
| 0xE0F1: 0x7470, |
| 0xE0F2: 0x7463, |
| 0xE0F3: 0x746A, |
| 0xE0F4: 0x7476, |
| 0xE0F5: 0x747E, |
| 0xE0F6: 0x748B, |
| 0xE0F7: 0x749E, |
| 0xE0F8: 0x74A7, |
| 0xE0F9: 0x74CA, |
| 0xE0FA: 0x74CF, |
| 0xE0FB: 0x74D4, |
| 0xE0FC: 0x73F1, |
| 0xE140: 0x74E0, |
| 0xE141: 0x74E3, |
| 0xE142: 0x74E7, |
| 0xE143: 0x74E9, |
| 0xE144: 0x74EE, |
| 0xE145: 0x74F2, |
| 0xE146: 0x74F0, |
| 0xE147: 0x74F1, |
| 0xE148: 0x74F8, |
| 0xE149: 0x74F7, |
| 0xE14A: 0x7504, |
| 0xE14B: 0x7503, |
| 0xE14C: 0x7505, |
| 0xE14D: 0x750C, |
| 0xE14E: 0x750E, |
| 0xE14F: 0x750D, |
| 0xE150: 0x7515, |
| 0xE151: 0x7513, |
| 0xE152: 0x751E, |
| 0xE153: 0x7526, |
| 0xE154: 0x752C, |
| 0xE155: 0x753C, |
| 0xE156: 0x7544, |
| 0xE157: 0x754D, |
| 0xE158: 0x754A, |
| 0xE159: 0x7549, |
| 0xE15A: 0x755B, |
| 0xE15B: 0x7546, |
| 0xE15C: 0x755A, |
| 0xE15D: 0x7569, |
| 0xE15E: 0x7564, |
| 0xE15F: 0x7567, |
| 0xE160: 0x756B, |
| 0xE161: 0x756D, |
| 0xE162: 0x7578, |
| 0xE163: 0x7576, |
| 0xE164: 0x7586, |
| 0xE165: 0x7587, |
| 0xE166: 0x7574, |
| 0xE167: 0x758A, |
| 0xE168: 0x7589, |
| 0xE169: 0x7582, |
| 0xE16A: 0x7594, |
| 0xE16B: 0x759A, |
| 0xE16C: 0x759D, |
| 0xE16D: 0x75A5, |
| 0xE16E: 0x75A3, |
| 0xE16F: 0x75C2, |
| 0xE170: 0x75B3, |
| 0xE171: 0x75C3, |
| 0xE172: 0x75B5, |
| 0xE173: 0x75BD, |
| 0xE174: 0x75B8, |
| 0xE175: 0x75BC, |
| 0xE176: 0x75B1, |
| 0xE177: 0x75CD, |
| 0xE178: 0x75CA, |
| 0xE179: 0x75D2, |
| 0xE17A: 0x75D9, |
| 0xE17B: 0x75E3, |
| 0xE17C: 0x75DE, |
| 0xE17D: 0x75FE, |
| 0xE17E: 0x75FF, |
| 0xE180: 0x75FC, |
| 0xE181: 0x7601, |
| 0xE182: 0x75F0, |
| 0xE183: 0x75FA, |
| 0xE184: 0x75F2, |
| 0xE185: 0x75F3, |
| 0xE186: 0x760B, |
| 0xE187: 0x760D, |
| 0xE188: 0x7609, |
| 0xE189: 0x761F, |
| 0xE18A: 0x7627, |
| 0xE18B: 0x7620, |
| 0xE18C: 0x7621, |
| 0xE18D: 0x7622, |
| 0xE18E: 0x7624, |
| 0xE18F: 0x7634, |
| 0xE190: 0x7630, |
| 0xE191: 0x763B, |
| 0xE192: 0x7647, |
| 0xE193: 0x7648, |
| 0xE194: 0x7646, |
| 0xE195: 0x765C, |
| 0xE196: 0x7658, |
| 0xE197: 0x7661, |
| 0xE198: 0x7662, |
| 0xE199: 0x7668, |
| 0xE19A: 0x7669, |
| 0xE19B: 0x766A, |
| 0xE19C: 0x7667, |
| 0xE19D: 0x766C, |
| 0xE19E: 0x7670, |
| 0xE19F: 0x7672, |
| 0xE1A0: 0x7676, |
| 0xE1A1: 0x7678, |
| 0xE1A2: 0x767C, |
| 0xE1A3: 0x7680, |
| 0xE1A4: 0x7683, |
| 0xE1A5: 0x7688, |
| 0xE1A6: 0x768B, |
| 0xE1A7: 0x768E, |
| 0xE1A8: 0x7696, |
| 0xE1A9: 0x7693, |
| 0xE1AA: 0x7699, |
| 0xE1AB: 0x769A, |
| 0xE1AC: 0x76B0, |
| 0xE1AD: 0x76B4, |
| 0xE1AE: 0x76B8, |
| 0xE1AF: 0x76B9, |
| 0xE1B0: 0x76BA, |
| 0xE1B1: 0x76C2, |
| 0xE1B2: 0x76CD, |
| 0xE1B3: 0x76D6, |
| 0xE1B4: 0x76D2, |
| 0xE1B5: 0x76DE, |
| 0xE1B6: 0x76E1, |
| 0xE1B7: 0x76E5, |
| 0xE1B8: 0x76E7, |
| 0xE1B9: 0x76EA, |
| 0xE1BA: 0x862F, |
| 0xE1BB: 0x76FB, |
| 0xE1BC: 0x7708, |
| 0xE1BD: 0x7707, |
| 0xE1BE: 0x7704, |
| 0xE1BF: 0x7729, |
| 0xE1C0: 0x7724, |
| 0xE1C1: 0x771E, |
| 0xE1C2: 0x7725, |
| 0xE1C3: 0x7726, |
| 0xE1C4: 0x771B, |
| 0xE1C5: 0x7737, |
| 0xE1C6: 0x7738, |
| 0xE1C7: 0x7747, |
| 0xE1C8: 0x775A, |
| 0xE1C9: 0x7768, |
| 0xE1CA: 0x776B, |
| 0xE1CB: 0x775B, |
| 0xE1CC: 0x7765, |
| 0xE1CD: 0x777F, |
| 0xE1CE: 0x777E, |
| 0xE1CF: 0x7779, |
| 0xE1D0: 0x778E, |
| 0xE1D1: 0x778B, |
| 0xE1D2: 0x7791, |
| 0xE1D3: 0x77A0, |
| 0xE1D4: 0x779E, |
| 0xE1D5: 0x77B0, |
| 0xE1D6: 0x77B6, |
| 0xE1D7: 0x77B9, |
| 0xE1D8: 0x77BF, |
| 0xE1D9: 0x77BC, |
| 0xE1DA: 0x77BD, |
| 0xE1DB: 0x77BB, |
| 0xE1DC: 0x77C7, |
| 0xE1DD: 0x77CD, |
| 0xE1DE: 0x77D7, |
| 0xE1DF: 0x77DA, |
| 0xE1E0: 0x77DC, |
| 0xE1E1: 0x77E3, |
| 0xE1E2: 0x77EE, |
| 0xE1E3: 0x77FC, |
| 0xE1E4: 0x780C, |
| 0xE1E5: 0x7812, |
| 0xE1E6: 0x7926, |
| 0xE1E7: 0x7820, |
| 0xE1E8: 0x792A, |
| 0xE1E9: 0x7845, |
| 0xE1EA: 0x788E, |
| 0xE1EB: 0x7874, |
| 0xE1EC: 0x7886, |
| 0xE1ED: 0x787C, |
| 0xE1EE: 0x789A, |
| 0xE1EF: 0x788C, |
| 0xE1F0: 0x78A3, |
| 0xE1F1: 0x78B5, |
| 0xE1F2: 0x78AA, |
| 0xE1F3: 0x78AF, |
| 0xE1F4: 0x78D1, |
| 0xE1F5: 0x78C6, |
| 0xE1F6: 0x78CB, |
| 0xE1F7: 0x78D4, |
| 0xE1F8: 0x78BE, |
| 0xE1F9: 0x78BC, |
| 0xE1FA: 0x78C5, |
| 0xE1FB: 0x78CA, |
| 0xE1FC: 0x78EC, |
| 0xE240: 0x78E7, |
| 0xE241: 0x78DA, |
| 0xE242: 0x78FD, |
| 0xE243: 0x78F4, |
| 0xE244: 0x7907, |
| 0xE245: 0x7912, |
| 0xE246: 0x7911, |
| 0xE247: 0x7919, |
| 0xE248: 0x792C, |
| 0xE249: 0x792B, |
| 0xE24A: 0x7940, |
| 0xE24B: 0x7960, |
| 0xE24C: 0x7957, |
| 0xE24D: 0x795F, |
| 0xE24E: 0x795A, |
| 0xE24F: 0x7955, |
| 0xE250: 0x7953, |
| 0xE251: 0x797A, |
| 0xE252: 0x797F, |
| 0xE253: 0x798A, |
| 0xE254: 0x799D, |
| 0xE255: 0x79A7, |
| 0xE256: 0x9F4B, |
| 0xE257: 0x79AA, |
| 0xE258: 0x79AE, |
| 0xE259: 0x79B3, |
| 0xE25A: 0x79B9, |
| 0xE25B: 0x79BA, |
| 0xE25C: 0x79C9, |
| 0xE25D: 0x79D5, |
| 0xE25E: 0x79E7, |
| 0xE25F: 0x79EC, |
| 0xE260: 0x79E1, |
| 0xE261: 0x79E3, |
| 0xE262: 0x7A08, |
| 0xE263: 0x7A0D, |
| 0xE264: 0x7A18, |
| 0xE265: 0x7A19, |
| 0xE266: 0x7A20, |
| 0xE267: 0x7A1F, |
| 0xE268: 0x7980, |
| 0xE269: 0x7A31, |
| 0xE26A: 0x7A3B, |
| 0xE26B: 0x7A3E, |
| 0xE26C: 0x7A37, |
| 0xE26D: 0x7A43, |
| 0xE26E: 0x7A57, |
| 0xE26F: 0x7A49, |
| 0xE270: 0x7A61, |
| 0xE271: 0x7A62, |
| 0xE272: 0x7A69, |
| 0xE273: 0x9F9D, |
| 0xE274: 0x7A70, |
| 0xE275: 0x7A79, |
| 0xE276: 0x7A7D, |
| 0xE277: 0x7A88, |
| 0xE278: 0x7A97, |
| 0xE279: 0x7A95, |
| 0xE27A: 0x7A98, |
| 0xE27B: 0x7A96, |
| 0xE27C: 0x7AA9, |
| 0xE27D: 0x7AC8, |
| 0xE27E: 0x7AB0, |
| 0xE280: 0x7AB6, |
| 0xE281: 0x7AC5, |
| 0xE282: 0x7AC4, |
| 0xE283: 0x7ABF, |
| 0xE284: 0x9083, |
| 0xE285: 0x7AC7, |
| 0xE286: 0x7ACA, |
| 0xE287: 0x7ACD, |
| 0xE288: 0x7ACF, |
| 0xE289: 0x7AD5, |
| 0xE28A: 0x7AD3, |
| 0xE28B: 0x7AD9, |
| 0xE28C: 0x7ADA, |
| 0xE28D: 0x7ADD, |
| 0xE28E: 0x7AE1, |
| 0xE28F: 0x7AE2, |
| 0xE290: 0x7AE6, |
| 0xE291: 0x7AED, |
| 0xE292: 0x7AF0, |
| 0xE293: 0x7B02, |
| 0xE294: 0x7B0F, |
| 0xE295: 0x7B0A, |
| 0xE296: 0x7B06, |
| 0xE297: 0x7B33, |
| 0xE298: 0x7B18, |
| 0xE299: 0x7B19, |
| 0xE29A: 0x7B1E, |
| 0xE29B: 0x7B35, |
| 0xE29C: 0x7B28, |
| 0xE29D: 0x7B36, |
| 0xE29E: 0x7B50, |
| 0xE29F: 0x7B7A, |
| 0xE2A0: 0x7B04, |
| 0xE2A1: 0x7B4D, |
| 0xE2A2: 0x7B0B, |
| 0xE2A3: 0x7B4C, |
| 0xE2A4: 0x7B45, |
| 0xE2A5: 0x7B75, |
| 0xE2A6: 0x7B65, |
| 0xE2A7: 0x7B74, |
| 0xE2A8: 0x7B67, |
| 0xE2A9: 0x7B70, |
| 0xE2AA: 0x7B71, |
| 0xE2AB: 0x7B6C, |
| 0xE2AC: 0x7B6E, |
| 0xE2AD: 0x7B9D, |
| 0xE2AE: 0x7B98, |
| 0xE2AF: 0x7B9F, |
| 0xE2B0: 0x7B8D, |
| 0xE2B1: 0x7B9C, |
| 0xE2B2: 0x7B9A, |
| 0xE2B3: 0x7B8B, |
| 0xE2B4: 0x7B92, |
| 0xE2B5: 0x7B8F, |
| 0xE2B6: 0x7B5D, |
| 0xE2B7: 0x7B99, |
| 0xE2B8: 0x7BCB, |
| 0xE2B9: 0x7BC1, |
| 0xE2BA: 0x7BCC, |
| 0xE2BB: 0x7BCF, |
| 0xE2BC: 0x7BB4, |
| 0xE2BD: 0x7BC6, |
| 0xE2BE: 0x7BDD, |
| 0xE2BF: 0x7BE9, |
| 0xE2C0: 0x7C11, |
| 0xE2C1: 0x7C14, |
| 0xE2C2: 0x7BE6, |
| 0xE2C3: 0x7BE5, |
| 0xE2C4: 0x7C60, |
| 0xE2C5: 0x7C00, |
| 0xE2C6: 0x7C07, |
| 0xE2C7: 0x7C13, |
| 0xE2C8: 0x7BF3, |
| 0xE2C9: 0x7BF7, |
| 0xE2CA: 0x7C17, |
| 0xE2CB: 0x7C0D, |
| 0xE2CC: 0x7BF6, |
| 0xE2CD: 0x7C23, |
| 0xE2CE: 0x7C27, |
| 0xE2CF: 0x7C2A, |
| 0xE2D0: 0x7C1F, |
| 0xE2D1: 0x7C37, |
| 0xE2D2: 0x7C2B, |
| 0xE2D3: 0x7C3D, |
| 0xE2D4: 0x7C4C, |
| 0xE2D5: 0x7C43, |
| 0xE2D6: 0x7C54, |
| 0xE2D7: 0x7C4F, |
| 0xE2D8: 0x7C40, |
| 0xE2D9: 0x7C50, |
| 0xE2DA: 0x7C58, |
| 0xE2DB: 0x7C5F, |
| 0xE2DC: 0x7C64, |
| 0xE2DD: 0x7C56, |
| 0xE2DE: 0x7C65, |
| 0xE2DF: 0x7C6C, |
| 0xE2E0: 0x7C75, |
| 0xE2E1: 0x7C83, |
| 0xE2E2: 0x7C90, |
| 0xE2E3: 0x7CA4, |
| 0xE2E4: 0x7CAD, |
| 0xE2E5: 0x7CA2, |
| 0xE2E6: 0x7CAB, |
| 0xE2E7: 0x7CA1, |
| 0xE2E8: 0x7CA8, |
| 0xE2E9: 0x7CB3, |
| 0xE2EA: 0x7CB2, |
| 0xE2EB: 0x7CB1, |
| 0xE2EC: 0x7CAE, |
| 0xE2ED: 0x7CB9, |
| 0xE2EE: 0x7CBD, |
| 0xE2EF: 0x7CC0, |
| 0xE2F0: 0x7CC5, |
| 0xE2F1: 0x7CC2, |
| 0xE2F2: 0x7CD8, |
| 0xE2F3: 0x7CD2, |
| 0xE2F4: 0x7CDC, |
| 0xE2F5: 0x7CE2, |
| 0xE2F6: 0x9B3B, |
| 0xE2F7: 0x7CEF, |
| 0xE2F8: 0x7CF2, |
| 0xE2F9: 0x7CF4, |
| 0xE2FA: 0x7CF6, |
| 0xE2FB: 0x7CFA, |
| 0xE2FC: 0x7D06, |
| 0xE340: 0x7D02, |
| 0xE341: 0x7D1C, |
| 0xE342: 0x7D15, |
| 0xE343: 0x7D0A, |
| 0xE344: 0x7D45, |
| 0xE345: 0x7D4B, |
| 0xE346: 0x7D2E, |
| 0xE347: 0x7D32, |
| 0xE348: 0x7D3F, |
| 0xE349: 0x7D35, |
| 0xE34A: 0x7D46, |
| 0xE34B: 0x7D73, |
| 0xE34C: 0x7D56, |
| 0xE34D: 0x7D4E, |
| 0xE34E: 0x7D72, |
| 0xE34F: 0x7D68, |
| 0xE350: 0x7D6E, |
| 0xE351: 0x7D4F, |
| 0xE352: 0x7D63, |
| 0xE353: 0x7D93, |
| 0xE354: 0x7D89, |
| 0xE355: 0x7D5B, |
| 0xE356: 0x7D8F, |
| 0xE357: 0x7D7D, |
| 0xE358: 0x7D9B, |
| 0xE359: 0x7DBA, |
| 0xE35A: 0x7DAE, |
| 0xE35B: 0x7DA3, |
| 0xE35C: 0x7DB5, |
| 0xE35D: 0x7DC7, |
| 0xE35E: 0x7DBD, |
| 0xE35F: 0x7DAB, |
| 0xE360: 0x7E3D, |
| 0xE361: 0x7DA2, |
| 0xE362: 0x7DAF, |
| 0xE363: 0x7DDC, |
| 0xE364: 0x7DB8, |
| 0xE365: 0x7D9F, |
| 0xE366: 0x7DB0, |
| 0xE367: 0x7DD8, |
| 0xE368: 0x7DDD, |
| 0xE369: 0x7DE4, |
| 0xE36A: 0x7DDE, |
| 0xE36B: 0x7DFB, |
| 0xE36C: 0x7DF2, |
| 0xE36D: 0x7DE1, |
| 0xE36E: 0x7E05, |
| 0xE36F: 0x7E0A, |
| 0xE370: 0x7E23, |
| 0xE371: 0x7E21, |
| 0xE372: 0x7E12, |
| 0xE373: 0x7E31, |
| 0xE374: 0x7E1F, |
| 0xE375: 0x7E09, |
| 0xE376: 0x7E0B, |
| 0xE377: 0x7E22, |
| 0xE378: 0x7E46, |
| 0xE379: 0x7E66, |
| 0xE37A: 0x7E3B, |
| 0xE37B: 0x7E35, |
| 0xE37C: 0x7E39, |
| 0xE37D: 0x7E43, |
| 0xE37E: 0x7E37, |
| 0xE380: 0x7E32, |
| 0xE381: 0x7E3A, |
| 0xE382: 0x7E67, |
| 0xE383: 0x7E5D, |
| 0xE384: 0x7E56, |
| 0xE385: 0x7E5E, |
| 0xE386: 0x7E59, |
| 0xE387: 0x7E5A, |
| 0xE388: 0x7E79, |
| 0xE389: 0x7E6A, |
| 0xE38A: 0x7E69, |
| 0xE38B: 0x7E7C, |
| 0xE38C: 0x7E7B, |
| 0xE38D: 0x7E83, |
| 0xE38E: 0x7DD5, |
| 0xE38F: 0x7E7D, |
| 0xE390: 0x8FAE, |
| 0xE391: 0x7E7F, |
| 0xE392: 0x7E88, |
| 0xE393: 0x7E89, |
| 0xE394: 0x7E8C, |
| 0xE395: 0x7E92, |
| 0xE396: 0x7E90, |
| 0xE397: 0x7E93, |
| 0xE398: 0x7E94, |
| 0xE399: 0x7E96, |
| 0xE39A: 0x7E8E, |
| 0xE39B: 0x7E9B, |
| 0xE39C: 0x7E9C, |
| 0xE39D: 0x7F38, |
| 0xE39E: 0x7F3A, |
| 0xE39F: 0x7F45, |
| 0xE3A0: 0x7F4C, |
| 0xE3A1: 0x7F4D, |
| 0xE3A2: 0x7F4E, |
| 0xE3A3: 0x7F50, |
| 0xE3A4: 0x7F51, |
| 0xE3A5: 0x7F55, |
| 0xE3A6: 0x7F54, |
| 0xE3A7: 0x7F58, |
| 0xE3A8: 0x7F5F, |
| 0xE3A9: 0x7F60, |
| 0xE3AA: 0x7F68, |
| 0xE3AB: 0x7F69, |
| 0xE3AC: 0x7F67, |
| 0xE3AD: 0x7F78, |
| 0xE3AE: 0x7F82, |
| 0xE3AF: 0x7F86, |
| 0xE3B0: 0x7F83, |
| 0xE3B1: 0x7F88, |
| 0xE3B2: 0x7F87, |
| 0xE3B3: 0x7F8C, |
| 0xE3B4: 0x7F94, |
| 0xE3B5: 0x7F9E, |
| 0xE3B6: 0x7F9D, |
| 0xE3B7: 0x7F9A, |
| 0xE3B8: 0x7FA3, |
| 0xE3B9: 0x7FAF, |
| 0xE3BA: 0x7FB2, |
| 0xE3BB: 0x7FB9, |
| 0xE3BC: 0x7FAE, |
| 0xE3BD: 0x7FB6, |
| 0xE3BE: 0x7FB8, |
| 0xE3BF: 0x8B71, |
| 0xE3C0: 0x7FC5, |
| 0xE3C1: 0x7FC6, |
| 0xE3C2: 0x7FCA, |
| 0xE3C3: 0x7FD5, |
| 0xE3C4: 0x7FD4, |
| 0xE3C5: 0x7FE1, |
| 0xE3C6: 0x7FE6, |
| 0xE3C7: 0x7FE9, |
| 0xE3C8: 0x7FF3, |
| 0xE3C9: 0x7FF9, |
| 0xE3CA: 0x98DC, |
| 0xE3CB: 0x8006, |
| 0xE3CC: 0x8004, |
| 0xE3CD: 0x800B, |
| 0xE3CE: 0x8012, |
| 0xE3CF: 0x8018, |
| 0xE3D0: 0x8019, |
| 0xE3D1: 0x801C, |
| 0xE3D2: 0x8021, |
| 0xE3D3: 0x8028, |
| 0xE3D4: 0x803F, |
| 0xE3D5: 0x803B, |
| 0xE3D6: 0x804A, |
| 0xE3D7: 0x8046, |
| 0xE3D8: 0x8052, |
| 0xE3D9: 0x8058, |
| 0xE3DA: 0x805A, |
| 0xE3DB: 0x805F, |
| 0xE3DC: 0x8062, |
| 0xE3DD: 0x8068, |
| 0xE3DE: 0x8073, |
| 0xE3DF: 0x8072, |
| 0xE3E0: 0x8070, |
| 0xE3E1: 0x8076, |
| 0xE3E2: 0x8079, |
| 0xE3E3: 0x807D, |
| 0xE3E4: 0x807F, |
| 0xE3E5: 0x8084, |
| 0xE3E6: 0x8086, |
| 0xE3E7: 0x8085, |
| 0xE3E8: 0x809B, |
| 0xE3E9: 0x8093, |
| 0xE3EA: 0x809A, |
| 0xE3EB: 0x80AD, |
| 0xE3EC: 0x5190, |
| 0xE3ED: 0x80AC, |
| 0xE3EE: 0x80DB, |
| 0xE3EF: 0x80E5, |
| 0xE3F0: 0x80D9, |
| 0xE3F1: 0x80DD, |
| 0xE3F2: 0x80C4, |
| 0xE3F3: 0x80DA, |
| 0xE3F4: 0x80D6, |
| 0xE3F5: 0x8109, |
| 0xE3F6: 0x80EF, |
| 0xE3F7: 0x80F1, |
| 0xE3F8: 0x811B, |
| 0xE3F9: 0x8129, |
| 0xE3FA: 0x8123, |
| 0xE3FB: 0x812F, |
| 0xE3FC: 0x814B, |
| 0xE440: 0x968B, |
| 0xE441: 0x8146, |
| 0xE442: 0x813E, |
| 0xE443: 0x8153, |
| 0xE444: 0x8151, |
| 0xE445: 0x80FC, |
| 0xE446: 0x8171, |
| 0xE447: 0x816E, |
| 0xE448: 0x8165, |
| 0xE449: 0x8166, |
| 0xE44A: 0x8174, |
| 0xE44B: 0x8183, |
| 0xE44C: 0x8188, |
| 0xE44D: 0x818A, |
| 0xE44E: 0x8180, |
| 0xE44F: 0x8182, |
| 0xE450: 0x81A0, |
| 0xE451: 0x8195, |
| 0xE452: 0x81A4, |
| 0xE453: 0x81A3, |
| 0xE454: 0x815F, |
| 0xE455: 0x8193, |
| 0xE456: 0x81A9, |
| 0xE457: 0x81B0, |
| 0xE458: 0x81B5, |
| 0xE459: 0x81BE, |
| 0xE45A: 0x81B8, |
| 0xE45B: 0x81BD, |
| 0xE45C: 0x81C0, |
| 0xE45D: 0x81C2, |
| 0xE45E: 0x81BA, |
| 0xE45F: 0x81C9, |
| 0xE460: 0x81CD, |
| 0xE461: 0x81D1, |
| 0xE462: 0x81D9, |
| 0xE463: 0x81D8, |
| 0xE464: 0x81C8, |
| 0xE465: 0x81DA, |
| 0xE466: 0x81DF, |
| 0xE467: 0x81E0, |
| 0xE468: 0x81E7, |
| 0xE469: 0x81FA, |
| 0xE46A: 0x81FB, |
| 0xE46B: 0x81FE, |
| 0xE46C: 0x8201, |
| 0xE46D: 0x8202, |
| 0xE46E: 0x8205, |
| 0xE46F: 0x8207, |
| 0xE470: 0x820A, |
| 0xE471: 0x820D, |
| 0xE472: 0x8210, |
| 0xE473: 0x8216, |
| 0xE474: 0x8229, |
| 0xE475: 0x822B, |
| 0xE476: 0x8238, |
| 0xE477: 0x8233, |
| 0xE478: 0x8240, |
| 0xE479: 0x8259, |
| 0xE47A: 0x8258, |
| 0xE47B: 0x825D, |
| 0xE47C: 0x825A, |
| 0xE47D: 0x825F, |
| 0xE47E: 0x8264, |
| 0xE480: 0x8262, |
| 0xE481: 0x8268, |
| 0xE482: 0x826A, |
| 0xE483: 0x826B, |
| 0xE484: 0x822E, |
| 0xE485: 0x8271, |
| 0xE486: 0x8277, |
| 0xE487: 0x8278, |
| 0xE488: 0x827E, |
| 0xE489: 0x828D, |
| 0xE48A: 0x8292, |
| 0xE48B: 0x82AB, |
| 0xE48C: 0x829F, |
| 0xE48D: 0x82BB, |
| 0xE48E: 0x82AC, |
| 0xE48F: 0x82E1, |
| 0xE490: 0x82E3, |
| 0xE491: 0x82DF, |
| 0xE492: 0x82D2, |
| 0xE493: 0x82F4, |
| 0xE494: 0x82F3, |
| 0xE495: 0x82FA, |
| 0xE496: 0x8393, |
| 0xE497: 0x8303, |
| 0xE498: 0x82FB, |
| 0xE499: 0x82F9, |
| 0xE49A: 0x82DE, |
| 0xE49B: 0x8306, |
| 0xE49C: 0x82DC, |
| 0xE49D: 0x8309, |
| 0xE49E: 0x82D9, |
| 0xE49F: 0x8335, |
| 0xE4A0: 0x8334, |
| 0xE4A1: 0x8316, |
| 0xE4A2: 0x8332, |
| 0xE4A3: 0x8331, |
| 0xE4A4: 0x8340, |
| 0xE4A5: 0x8339, |
| 0xE4A6: 0x8350, |
| 0xE4A7: 0x8345, |
| 0xE4A8: 0x832F, |
| 0xE4A9: 0x832B, |
| 0xE4AA: 0x8317, |
| 0xE4AB: 0x8318, |
| 0xE4AC: 0x8385, |
| 0xE4AD: 0x839A, |
| 0xE4AE: 0x83AA, |
| 0xE4AF: 0x839F, |
| 0xE4B0: 0x83A2, |
| 0xE4B1: 0x8396, |
| 0xE4B2: 0x8323, |
| 0xE4B3: 0x838E, |
| 0xE4B4: 0x8387, |
| 0xE4B5: 0x838A, |
| 0xE4B6: 0x837C, |
| 0xE4B7: 0x83B5, |
| 0xE4B8: 0x8373, |
| 0xE4B9: 0x8375, |
| 0xE4BA: 0x83A0, |
| 0xE4BB: 0x8389, |
| 0xE4BC: 0x83A8, |
| 0xE4BD: 0x83F4, |
| 0xE4BE: 0x8413, |
| 0xE4BF: 0x83EB, |
| 0xE4C0: 0x83CE, |
| 0xE4C1: 0x83FD, |
| 0xE4C2: 0x8403, |
| 0xE4C3: 0x83D8, |
| 0xE4C4: 0x840B, |
| 0xE4C5: 0x83C1, |
| 0xE4C6: 0x83F7, |
| 0xE4C7: 0x8407, |
| 0xE4C8: 0x83E0, |
| 0xE4C9: 0x83F2, |
| 0xE4CA: 0x840D, |
| 0xE4CB: 0x8422, |
| 0xE4CC: 0x8420, |
| 0xE4CD: 0x83BD, |
| 0xE4CE: 0x8438, |
| 0xE4CF: 0x8506, |
| 0xE4D0: 0x83FB, |
| 0xE4D1: 0x846D, |
| 0xE4D2: 0x842A, |
| 0xE4D3: 0x843C, |
| 0xE4D4: 0x855A, |
| 0xE4D5: 0x8484, |
| 0xE4D6: 0x8477, |
| 0xE4D7: 0x846B, |
| 0xE4D8: 0x84AD, |
| 0xE4D9: 0x846E, |
| 0xE4DA: 0x8482, |
| 0xE4DB: 0x8469, |
| 0xE4DC: 0x8446, |
| 0xE4DD: 0x842C, |
| 0xE4DE: 0x846F, |
| 0xE4DF: 0x8479, |
| 0xE4E0: 0x8435, |
| 0xE4E1: 0x84CA, |
| 0xE4E2: 0x8462, |
| 0xE4E3: 0x84B9, |
| 0xE4E4: 0x84BF, |
| 0xE4E5: 0x849F, |
| 0xE4E6: 0x84D9, |
| 0xE4E7: 0x84CD, |
| 0xE4E8: 0x84BB, |
| 0xE4E9: 0x84DA, |
| 0xE4EA: 0x84D0, |
| 0xE4EB: 0x84C1, |
| 0xE4EC: 0x84C6, |
| 0xE4ED: 0x84D6, |
| 0xE4EE: 0x84A1, |
| 0xE4EF: 0x8521, |
| 0xE4F0: 0x84FF, |
| 0xE4F1: 0x84F4, |
| 0xE4F2: 0x8517, |
| 0xE4F3: 0x8518, |
| 0xE4F4: 0x852C, |
| 0xE4F5: 0x851F, |
| 0xE4F6: 0x8515, |
| 0xE4F7: 0x8514, |
| 0xE4F8: 0x84FC, |
| 0xE4F9: 0x8540, |
| 0xE4FA: 0x8563, |
| 0xE4FB: 0x8558, |
| 0xE4FC: 0x8548, |
| 0xE540: 0x8541, |
| 0xE541: 0x8602, |
| 0xE542: 0x854B, |
| 0xE543: 0x8555, |
| 0xE544: 0x8580, |
| 0xE545: 0x85A4, |
| 0xE546: 0x8588, |
| 0xE547: 0x8591, |
| 0xE548: 0x858A, |
| 0xE549: 0x85A8, |
| 0xE54A: 0x856D, |
| 0xE54B: 0x8594, |
| 0xE54C: 0x859B, |
| 0xE54D: 0x85EA, |
| 0xE54E: 0x8587, |
| 0xE54F: 0x859C, |
| 0xE550: 0x8577, |
| 0xE551: 0x857E, |
| 0xE552: 0x8590, |
| 0xE553: 0x85C9, |
| 0xE554: 0x85BA, |
| 0xE555: 0x85CF, |
| 0xE556: 0x85B9, |
| 0xE557: 0x85D0, |
| 0xE558: 0x85D5, |
| 0xE559: 0x85DD, |
| 0xE55A: 0x85E5, |
| 0xE55B: 0x85DC, |
| 0xE55C: 0x85F9, |
| 0xE55D: 0x860A, |
| 0xE55E: 0x8613, |
| 0xE55F: 0x860B, |
| 0xE560: 0x85FE, |
| 0xE561: 0x85FA, |
| 0xE562: 0x8606, |
| 0xE563: 0x8622, |
| 0xE564: 0x861A, |
| 0xE565: 0x8630, |
| 0xE566: 0x863F, |
| 0xE567: 0x864D, |
| 0xE568: 0x4E55, |
| 0xE569: 0x8654, |
| 0xE56A: 0x865F, |
| 0xE56B: 0x8667, |
| 0xE56C: 0x8671, |
| 0xE56D: 0x8693, |
| 0xE56E: 0x86A3, |
| 0xE56F: 0x86A9, |
| 0xE570: 0x86AA, |
| 0xE571: 0x868B, |
| 0xE572: 0x868C, |
| 0xE573: 0x86B6, |
| 0xE574: 0x86AF, |
| 0xE575: 0x86C4, |
| 0xE576: 0x86C6, |
| 0xE577: 0x86B0, |
| 0xE578: 0x86C9, |
| 0xE579: 0x8823, |
| 0xE57A: 0x86AB, |
| 0xE57B: 0x86D4, |
| 0xE57C: 0x86DE, |
| 0xE57D: 0x86E9, |
| 0xE57E: 0x86EC, |
| 0xE580: 0x86DF, |
| 0xE581: 0x86DB, |
| 0xE582: 0x86EF, |
| 0xE583: 0x8712, |
| 0xE584: 0x8706, |
| 0xE585: 0x8708, |
| 0xE586: 0x8700, |
| 0xE587: 0x8703, |
| 0xE588: 0x86FB, |
| 0xE589: 0x8711, |
| 0xE58A: 0x8709, |
| 0xE58B: 0x870D, |
| 0xE58C: 0x86F9, |
| 0xE58D: 0x870A, |
| 0xE58E: 0x8734, |
| 0xE58F: 0x873F, |
| 0xE590: 0x8737, |
| 0xE591: 0x873B, |
| 0xE592: 0x8725, |
| 0xE593: 0x8729, |
| 0xE594: 0x871A, |
| 0xE595: 0x8760, |
| 0xE596: 0x875F, |
| 0xE597: 0x8778, |
| 0xE598: 0x874C, |
| 0xE599: 0x874E, |
| 0xE59A: 0x8774, |
| 0xE59B: 0x8757, |
| 0xE59C: 0x8768, |
| 0xE59D: 0x876E, |
| 0xE59E: 0x8759, |
| 0xE59F: 0x8753, |
| 0xE5A0: 0x8763, |
| 0xE5A1: 0x876A, |
| 0xE5A2: 0x8805, |
| 0xE5A3: 0x87A2, |
| 0xE5A4: 0x879F, |
| 0xE5A5: 0x8782, |
| 0xE5A6: 0x87AF, |
| 0xE5A7: 0x87CB, |
| 0xE5A8: 0x87BD, |
| 0xE5A9: 0x87C0, |
| 0xE5AA: 0x87D0, |
| 0xE5AB: 0x96D6, |
| 0xE5AC: 0x87AB, |
| 0xE5AD: 0x87C4, |
| 0xE5AE: 0x87B3, |
| 0xE5AF: 0x87C7, |
| 0xE5B0: 0x87C6, |
| 0xE5B1: 0x87BB, |
| 0xE5B2: 0x87EF, |
| 0xE5B3: 0x87F2, |
| 0xE5B4: 0x87E0, |
| 0xE5B5: 0x880F, |
| 0xE5B6: 0x880D, |
| 0xE5B7: 0x87FE, |
| 0xE5B8: 0x87F6, |
| 0xE5B9: 0x87F7, |
| 0xE5BA: 0x880E, |
| 0xE5BB: 0x87D2, |
| 0xE5BC: 0x8811, |
| 0xE5BD: 0x8816, |
| 0xE5BE: 0x8815, |
| 0xE5BF: 0x8822, |
| 0xE5C0: 0x8821, |
| 0xE5C1: 0x8831, |
| 0xE5C2: 0x8836, |
| 0xE5C3: 0x8839, |
| 0xE5C4: 0x8827, |
| 0xE5C5: 0x883B, |
| 0xE5C6: 0x8844, |
| 0xE5C7: 0x8842, |
| 0xE5C8: 0x8852, |
| 0xE5C9: 0x8859, |
| 0xE5CA: 0x885E, |
| 0xE5CB: 0x8862, |
| 0xE5CC: 0x886B, |
| 0xE5CD: 0x8881, |
| 0xE5CE: 0x887E, |
| 0xE5CF: 0x889E, |
| 0xE5D0: 0x8875, |
| 0xE5D1: 0x887D, |
| 0xE5D2: 0x88B5, |
| 0xE5D3: 0x8872, |
| 0xE5D4: 0x8882, |
| 0xE5D5: 0x8897, |
| 0xE5D6: 0x8892, |
| 0xE5D7: 0x88AE, |
| 0xE5D8: 0x8899, |
| 0xE5D9: 0x88A2, |
| 0xE5DA: 0x888D, |
| 0xE5DB: 0x88A4, |
| 0xE5DC: 0x88B0, |
| 0xE5DD: 0x88BF, |
| 0xE5DE: 0x88B1, |
| 0xE5DF: 0x88C3, |
| 0xE5E0: 0x88C4, |
| 0xE5E1: 0x88D4, |
| 0xE5E2: 0x88D8, |
| 0xE5E3: 0x88D9, |
| 0xE5E4: 0x88DD, |
| 0xE5E5: 0x88F9, |
| 0xE5E6: 0x8902, |
| 0xE5E7: 0x88FC, |
| 0xE5E8: 0x88F4, |
| 0xE5E9: 0x88E8, |
| 0xE5EA: 0x88F2, |
| 0xE5EB: 0x8904, |
| 0xE5EC: 0x890C, |
| 0xE5ED: 0x890A, |
| 0xE5EE: 0x8913, |
| 0xE5EF: 0x8943, |
| 0xE5F0: 0x891E, |
| 0xE5F1: 0x8925, |
| 0xE5F2: 0x892A, |
| 0xE5F3: 0x892B, |
| 0xE5F4: 0x8941, |
| 0xE5F5: 0x8944, |
| 0xE5F6: 0x893B, |
| 0xE5F7: 0x8936, |
| 0xE5F8: 0x8938, |
| 0xE5F9: 0x894C, |
| 0xE5FA: 0x891D, |
| 0xE5FB: 0x8960, |
| 0xE5FC: 0x895E, |
| 0xE640: 0x8966, |
| 0xE641: 0x8964, |
| 0xE642: 0x896D, |
| 0xE643: 0x896A, |
| 0xE644: 0x896F, |
| 0xE645: 0x8974, |
| 0xE646: 0x8977, |
| 0xE647: 0x897E, |
| 0xE648: 0x8983, |
| 0xE649: 0x8988, |
| 0xE64A: 0x898A, |
| 0xE64B: 0x8993, |
| 0xE64C: 0x8998, |
| 0xE64D: 0x89A1, |
| 0xE64E: 0x89A9, |
| 0xE64F: 0x89A6, |
| 0xE650: 0x89AC, |
| 0xE651: 0x89AF, |
| 0xE652: 0x89B2, |
| 0xE653: 0x89BA, |
| 0xE654: 0x89BD, |
| 0xE655: 0x89BF, |
| 0xE656: 0x89C0, |
| 0xE657: 0x89DA, |
| 0xE658: 0x89DC, |
| 0xE659: 0x89DD, |
| 0xE65A: 0x89E7, |
| 0xE65B: 0x89F4, |
| 0xE65C: 0x89F8, |
| 0xE65D: 0x8A03, |
| 0xE65E: 0x8A16, |
| 0xE65F: 0x8A10, |
| 0xE660: 0x8A0C, |
| 0xE661: 0x8A1B, |
| 0xE662: 0x8A1D, |
| 0xE663: 0x8A25, |
| 0xE664: 0x8A36, |
| 0xE665: 0x8A41, |
| 0xE666: 0x8A5B, |
| 0xE667: 0x8A52, |
| 0xE668: 0x8A46, |
| 0xE669: 0x8A48, |
| 0xE66A: 0x8A7C, |
| 0xE66B: 0x8A6D, |
| 0xE66C: 0x8A6C, |
| 0xE66D: 0x8A62, |
| 0xE66E: 0x8A85, |
| 0xE66F: 0x8A82, |
| 0xE670: 0x8A84, |
| 0xE671: 0x8AA8, |
| 0xE672: 0x8AA1, |
| 0xE673: 0x8A91, |
| 0xE674: 0x8AA5, |
| 0xE675: 0x8AA6, |
| 0xE676: 0x8A9A, |
| 0xE677: 0x8AA3, |
| 0xE678: 0x8AC4, |
| 0xE679: 0x8ACD, |
| 0xE67A: 0x8AC2, |
| 0xE67B: 0x8ADA, |
| 0xE67C: 0x8AEB, |
| 0xE67D: 0x8AF3, |
| 0xE67E: 0x8AE7, |
| 0xE680: 0x8AE4, |
| 0xE681: 0x8AF1, |
| 0xE682: 0x8B14, |
| 0xE683: 0x8AE0, |
| 0xE684: 0x8AE2, |
| 0xE685: 0x8AF7, |
| 0xE686: 0x8ADE, |
| 0xE687: 0x8ADB, |
| 0xE688: 0x8B0C, |
| 0xE689: 0x8B07, |
| 0xE68A: 0x8B1A, |
| 0xE68B: 0x8AE1, |
| 0xE68C: 0x8B16, |
| 0xE68D: 0x8B10, |
| 0xE68E: 0x8B17, |
| 0xE68F: 0x8B20, |
| 0xE690: 0x8B33, |
| 0xE691: 0x97AB, |
| 0xE692: 0x8B26, |
| 0xE693: 0x8B2B, |
| 0xE694: 0x8B3E, |
| 0xE695: 0x8B28, |
| 0xE696: 0x8B41, |
| 0xE697: 0x8B4C, |
| 0xE698: 0x8B4F, |
| 0xE699: 0x8B4E, |
| 0xE69A: 0x8B49, |
| 0xE69B: 0x8B56, |
| 0xE69C: 0x8B5B, |
| 0xE69D: 0x8B5A, |
| 0xE69E: 0x8B6B, |
| 0xE69F: 0x8B5F, |
| 0xE6A0: 0x8B6C, |
| 0xE6A1: 0x8B6F, |
| 0xE6A2: 0x8B74, |
| 0xE6A3: 0x8B7D, |
| 0xE6A4: 0x8B80, |
| 0xE6A5: 0x8B8C, |
| 0xE6A6: 0x8B8E, |
| 0xE6A7: 0x8B92, |
| 0xE6A8: 0x8B93, |
| 0xE6A9: 0x8B96, |
| 0xE6AA: 0x8B99, |
| 0xE6AB: 0x8B9A, |
| 0xE6AC: 0x8C3A, |
| 0xE6AD: 0x8C41, |
| 0xE6AE: 0x8C3F, |
| 0xE6AF: 0x8C48, |
| 0xE6B0: 0x8C4C, |
| 0xE6B1: 0x8C4E, |
| 0xE6B2: 0x8C50, |
| 0xE6B3: 0x8C55, |
| 0xE6B4: 0x8C62, |
| 0xE6B5: 0x8C6C, |
| 0xE6B6: 0x8C78, |
| 0xE6B7: 0x8C7A, |
| 0xE6B8: 0x8C82, |
| 0xE6B9: 0x8C89, |
| 0xE6BA: 0x8C85, |
| 0xE6BB: 0x8C8A, |
| 0xE6BC: 0x8C8D, |
| 0xE6BD: 0x8C8E, |
| 0xE6BE: 0x8C94, |
| 0xE6BF: 0x8C7C, |
| 0xE6C0: 0x8C98, |
| 0xE6C1: 0x621D, |
| 0xE6C2: 0x8CAD, |
| 0xE6C3: 0x8CAA, |
| 0xE6C4: 0x8CBD, |
| 0xE6C5: 0x8CB2, |
| 0xE6C6: 0x8CB3, |
| 0xE6C7: 0x8CAE, |
| 0xE6C8: 0x8CB6, |
| 0xE6C9: 0x8CC8, |
| 0xE6CA: 0x8CC1, |
| 0xE6CB: 0x8CE4, |
| 0xE6CC: 0x8CE3, |
| 0xE6CD: 0x8CDA, |
| 0xE6CE: 0x8CFD, |
| 0xE6CF: 0x8CFA, |
| 0xE6D0: 0x8CFB, |
| 0xE6D1: 0x8D04, |
| 0xE6D2: 0x8D05, |
| 0xE6D3: 0x8D0A, |
| 0xE6D4: 0x8D07, |
| 0xE6D5: 0x8D0F, |
| 0xE6D6: 0x8D0D, |
| 0xE6D7: 0x8D10, |
| 0xE6D8: 0x9F4E, |
| 0xE6D9: 0x8D13, |
| 0xE6DA: 0x8CCD, |
| 0xE6DB: 0x8D14, |
| 0xE6DC: 0x8D16, |
| 0xE6DD: 0x8D67, |
| 0xE6DE: 0x8D6D, |
| 0xE6DF: 0x8D71, |
| 0xE6E0: 0x8D73, |
| 0xE6E1: 0x8D81, |
| 0xE6E2: 0x8D99, |
| 0xE6E3: 0x8DC2, |
| 0xE6E4: 0x8DBE, |
| 0xE6E5: 0x8DBA, |
| 0xE6E6: 0x8DCF, |
| 0xE6E7: 0x8DDA, |
| 0xE6E8: 0x8DD6, |
| 0xE6E9: 0x8DCC, |
| 0xE6EA: 0x8DDB, |
| 0xE6EB: 0x8DCB, |
| 0xE6EC: 0x8DEA, |
| 0xE6ED: 0x8DEB, |
| 0xE6EE: 0x8DDF, |
| 0xE6EF: 0x8DE3, |
| 0xE6F0: 0x8DFC, |
| 0xE6F1: 0x8E08, |
| 0xE6F2: 0x8E09, |
| 0xE6F3: 0x8DFF, |
| 0xE6F4: 0x8E1D, |
| 0xE6F5: 0x8E1E, |
| 0xE6F6: 0x8E10, |
| 0xE6F7: 0x8E1F, |
| 0xE6F8: 0x8E42, |
| 0xE6F9: 0x8E35, |
| 0xE6FA: 0x8E30, |
| 0xE6FB: 0x8E34, |
| 0xE6FC: 0x8E4A, |
| 0xE740: 0x8E47, |
| 0xE741: 0x8E49, |
| 0xE742: 0x8E4C, |
| 0xE743: 0x8E50, |
| 0xE744: 0x8E48, |
| 0xE745: 0x8E59, |
| 0xE746: 0x8E64, |
| 0xE747: 0x8E60, |
| 0xE748: 0x8E2A, |
| 0xE749: 0x8E63, |
| 0xE74A: 0x8E55, |
| 0xE74B: 0x8E76, |
| 0xE74C: 0x8E72, |
| 0xE74D: 0x8E7C, |
| 0xE74E: 0x8E81, |
| 0xE74F: 0x8E87, |
| 0xE750: 0x8E85, |
| 0xE751: 0x8E84, |
| 0xE752: 0x8E8B, |
| 0xE753: 0x8E8A, |
| 0xE754: 0x8E93, |
| 0xE755: 0x8E91, |
| 0xE756: 0x8E94, |
| 0xE757: 0x8E99, |
| 0xE758: 0x8EAA, |
| 0xE759: 0x8EA1, |
| 0xE75A: 0x8EAC, |
| 0xE75B: 0x8EB0, |
| 0xE75C: 0x8EC6, |
| 0xE75D: 0x8EB1, |
| 0xE75E: 0x8EBE, |
| 0xE75F: 0x8EC5, |
| 0xE760: 0x8EC8, |
| 0xE761: 0x8ECB, |
| 0xE762: 0x8EDB, |
| 0xE763: 0x8EE3, |
| 0xE764: 0x8EFC, |
| 0xE765: 0x8EFB, |
| 0xE766: 0x8EEB, |
| 0xE767: 0x8EFE, |
| 0xE768: 0x8F0A, |
| 0xE769: 0x8F05, |
| 0xE76A: 0x8F15, |
| 0xE76B: 0x8F12, |
| 0xE76C: 0x8F19, |
| 0xE76D: 0x8F13, |
| 0xE76E: 0x8F1C, |
| 0xE76F: 0x8F1F, |
| 0xE770: 0x8F1B, |
| 0xE771: 0x8F0C, |
| 0xE772: 0x8F26, |
| 0xE773: 0x8F33, |
| 0xE774: 0x8F3B, |
| 0xE775: 0x8F39, |
| 0xE776: 0x8F45, |
| 0xE777: 0x8F42, |
| 0xE778: 0x8F3E, |
| 0xE779: 0x8F4C, |
| 0xE77A: 0x8F49, |
| 0xE77B: 0x8F46, |
| 0xE77C: 0x8F4E, |
| 0xE77D: 0x8F57, |
| 0xE77E: 0x8F5C, |
| 0xE780: 0x8F62, |
| 0xE781: 0x8F63, |
| 0xE782: 0x8F64, |
| 0xE783: 0x8F9C, |
| 0xE784: 0x8F9F, |
| 0xE785: 0x8FA3, |
| 0xE786: 0x8FAD, |
| 0xE787: 0x8FAF, |
| 0xE788: 0x8FB7, |
| 0xE789: 0x8FDA, |
| 0xE78A: 0x8FE5, |
| 0xE78B: 0x8FE2, |
| 0xE78C: 0x8FEA, |
| 0xE78D: 0x8FEF, |
| 0xE78E: 0x9087, |
| 0xE78F: 0x8FF4, |
| 0xE790: 0x9005, |
| 0xE791: 0x8FF9, |
| 0xE792: 0x8FFA, |
| 0xE793: 0x9011, |
| 0xE794: 0x9015, |
| 0xE795: 0x9021, |
| 0xE796: 0x900D, |
| 0xE797: 0x901E, |
| 0xE798: 0x9016, |
| 0xE799: 0x900B, |
| 0xE79A: 0x9027, |
| 0xE79B: 0x9036, |
| 0xE79C: 0x9035, |
| 0xE79D: 0x9039, |
| 0xE79E: 0x8FF8, |
| 0xE79F: 0x904F, |
| 0xE7A0: 0x9050, |
| 0xE7A1: 0x9051, |
| 0xE7A2: 0x9052, |
| 0xE7A3: 0x900E, |
| 0xE7A4: 0x9049, |
| 0xE7A5: 0x903E, |
| 0xE7A6: 0x9056, |
| 0xE7A7: 0x9058, |
| 0xE7A8: 0x905E, |
| 0xE7A9: 0x9068, |
| 0xE7AA: 0x906F, |
| 0xE7AB: 0x9076, |
| 0xE7AC: 0x96A8, |
| 0xE7AD: 0x9072, |
| 0xE7AE: 0x9082, |
| 0xE7AF: 0x907D, |
| 0xE7B0: 0x9081, |
| 0xE7B1: 0x9080, |
| 0xE7B2: 0x908A, |
| 0xE7B3: 0x9089, |
| 0xE7B4: 0x908F, |
| 0xE7B5: 0x90A8, |
| 0xE7B6: 0x90AF, |
| 0xE7B7: 0x90B1, |
| 0xE7B8: 0x90B5, |
| 0xE7B9: 0x90E2, |
| 0xE7BA: 0x90E4, |
| 0xE7BB: 0x6248, |
| 0xE7BC: 0x90DB, |
| 0xE7BD: 0x9102, |
| 0xE7BE: 0x9112, |
| 0xE7BF: 0x9119, |
| 0xE7C0: 0x9132, |
| 0xE7C1: 0x9130, |
| 0xE7C2: 0x914A, |
| 0xE7C3: 0x9156, |
| 0xE7C4: 0x9158, |
| 0xE7C5: 0x9163, |
| 0xE7C6: 0x9165, |
| 0xE7C7: 0x9169, |
| 0xE7C8: 0x9173, |
| 0xE7C9: 0x9172, |
| 0xE7CA: 0x918B, |
| 0xE7CB: 0x9189, |
| 0xE7CC: 0x9182, |
| 0xE7CD: 0x91A2, |
| 0xE7CE: 0x91AB, |
| 0xE7CF: 0x91AF, |
| 0xE7D0: 0x91AA, |
| 0xE7D1: 0x91B5, |
| 0xE7D2: 0x91B4, |
| 0xE7D3: 0x91BA, |
| 0xE7D4: 0x91C0, |
| 0xE7D5: 0x91C1, |
| 0xE7D6: 0x91C9, |
| 0xE7D7: 0x91CB, |
| 0xE7D8: 0x91D0, |
| 0xE7D9: 0x91D6, |
| 0xE7DA: 0x91DF, |
| 0xE7DB: 0x91E1, |
| 0xE7DC: 0x91DB, |
| 0xE7DD: 0x91FC, |
| 0xE7DE: 0x91F5, |
| 0xE7DF: 0x91F6, |
| 0xE7E0: 0x921E, |
| 0xE7E1: 0x91FF, |
| 0xE7E2: 0x9214, |
| 0xE7E3: 0x922C, |
| 0xE7E4: 0x9215, |
| 0xE7E5: 0x9211, |
| 0xE7E6: 0x925E, |
| 0xE7E7: 0x9257, |
| 0xE7E8: 0x9245, |
| 0xE7E9: 0x9249, |
| 0xE7EA: 0x9264, |
| 0xE7EB: 0x9248, |
| 0xE7EC: 0x9295, |
| 0xE7ED: 0x923F, |
| 0xE7EE: 0x924B, |
| 0xE7EF: 0x9250, |
| 0xE7F0: 0x929C, |
| 0xE7F1: 0x9296, |
| 0xE7F2: 0x9293, |
| 0xE7F3: 0x929B, |
| 0xE7F4: 0x925A, |
| 0xE7F5: 0x92CF, |
| 0xE7F6: 0x92B9, |
| 0xE7F7: 0x92B7, |
| 0xE7F8: 0x92E9, |
| 0xE7F9: 0x930F, |
| 0xE7FA: 0x92FA, |
| 0xE7FB: 0x9344, |
| 0xE7FC: 0x932E, |
| 0xE840: 0x9319, |
| 0xE841: 0x9322, |
| 0xE842: 0x931A, |
| 0xE843: 0x9323, |
| 0xE844: 0x933A, |
| 0xE845: 0x9335, |
| 0xE846: 0x933B, |
| 0xE847: 0x935C, |
| 0xE848: 0x9360, |
| 0xE849: 0x937C, |
| 0xE84A: 0x936E, |
| 0xE84B: 0x9356, |
| 0xE84C: 0x93B0, |
| 0xE84D: 0x93AC, |
| 0xE84E: 0x93AD, |
| 0xE84F: 0x9394, |
| 0xE850: 0x93B9, |
| 0xE851: 0x93D6, |
| 0xE852: 0x93D7, |
| 0xE853: 0x93E8, |
| 0xE854: 0x93E5, |
| 0xE855: 0x93D8, |
| 0xE856: 0x93C3, |
| 0xE857: 0x93DD, |
| 0xE858: 0x93D0, |
| 0xE859: 0x93C8, |
| 0xE85A: 0x93E4, |
| 0xE85B: 0x941A, |
| 0xE85C: 0x9414, |
| 0xE85D: 0x9413, |
| 0xE85E: 0x9403, |
| 0xE85F: 0x9407, |
| 0xE860: 0x9410, |
| 0xE861: 0x9436, |
| 0xE862: 0x942B, |
| 0xE863: 0x9435, |
| 0xE864: 0x9421, |
| 0xE865: 0x943A, |
| 0xE866: 0x9441, |
| 0xE867: 0x9452, |
| 0xE868: 0x9444, |
| 0xE869: 0x945B, |
| 0xE86A: 0x9460, |
| 0xE86B: 0x9462, |
| 0xE86C: 0x945E, |
| 0xE86D: 0x946A, |
| 0xE86E: 0x9229, |
| 0xE86F: 0x9470, |
| 0xE870: 0x9475, |
| 0xE871: 0x9477, |
| 0xE872: 0x947D, |
| 0xE873: 0x945A, |
| 0xE874: 0x947C, |
| 0xE875: 0x947E, |
| 0xE876: 0x9481, |
| 0xE877: 0x947F, |
| 0xE878: 0x9582, |
| 0xE879: 0x9587, |
| 0xE87A: 0x958A, |
| 0xE87B: 0x9594, |
| 0xE87C: 0x9596, |
| 0xE87D: 0x9598, |
| 0xE87E: 0x9599, |
| 0xE880: 0x95A0, |
| 0xE881: 0x95A8, |
| 0xE882: 0x95A7, |
| 0xE883: 0x95AD, |
| 0xE884: 0x95BC, |
| 0xE885: 0x95BB, |
| 0xE886: 0x95B9, |
| 0xE887: 0x95BE, |
| 0xE888: 0x95CA, |
| 0xE889: 0x6FF6, |
| 0xE88A: 0x95C3, |
| 0xE88B: 0x95CD, |
| 0xE88C: 0x95CC, |
| 0xE88D: 0x95D5, |
| 0xE88E: 0x95D4, |
| 0xE88F: 0x95D6, |
| 0xE890: 0x95DC, |
| 0xE891: 0x95E1, |
| 0xE892: 0x95E5, |
| 0xE893: 0x95E2, |
| 0xE894: 0x9621, |
| 0xE895: 0x9628, |
| 0xE896: 0x962E, |
| 0xE897: 0x962F, |
| 0xE898: 0x9642, |
| 0xE899: 0x964C, |
| 0xE89A: 0x964F, |
| 0xE89B: 0x964B, |
| 0xE89C: 0x9677, |
| 0xE89D: 0x965C, |
| 0xE89E: 0x965E, |
| 0xE89F: 0x965D, |
| 0xE8A0: 0x965F, |
| 0xE8A1: 0x9666, |
| 0xE8A2: 0x9672, |
| 0xE8A3: 0x966C, |
| 0xE8A4: 0x968D, |
| 0xE8A5: 0x9698, |
| 0xE8A6: 0x9695, |
| 0xE8A7: 0x9697, |
| 0xE8A8: 0x96AA, |
| 0xE8A9: 0x96A7, |
| 0xE8AA: 0x96B1, |
| 0xE8AB: 0x96B2, |
| 0xE8AC: 0x96B0, |
| 0xE8AD: 0x96B4, |
| 0xE8AE: 0x96B6, |
| 0xE8AF: 0x96B8, |
| 0xE8B0: 0x96B9, |
| 0xE8B1: 0x96CE, |
| 0xE8B2: 0x96CB, |
| 0xE8B3: 0x96C9, |
| 0xE8B4: 0x96CD, |
| 0xE8B5: 0x894D, |
| 0xE8B6: 0x96DC, |
| 0xE8B7: 0x970D, |
| 0xE8B8: 0x96D5, |
| 0xE8B9: 0x96F9, |
| 0xE8BA: 0x9704, |
| 0xE8BB: 0x9706, |
| 0xE8BC: 0x9708, |
| 0xE8BD: 0x9713, |
| 0xE8BE: 0x970E, |
| 0xE8BF: 0x9711, |
| 0xE8C0: 0x970F, |
| 0xE8C1: 0x9716, |
| 0xE8C2: 0x9719, |
| 0xE8C3: 0x9724, |
| 0xE8C4: 0x972A, |
| 0xE8C5: 0x9730, |
| 0xE8C6: 0x9739, |
| 0xE8C7: 0x973D, |
| 0xE8C8: 0x973E, |
| 0xE8C9: 0x9744, |
| 0xE8CA: 0x9746, |
| 0xE8CB: 0x9748, |
| 0xE8CC: 0x9742, |
| 0xE8CD: 0x9749, |
| 0xE8CE: 0x975C, |
| 0xE8CF: 0x9760, |
| 0xE8D0: 0x9764, |
| 0xE8D1: 0x9766, |
| 0xE8D2: 0x9768, |
| 0xE8D3: 0x52D2, |
| 0xE8D4: 0x976B, |
| 0xE8D5: 0x9771, |
| 0xE8D6: 0x9779, |
| 0xE8D7: 0x9785, |
| 0xE8D8: 0x977C, |
| 0xE8D9: 0x9781, |
| 0xE8DA: 0x977A, |
| 0xE8DB: 0x9786, |
| 0xE8DC: 0x978B, |
| 0xE8DD: 0x978F, |
| 0xE8DE: 0x9790, |
| 0xE8DF: 0x979C, |
| 0xE8E0: 0x97A8, |
| 0xE8E1: 0x97A6, |
| 0xE8E2: 0x97A3, |
| 0xE8E3: 0x97B3, |
| 0xE8E4: 0x97B4, |
| 0xE8E5: 0x97C3, |
| 0xE8E6: 0x97C6, |
| 0xE8E7: 0x97C8, |
| 0xE8E8: 0x97CB, |
| 0xE8E9: 0x97DC, |
| 0xE8EA: 0x97ED, |
| 0xE8EB: 0x9F4F, |
| 0xE8EC: 0x97F2, |
| 0xE8ED: 0x7ADF, |
| 0xE8EE: 0x97F6, |
| 0xE8EF: 0x97F5, |
| 0xE8F0: 0x980F, |
| 0xE8F1: 0x980C, |
| 0xE8F2: 0x9838, |
| 0xE8F3: 0x9824, |
| 0xE8F4: 0x9821, |
| 0xE8F5: 0x9837, |
| 0xE8F6: 0x983D, |
| 0xE8F7: 0x9846, |
| 0xE8F8: 0x984F, |
| 0xE8F9: 0x984B, |
| 0xE8FA: 0x986B, |
| 0xE8FB: 0x986F, |
| 0xE8FC: 0x9870, |
| 0xE940: 0x9871, |
| 0xE941: 0x9874, |
| 0xE942: 0x9873, |
| 0xE943: 0x98AA, |
| 0xE944: 0x98AF, |
| 0xE945: 0x98B1, |
| 0xE946: 0x98B6, |
| 0xE947: 0x98C4, |
| 0xE948: 0x98C3, |
| 0xE949: 0x98C6, |
| 0xE94A: 0x98E9, |
| 0xE94B: 0x98EB, |
| 0xE94C: 0x9903, |
| 0xE94D: 0x9909, |
| 0xE94E: 0x9912, |
| 0xE94F: 0x9914, |
| 0xE950: 0x9918, |
| 0xE951: 0x9921, |
| 0xE952: 0x991D, |
| 0xE953: 0x991E, |
| 0xE954: 0x9924, |
| 0xE955: 0x9920, |
| 0xE956: 0x992C, |
| 0xE957: 0x992E, |
| 0xE958: 0x993D, |
| 0xE959: 0x993E, |
| 0xE95A: 0x9942, |
| 0xE95B: 0x9949, |
| 0xE95C: 0x9945, |
| 0xE95D: 0x9950, |
| 0xE95E: 0x994B, |
| 0xE95F: 0x9951, |
| 0xE960: 0x9952, |
| 0xE961: 0x994C, |
| 0xE962: 0x9955, |
| 0xE963: 0x9997, |
| 0xE964: 0x9998, |
| 0xE965: 0x99A5, |
| 0xE966: 0x99AD, |
| 0xE967: 0x99AE, |
| 0xE968: 0x99BC, |
| 0xE969: 0x99DF, |
| 0xE96A: 0x99DB, |
| 0xE96B: 0x99DD, |
| 0xE96C: 0x99D8, |
| 0xE96D: 0x99D1, |
| 0xE96E: 0x99ED, |
| 0xE96F: 0x99EE, |
| 0xE970: 0x99F1, |
| 0xE971: 0x99F2, |
| 0xE972: 0x99FB, |
| 0xE973: 0x99F8, |
| 0xE974: 0x9A01, |
| 0xE975: 0x9A0F, |
| 0xE976: 0x9A05, |
| 0xE977: 0x99E2, |
| 0xE978: 0x9A19, |
| 0xE979: 0x9A2B, |
| 0xE97A: 0x9A37, |
| 0xE97B: 0x9A45, |
| 0xE97C: 0x9A42, |
| 0xE97D: 0x9A40, |
| 0xE97E: 0x9A43, |
| 0xE980: 0x9A3E, |
| 0xE981: 0x9A55, |
| 0xE982: 0x9A4D, |
| 0xE983: 0x9A5B, |
| 0xE984: 0x9A57, |
| 0xE985: 0x9A5F, |
| 0xE986: 0x9A62, |
| 0xE987: 0x9A65, |
| 0xE988: 0x9A64, |
| 0xE989: 0x9A69, |
| 0xE98A: 0x9A6B, |
| 0xE98B: 0x9A6A, |
| 0xE98C: 0x9AAD, |
| 0xE98D: 0x9AB0, |
| 0xE98E: 0x9ABC, |
| 0xE98F: 0x9AC0, |
| 0xE990: 0x9ACF, |
| 0xE991: 0x9AD1, |
| 0xE992: 0x9AD3, |
| 0xE993: 0x9AD4, |
| 0xE994: 0x9ADE, |
| 0xE995: 0x9ADF, |
| 0xE996: 0x9AE2, |
| 0xE997: 0x9AE3, |
| 0xE998: 0x9AE6, |
| 0xE999: 0x9AEF, |
| 0xE99A: 0x9AEB, |
| 0xE99B: 0x9AEE, |
| 0xE99C: 0x9AF4, |
| 0xE99D: 0x9AF1, |
| 0xE99E: 0x9AF7, |
| 0xE99F: 0x9AFB, |
| 0xE9A0: 0x9B06, |
| 0xE9A1: 0x9B18, |
| 0xE9A2: 0x9B1A, |
| 0xE9A3: 0x9B1F, |
| 0xE9A4: 0x9B22, |
| 0xE9A5: 0x9B23, |
| 0xE9A6: 0x9B25, |
| 0xE9A7: 0x9B27, |
| 0xE9A8: 0x9B28, |
| 0xE9A9: 0x9B29, |
| 0xE9AA: 0x9B2A, |
| 0xE9AB: 0x9B2E, |
| 0xE9AC: 0x9B2F, |
| 0xE9AD: 0x9B32, |
| 0xE9AE: 0x9B44, |
| 0xE9AF: 0x9B43, |
| 0xE9B0: 0x9B4F, |
| 0xE9B1: 0x9B4D, |
| 0xE9B2: 0x9B4E, |
| 0xE9B3: 0x9B51, |
| 0xE9B4: 0x9B58, |
| 0xE9B5: 0x9B74, |
| 0xE9B6: 0x9B93, |
| 0xE9B7: 0x9B83, |
| 0xE9B8: 0x9B91, |
| 0xE9B9: 0x9B96, |
| 0xE9BA: 0x9B97, |
| 0xE9BB: 0x9B9F, |
| 0xE9BC: 0x9BA0, |
| 0xE9BD: 0x9BA8, |
| 0xE9BE: 0x9BB4, |
| 0xE9BF: 0x9BC0, |
| 0xE9C0: 0x9BCA, |
| 0xE9C1: 0x9BB9, |
| 0xE9C2: 0x9BC6, |
| 0xE9C3: 0x9BCF, |
| 0xE9C4: 0x9BD1, |
| 0xE9C5: 0x9BD2, |
| 0xE9C6: 0x9BE3, |
| 0xE9C7: 0x9BE2, |
| 0xE9C8: 0x9BE4, |
| 0xE9C9: 0x9BD4, |
| 0xE9CA: 0x9BE1, |
| 0xE9CB: 0x9C3A, |
| 0xE9CC: 0x9BF2, |
| 0xE9CD: 0x9BF1, |
| 0xE9CE: 0x9BF0, |
| 0xE9CF: 0x9C15, |
| 0xE9D0: 0x9C14, |
| 0xE9D1: 0x9C09, |
| 0xE9D2: 0x9C13, |
| 0xE9D3: 0x9C0C, |
| 0xE9D4: 0x9C06, |
| 0xE9D5: 0x9C08, |
| 0xE9D6: 0x9C12, |
| 0xE9D7: 0x9C0A, |
| 0xE9D8: 0x9C04, |
| 0xE9D9: 0x9C2E, |
| 0xE9DA: 0x9C1B, |
| 0xE9DB: 0x9C25, |
| 0xE9DC: 0x9C24, |
| 0xE9DD: 0x9C21, |
| 0xE9DE: 0x9C30, |
| 0xE9DF: 0x9C47, |
| 0xE9E0: 0x9C32, |
| 0xE9E1: 0x9C46, |
| 0xE9E2: 0x9C3E, |
| 0xE9E3: 0x9C5A, |
| 0xE9E4: 0x9C60, |
| 0xE9E5: 0x9C67, |
| 0xE9E6: 0x9C76, |
| 0xE9E7: 0x9C78, |
| 0xE9E8: 0x9CE7, |
| 0xE9E9: 0x9CEC, |
| 0xE9EA: 0x9CF0, |
| 0xE9EB: 0x9D09, |
| 0xE9EC: 0x9D08, |
| 0xE9ED: 0x9CEB, |
| 0xE9EE: 0x9D03, |
| 0xE9EF: 0x9D06, |
| 0xE9F0: 0x9D2A, |
| 0xE9F1: 0x9D26, |
| 0xE9F2: 0x9DAF, |
| 0xE9F3: 0x9D23, |
| 0xE9F4: 0x9D1F, |
| 0xE9F5: 0x9D44, |
| 0xE9F6: 0x9D15, |
| 0xE9F7: 0x9D12, |
| 0xE9F8: 0x9D41, |
| 0xE9F9: 0x9D3F, |
| 0xE9FA: 0x9D3E, |
| 0xE9FB: 0x9D46, |
| 0xE9FC: 0x9D48, |
| 0xEA40: 0x9D5D, |
| 0xEA41: 0x9D5E, |
| 0xEA42: 0x9D64, |
| 0xEA43: 0x9D51, |
| 0xEA44: 0x9D50, |
| 0xEA45: 0x9D59, |
| 0xEA46: 0x9D72, |
| 0xEA47: 0x9D89, |
| 0xEA48: 0x9D87, |
| 0xEA49: 0x9DAB, |
| 0xEA4A: 0x9D6F, |
| 0xEA4B: 0x9D7A, |
| 0xEA4C: 0x9D9A, |
| 0xEA4D: 0x9DA4, |
| 0xEA4E: 0x9DA9, |
| 0xEA4F: 0x9DB2, |
| 0xEA50: 0x9DC4, |
| 0xEA51: 0x9DC1, |
| 0xEA52: 0x9DBB, |
| 0xEA53: 0x9DB8, |
| 0xEA54: 0x9DBA, |
| 0xEA55: 0x9DC6, |
| 0xEA56: 0x9DCF, |
| 0xEA57: 0x9DC2, |
| 0xEA58: 0x9DD9, |
| 0xEA59: 0x9DD3, |
| 0xEA5A: 0x9DF8, |
| 0xEA5B: 0x9DE6, |
| 0xEA5C: 0x9DED, |
| 0xEA5D: 0x9DEF, |
| 0xEA5E: 0x9DFD, |
| 0xEA5F: 0x9E1A, |
| 0xEA60: 0x9E1B, |
| 0xEA61: 0x9E1E, |
| 0xEA62: 0x9E75, |
| 0xEA63: 0x9E79, |
| 0xEA64: 0x9E7D, |
| 0xEA65: 0x9E81, |
| 0xEA66: 0x9E88, |
| 0xEA67: 0x9E8B, |
| 0xEA68: 0x9E8C, |
| 0xEA69: 0x9E92, |
| 0xEA6A: 0x9E95, |
| 0xEA6B: 0x9E91, |
| 0xEA6C: 0x9E9D, |
| 0xEA6D: 0x9EA5, |
| 0xEA6E: 0x9EA9, |
| 0xEA6F: 0x9EB8, |
| 0xEA70: 0x9EAA, |
| 0xEA71: 0x9EAD, |
| 0xEA72: 0x9761, |
| 0xEA73: 0x9ECC, |
| 0xEA74: 0x9ECE, |
| 0xEA75: 0x9ECF, |
| 0xEA76: 0x9ED0, |
| 0xEA77: 0x9ED4, |
| 0xEA78: 0x9EDC, |
| 0xEA79: 0x9EDE, |
| 0xEA7A: 0x9EDD, |
| 0xEA7B: 0x9EE0, |
| 0xEA7C: 0x9EE5, |
| 0xEA7D: 0x9EE8, |
| 0xEA7E: 0x9EEF, |
| 0xEA80: 0x9EF4, |
| 0xEA81: 0x9EF6, |
| 0xEA82: 0x9EF7, |
| 0xEA83: 0x9EF9, |
| 0xEA84: 0x9EFB, |
| 0xEA85: 0x9EFC, |
| 0xEA86: 0x9EFD, |
| 0xEA87: 0x9F07, |
| 0xEA88: 0x9F08, |
| 0xEA89: 0x76B7, |
| 0xEA8A: 0x9F15, |
| 0xEA8B: 0x9F21, |
| 0xEA8C: 0x9F2C, |
| 0xEA8D: 0x9F3E, |
| 0xEA8E: 0x9F4A, |
| 0xEA8F: 0x9F52, |
| 0xEA90: 0x9F54, |
| 0xEA91: 0x9F63, |
| 0xEA92: 0x9F5F, |
| 0xEA93: 0x9F60, |
| 0xEA94: 0x9F61, |
| 0xEA95: 0x9F66, |
| 0xEA96: 0x9F67, |
| 0xEA97: 0x9F6C, |
| 0xEA98: 0x9F6A, |
| 0xEA99: 0x9F77, |
| 0xEA9A: 0x9F72, |
| 0xEA9B: 0x9F76, |
| 0xEA9C: 0x9F95, |
| 0xEA9D: 0x9F9C, |
| 0xEA9E: 0x9FA0, |
| 0xEA9F: 0x582F, |
| 0xEAA0: 0x69C7, |
| 0xEAA1: 0x9059, |
| 0xEAA2: 0x7464, |
| 0xEAA3: 0x51DC, |
| 0xEAA4: 0x7199, |
| }; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var GenericGF_1 = __webpack_require__(1); |
| var GenericGFPoly_1 = __webpack_require__(2); |
| function runEuclideanAlgorithm(field, a, b, R) { |
| var _a; |
| |
| if (a.degree() < b.degree()) { |
| _a = [b, a], a = _a[0], b = _a[1]; |
| } |
| var rLast = a; |
| var r = b; |
| var tLast = field.zero; |
| var t = field.one; |
| |
| while (r.degree() >= R / 2) { |
| var rLastLast = rLast; |
| var tLastLast = tLast; |
| rLast = r; |
| tLast = t; |
| |
| if (rLast.isZero()) { |
| |
| return null; |
| } |
| r = rLastLast; |
| var q = field.zero; |
| var denominatorLeadingTerm = rLast.getCoefficient(rLast.degree()); |
| var dltInverse = field.inverse(denominatorLeadingTerm); |
| while (r.degree() >= rLast.degree() && !r.isZero()) { |
| var degreeDiff = r.degree() - rLast.degree(); |
| var scale = field.multiply(r.getCoefficient(r.degree()), dltInverse); |
| q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale)); |
| r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale)); |
| } |
| t = q.multiplyPoly(tLast).addOrSubtract(tLastLast); |
| if (r.degree() >= rLast.degree()) { |
| return null; |
| } |
| } |
| var sigmaTildeAtZero = t.getCoefficient(0); |
| if (sigmaTildeAtZero === 0) { |
| return null; |
| } |
| var inverse = field.inverse(sigmaTildeAtZero); |
| return [t.multiply(inverse), r.multiply(inverse)]; |
| } |
| function findErrorLocations(field, errorLocator) { |
| |
| var numErrors = errorLocator.degree(); |
| if (numErrors === 1) { |
| return [errorLocator.getCoefficient(1)]; |
| } |
| var result = new Array(numErrors); |
| var errorCount = 0; |
| for (var i = 1; i < field.size && errorCount < numErrors; i++) { |
| if (errorLocator.evaluateAt(i) === 0) { |
| result[errorCount] = field.inverse(i); |
| errorCount++; |
| } |
| } |
| if (errorCount !== numErrors) { |
| return null; |
| } |
| return result; |
| } |
| function findErrorMagnitudes(field, errorEvaluator, errorLocations) { |
| |
| var s = errorLocations.length; |
| var result = new Array(s); |
| for (var i = 0; i < s; i++) { |
| var xiInverse = field.inverse(errorLocations[i]); |
| var denominator = 1; |
| for (var j = 0; j < s; j++) { |
| if (i !== j) { |
| denominator = field.multiply(denominator, GenericGF_1.addOrSubtractGF(1, field.multiply(errorLocations[j], xiInverse))); |
| } |
| } |
| result[i] = field.multiply(errorEvaluator.evaluateAt(xiInverse), field.inverse(denominator)); |
| if (field.generatorBase !== 0) { |
| result[i] = field.multiply(result[i], xiInverse); |
| } |
| } |
| return result; |
| } |
| function decode(bytes, twoS) { |
| var outputBytes = new Uint8ClampedArray(bytes.length); |
| outputBytes.set(bytes); |
| var field = new GenericGF_1.default(0x011D, 256, 0); |
| var poly = new GenericGFPoly_1.default(field, outputBytes); |
| var syndromeCoefficients = new Uint8ClampedArray(twoS); |
| var error = false; |
| for (var s = 0; s < twoS; s++) { |
| var evaluation = poly.evaluateAt(field.exp(s + field.generatorBase)); |
| syndromeCoefficients[syndromeCoefficients.length - 1 - s] = evaluation; |
| if (evaluation !== 0) { |
| error = true; |
| } |
| } |
| if (!error) { |
| return outputBytes; |
| } |
| var syndrome = new GenericGFPoly_1.default(field, syndromeCoefficients); |
| var sigmaOmega = runEuclideanAlgorithm(field, field.buildMonomial(twoS, 1), syndrome, twoS); |
| if (sigmaOmega === null) { |
| return null; |
| } |
| var errorLocations = findErrorLocations(field, sigmaOmega[0]); |
| if (errorLocations == null) { |
| return null; |
| } |
| var errorMagnitudes = findErrorMagnitudes(field, sigmaOmega[1], errorLocations); |
| for (var i = 0; i < errorLocations.length; i++) { |
| var position = outputBytes.length - 1 - field.log(errorLocations[i]); |
| if (position < 0) { |
| return null; |
| } |
| outputBytes[position] = GenericGF_1.addOrSubtractGF(outputBytes[position], errorMagnitudes[i]); |
| } |
| return outputBytes; |
| } |
| exports.decode = decode; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.VERSIONS = [ |
| { |
| infoBits: null, |
| versionNumber: 1, |
| alignmentPatternCenters: [], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 7, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 19 }], |
| }, |
| { |
| ecCodewordsPerBlock: 10, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }], |
| }, |
| { |
| ecCodewordsPerBlock: 13, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 13 }], |
| }, |
| { |
| ecCodewordsPerBlock: 17, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 9 }], |
| }, |
| ], |
| }, |
| { |
| infoBits: null, |
| versionNumber: 2, |
| alignmentPatternCenters: [6, 18], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 10, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 34 }], |
| }, |
| { |
| ecCodewordsPerBlock: 16, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 28 }], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 22 }], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 16 }], |
| }, |
| ], |
| }, |
| { |
| infoBits: null, |
| versionNumber: 3, |
| alignmentPatternCenters: [6, 22], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 15, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 55 }], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 44 }], |
| }, |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 17 }], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 13 }], |
| }, |
| ], |
| }, |
| { |
| infoBits: null, |
| versionNumber: 4, |
| alignmentPatternCenters: [6, 26], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 20, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 80 }], |
| }, |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 32 }], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 24 }], |
| }, |
| { |
| ecCodewordsPerBlock: 16, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 9 }], |
| }, |
| ], |
| }, |
| { |
| infoBits: null, |
| versionNumber: 5, |
| alignmentPatternCenters: [6, 30], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [{ numBlocks: 1, dataCodewordsPerBlock: 108 }], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 43 }], |
| }, |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 11 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 12 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: null, |
| versionNumber: 6, |
| alignmentPatternCenters: [6, 34], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 68 }], |
| }, |
| { |
| ecCodewordsPerBlock: 16, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 27 }], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 19 }], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 15 }], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x07C94, |
| versionNumber: 7, |
| alignmentPatternCenters: [6, 22, 38], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 20, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 78 }], |
| }, |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 31 }], |
| }, |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 14 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 15 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 13 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 14 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x085BC, |
| versionNumber: 8, |
| alignmentPatternCenters: [6, 24, 42], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 97 }], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 38 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 39 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 18 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 19 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 14 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 15 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x09A99, |
| versionNumber: 9, |
| alignmentPatternCenters: [6, 26, 46], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [{ numBlocks: 2, dataCodewordsPerBlock: 116 }], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 36 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 37 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 20, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 16 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 17 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 12 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 13 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x0A4D3, |
| versionNumber: 10, |
| alignmentPatternCenters: [6, 28, 50], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 18, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 68 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 69 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 43 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 44 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 19 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 20 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x0BBF6, |
| versionNumber: 11, |
| alignmentPatternCenters: [6, 30, 54], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 20, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 81 }], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 1, dataCodewordsPerBlock: 50 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 51 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 22 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 23 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 12 }, |
| { numBlocks: 8, dataCodewordsPerBlock: 13 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x0C762, |
| versionNumber: 12, |
| alignmentPatternCenters: [6, 32, 58], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 92 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 93 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 36 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 37 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 20 }, |
| { numBlocks: 6, dataCodewordsPerBlock: 21 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 7, dataCodewordsPerBlock: 14 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 15 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x0D847, |
| versionNumber: 13, |
| alignmentPatternCenters: [6, 34, 62], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [{ numBlocks: 4, dataCodewordsPerBlock: 107 }], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 8, dataCodewordsPerBlock: 37 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 38 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 8, dataCodewordsPerBlock: 20 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 21 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 12, dataCodewordsPerBlock: 11 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 12 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x0E60D, |
| versionNumber: 14, |
| alignmentPatternCenters: [6, 26, 46, 66], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 115 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 116 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 40 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 41 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 20, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 16 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 17 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 12 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 13 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x0F928, |
| versionNumber: 15, |
| alignmentPatternCenters: [6, 26, 48, 70], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 22, |
| ecBlocks: [ |
| { numBlocks: 5, dataCodewordsPerBlock: 87 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 88 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 5, dataCodewordsPerBlock: 41 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 42 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 5, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 12 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 13 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x10B78, |
| versionNumber: 16, |
| alignmentPatternCenters: [6, 26, 50, 74], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 5, dataCodewordsPerBlock: 98 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 99 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 7, dataCodewordsPerBlock: 45 }, |
| { numBlocks: 3, dataCodewordsPerBlock: 46 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [ |
| { numBlocks: 15, dataCodewordsPerBlock: 19 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 20 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 13, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1145D, |
| versionNumber: 17, |
| alignmentPatternCenters: [6, 30, 54, 78], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 1, dataCodewordsPerBlock: 107 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 108 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 10, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 1, dataCodewordsPerBlock: 22 }, |
| { numBlocks: 15, dataCodewordsPerBlock: 23 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 14 }, |
| { numBlocks: 17, dataCodewordsPerBlock: 15 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x12A17, |
| versionNumber: 18, |
| alignmentPatternCenters: [6, 30, 56, 82], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 5, dataCodewordsPerBlock: 120 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 121 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 9, dataCodewordsPerBlock: 43 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 44 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 17, dataCodewordsPerBlock: 22 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 23 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 14 }, |
| { numBlocks: 19, dataCodewordsPerBlock: 15 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x13532, |
| versionNumber: 19, |
| alignmentPatternCenters: [6, 30, 58, 86], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 113 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 114 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 44 }, |
| { numBlocks: 11, dataCodewordsPerBlock: 45 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 17, dataCodewordsPerBlock: 21 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 22 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 9, dataCodewordsPerBlock: 13 }, |
| { numBlocks: 16, dataCodewordsPerBlock: 14 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x149A6, |
| versionNumber: 20, |
| alignmentPatternCenters: [6, 34, 62, 90], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 107 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 108 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 41 }, |
| { numBlocks: 13, dataCodewordsPerBlock: 42 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 15, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 15, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 10, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x15683, |
| versionNumber: 21, |
| alignmentPatternCenters: [6, 28, 50, 72, 94], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 116 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 117 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 42 }], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 17, dataCodewordsPerBlock: 22 }, |
| { numBlocks: 6, dataCodewordsPerBlock: 23 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 19, dataCodewordsPerBlock: 16 }, |
| { numBlocks: 6, dataCodewordsPerBlock: 17 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x168C9, |
| versionNumber: 22, |
| alignmentPatternCenters: [6, 26, 50, 74, 98], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 111 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 112 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 46 }], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 7, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 16, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 24, |
| ecBlocks: [{ numBlocks: 34, dataCodewordsPerBlock: 13 }], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x177EC, |
| versionNumber: 23, |
| alignmentPatternCenters: [6, 30, 54, 74, 102], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 121 }, |
| { numBlocks: 5, dataCodewordsPerBlock: 122 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 16, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x18EC4, |
| versionNumber: 24, |
| alignmentPatternCenters: [6, 28, 54, 80, 106], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 117 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 118 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 45 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 46 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 16, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 30, dataCodewordsPerBlock: 16 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 17 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x191E1, |
| versionNumber: 25, |
| alignmentPatternCenters: [6, 32, 58, 84, 110], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 26, |
| ecBlocks: [ |
| { numBlocks: 8, dataCodewordsPerBlock: 106 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 107 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 8, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 13, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 7, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 22, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 22, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 13, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1AFAB, |
| versionNumber: 26, |
| alignmentPatternCenters: [6, 30, 58, 86, 114], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 10, dataCodewordsPerBlock: 114 }, |
| { numBlocks: 2, dataCodewordsPerBlock: 115 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 19, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 28, dataCodewordsPerBlock: 22 }, |
| { numBlocks: 6, dataCodewordsPerBlock: 23 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 33, dataCodewordsPerBlock: 16 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 17 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1B08E, |
| versionNumber: 27, |
| alignmentPatternCenters: [6, 34, 62, 90, 118], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 8, dataCodewordsPerBlock: 122 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 123 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 22, dataCodewordsPerBlock: 45 }, |
| { numBlocks: 3, dataCodewordsPerBlock: 46 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 8, dataCodewordsPerBlock: 23 }, |
| { numBlocks: 26, dataCodewordsPerBlock: 24 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 12, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 28, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1CC1A, |
| versionNumber: 28, |
| alignmentPatternCenters: [6, 26, 50, 74, 98, 122], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 117 }, |
| { numBlocks: 10, dataCodewordsPerBlock: 118 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 3, dataCodewordsPerBlock: 45 }, |
| { numBlocks: 23, dataCodewordsPerBlock: 46 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 31, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 31, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1D33F, |
| versionNumber: 29, |
| alignmentPatternCenters: [6, 30, 54, 78, 102, 126], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 7, dataCodewordsPerBlock: 116 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 117 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 21, dataCodewordsPerBlock: 45 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 46 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 1, dataCodewordsPerBlock: 23 }, |
| { numBlocks: 37, dataCodewordsPerBlock: 24 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 19, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 26, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1ED75, |
| versionNumber: 30, |
| alignmentPatternCenters: [6, 26, 52, 78, 104, 130], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 5, dataCodewordsPerBlock: 115 }, |
| { numBlocks: 10, dataCodewordsPerBlock: 116 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 19, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 10, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 15, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 25, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 23, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 25, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x1F250, |
| versionNumber: 31, |
| alignmentPatternCenters: [6, 30, 56, 82, 108, 134], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 13, dataCodewordsPerBlock: 115 }, |
| { numBlocks: 3, dataCodewordsPerBlock: 116 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 29, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 42, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 23, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 28, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x209D5, |
| versionNumber: 32, |
| alignmentPatternCenters: [6, 34, 60, 86, 112, 138], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [{ numBlocks: 17, dataCodewordsPerBlock: 115 }], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 10, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 23, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 10, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 35, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 19, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 35, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x216F0, |
| versionNumber: 33, |
| alignmentPatternCenters: [6, 30, 58, 86, 114, 142], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 17, dataCodewordsPerBlock: 115 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 116 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 14, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 21, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 29, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 19, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 11, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 46, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x228BA, |
| versionNumber: 34, |
| alignmentPatternCenters: [6, 34, 62, 90, 118, 146], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 13, dataCodewordsPerBlock: 115 }, |
| { numBlocks: 6, dataCodewordsPerBlock: 116 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 14, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 23, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 44, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 59, dataCodewordsPerBlock: 16 }, |
| { numBlocks: 1, dataCodewordsPerBlock: 17 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x2379F, |
| versionNumber: 35, |
| alignmentPatternCenters: [6, 30, 54, 78, 102, 126, 150], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 12, dataCodewordsPerBlock: 121 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 122 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 12, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 26, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 39, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 22, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 41, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x24B0B, |
| versionNumber: 36, |
| alignmentPatternCenters: [6, 24, 50, 76, 102, 128, 154], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 121 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 122 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 6, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 34, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 46, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 10, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 2, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 64, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x2542E, |
| versionNumber: 37, |
| alignmentPatternCenters: [6, 28, 54, 80, 106, 132, 158], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 17, dataCodewordsPerBlock: 122 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 123 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 29, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 49, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 10, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 24, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 46, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x26A64, |
| versionNumber: 38, |
| alignmentPatternCenters: [6, 32, 58, 84, 110, 136, 162], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 4, dataCodewordsPerBlock: 122 }, |
| { numBlocks: 18, dataCodewordsPerBlock: 123 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 13, dataCodewordsPerBlock: 46 }, |
| { numBlocks: 32, dataCodewordsPerBlock: 47 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 48, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 14, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 42, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 32, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x27541, |
| versionNumber: 39, |
| alignmentPatternCenters: [6, 26, 54, 82, 110, 138, 166], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 20, dataCodewordsPerBlock: 117 }, |
| { numBlocks: 4, dataCodewordsPerBlock: 118 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 40, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 7, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 43, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 22, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 10, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 67, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| { |
| infoBits: 0x28C69, |
| versionNumber: 40, |
| alignmentPatternCenters: [6, 30, 58, 86, 114, 142, 170], |
| errorCorrectionLevels: [ |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 19, dataCodewordsPerBlock: 118 }, |
| { numBlocks: 6, dataCodewordsPerBlock: 119 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 28, |
| ecBlocks: [ |
| { numBlocks: 18, dataCodewordsPerBlock: 47 }, |
| { numBlocks: 31, dataCodewordsPerBlock: 48 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 34, dataCodewordsPerBlock: 24 }, |
| { numBlocks: 34, dataCodewordsPerBlock: 25 }, |
| ], |
| }, |
| { |
| ecCodewordsPerBlock: 30, |
| ecBlocks: [ |
| { numBlocks: 20, dataCodewordsPerBlock: 15 }, |
| { numBlocks: 61, dataCodewordsPerBlock: 16 }, |
| ], |
| }, |
| ], |
| }, |
| ]; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var BitMatrix_1 = __webpack_require__(0); |
| function squareToQuadrilateral(p1, p2, p3, p4) { |
| var dx3 = p1.x - p2.x + p3.x - p4.x; |
| var dy3 = p1.y - p2.y + p3.y - p4.y; |
| if (dx3 === 0 && dy3 === 0) { |
| return { |
| a11: p2.x - p1.x, |
| a12: p2.y - p1.y, |
| a13: 0, |
| a21: p3.x - p2.x, |
| a22: p3.y - p2.y, |
| a23: 0, |
| a31: p1.x, |
| a32: p1.y, |
| a33: 1, |
| }; |
| } |
| else { |
| var dx1 = p2.x - p3.x; |
| var dx2 = p4.x - p3.x; |
| var dy1 = p2.y - p3.y; |
| var dy2 = p4.y - p3.y; |
| var denominator = dx1 * dy2 - dx2 * dy1; |
| var a13 = (dx3 * dy2 - dx2 * dy3) / denominator; |
| var a23 = (dx1 * dy3 - dx3 * dy1) / denominator; |
| return { |
| a11: p2.x - p1.x + a13 * p2.x, |
| a12: p2.y - p1.y + a13 * p2.y, |
| a13: a13, |
| a21: p4.x - p1.x + a23 * p4.x, |
| a22: p4.y - p1.y + a23 * p4.y, |
| a23: a23, |
| a31: p1.x, |
| a32: p1.y, |
| a33: 1, |
| }; |
| } |
| } |
| function quadrilateralToSquare(p1, p2, p3, p4) { |
| |
| var sToQ = squareToQuadrilateral(p1, p2, p3, p4); |
| return { |
| a11: sToQ.a22 * sToQ.a33 - sToQ.a23 * sToQ.a32, |
| a12: sToQ.a13 * sToQ.a32 - sToQ.a12 * sToQ.a33, |
| a13: sToQ.a12 * sToQ.a23 - sToQ.a13 * sToQ.a22, |
| a21: sToQ.a23 * sToQ.a31 - sToQ.a21 * sToQ.a33, |
| a22: sToQ.a11 * sToQ.a33 - sToQ.a13 * sToQ.a31, |
| a23: sToQ.a13 * sToQ.a21 - sToQ.a11 * sToQ.a23, |
| a31: sToQ.a21 * sToQ.a32 - sToQ.a22 * sToQ.a31, |
| a32: sToQ.a12 * sToQ.a31 - sToQ.a11 * sToQ.a32, |
| a33: sToQ.a11 * sToQ.a22 - sToQ.a12 * sToQ.a21, |
| }; |
| } |
| function times(a, b) { |
| return { |
| a11: a.a11 * b.a11 + a.a21 * b.a12 + a.a31 * b.a13, |
| a12: a.a12 * b.a11 + a.a22 * b.a12 + a.a32 * b.a13, |
| a13: a.a13 * b.a11 + a.a23 * b.a12 + a.a33 * b.a13, |
| a21: a.a11 * b.a21 + a.a21 * b.a22 + a.a31 * b.a23, |
| a22: a.a12 * b.a21 + a.a22 * b.a22 + a.a32 * b.a23, |
| a23: a.a13 * b.a21 + a.a23 * b.a22 + a.a33 * b.a23, |
| a31: a.a11 * b.a31 + a.a21 * b.a32 + a.a31 * b.a33, |
| a32: a.a12 * b.a31 + a.a22 * b.a32 + a.a32 * b.a33, |
| a33: a.a13 * b.a31 + a.a23 * b.a32 + a.a33 * b.a33, |
| }; |
| } |
| function extract(image, location) { |
| var qToS = quadrilateralToSquare({ x: 3.5, y: 3.5 }, { x: location.dimension - 3.5, y: 3.5 }, { x: location.dimension - 6.5, y: location.dimension - 6.5 }, { x: 3.5, y: location.dimension - 3.5 }); |
| var sToQ = squareToQuadrilateral(location.topLeft, location.topRight, location.alignmentPattern, location.bottomLeft); |
| var transform = times(sToQ, qToS); |
| var matrix = BitMatrix_1.BitMatrix.createEmpty(location.dimension, location.dimension); |
| var mappingFunction = function (x, y) { |
| var denominator = transform.a13 * x + transform.a23 * y + transform.a33; |
| return { |
| x: (transform.a11 * x + transform.a21 * y + transform.a31) / denominator, |
| y: (transform.a12 * x + transform.a22 * y + transform.a32) / denominator, |
| }; |
| }; |
| for (var y = 0; y < location.dimension; y++) { |
| for (var x = 0; x < location.dimension; x++) { |
| var xValue = x + 0.5; |
| var yValue = y + 0.5; |
| var sourcePixel = mappingFunction(xValue, yValue); |
| matrix.set(x, y, image.get(Math.floor(sourcePixel.x), Math.floor(sourcePixel.y))); |
| } |
| } |
| return { |
| matrix: matrix, |
| mappingFunction: mappingFunction, |
| }; |
| } |
| exports.extract = extract; |
| |
| |
| }), |
| |
| (function(module, exports, __webpack_require__) { |
| |
| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| var MAX_FINDERPATTERNS_TO_SEARCH = 4; |
| var MIN_QUAD_RATIO = 0.5; |
| var MAX_QUAD_RATIO = 1.5; |
| var distance = function (a, b) { return Math.sqrt(Math.pow((b.x - a.x), 2) + Math.pow((b.y - a.y), 2)); }; |
| function sum(values) { |
| return values.reduce(function (a, b) { return a + b; }); |
| } |
| |
| function reorderFinderPatterns(pattern1, pattern2, pattern3) { |
| var _a, _b, _c, _d; |
| |
| var oneTwoDistance = distance(pattern1, pattern2); |
| var twoThreeDistance = distance(pattern2, pattern3); |
| var oneThreeDistance = distance(pattern1, pattern3); |
| var bottomLeft; |
| var topLeft; |
| var topRight; |
| |
| if (twoThreeDistance >= oneTwoDistance && twoThreeDistance >= oneThreeDistance) { |
| _a = [pattern2, pattern1, pattern3], bottomLeft = _a[0], topLeft = _a[1], topRight = _a[2]; |
| } |
| else if (oneThreeDistance >= twoThreeDistance && oneThreeDistance >= oneTwoDistance) { |
| _b = [pattern1, pattern2, pattern3], bottomLeft = _b[0], topLeft = _b[1], topRight = _b[2]; |
| } |
| else { |
| _c = [pattern1, pattern3, pattern2], bottomLeft = _c[0], topLeft = _c[1], topRight = _c[2]; |
| } |
| |
| |
| |
| if (((topRight.x - topLeft.x) * (bottomLeft.y - topLeft.y)) - ((topRight.y - topLeft.y) * (bottomLeft.x - topLeft.x)) < 0) { |
| _d = [topRight, bottomLeft], bottomLeft = _d[0], topRight = _d[1]; |
| } |
| return { bottomLeft: bottomLeft, topLeft: topLeft, topRight: topRight }; |
| } |
| |
| function computeDimension(topLeft, topRight, bottomLeft, matrix) { |
| var moduleSize = (sum(countBlackWhiteRun(topLeft, bottomLeft, matrix, 5)) / 7 + |
| sum(countBlackWhiteRun(topLeft, topRight, matrix, 5)) / 7 + |
| sum(countBlackWhiteRun(bottomLeft, topLeft, matrix, 5)) / 7 + |
| sum(countBlackWhiteRun(topRight, topLeft, matrix, 5)) / 7) / 4; |
| if (moduleSize < 1) { |
| throw new Error("Invalid module size"); |
| } |
| var topDimension = Math.round(distance(topLeft, topRight) / moduleSize); |
| var sideDimension = Math.round(distance(topLeft, bottomLeft) / moduleSize); |
| var dimension = Math.floor((topDimension + sideDimension) / 2) + 7; |
| switch (dimension % 4) { |
| case 0: |
| dimension++; |
| break; |
| case 2: |
| dimension--; |
| break; |
| } |
| return { dimension: dimension, moduleSize: moduleSize }; |
| } |
| |
| |
| |
| function countBlackWhiteRunTowardsPoint(origin, end, matrix, length) { |
| var switchPoints = [{ x: Math.floor(origin.x), y: Math.floor(origin.y) }]; |
| var steep = Math.abs(end.y - origin.y) > Math.abs(end.x - origin.x); |
| var fromX; |
| var fromY; |
| var toX; |
| var toY; |
| if (steep) { |
| fromX = Math.floor(origin.y); |
| fromY = Math.floor(origin.x); |
| toX = Math.floor(end.y); |
| toY = Math.floor(end.x); |
| } |
| else { |
| fromX = Math.floor(origin.x); |
| fromY = Math.floor(origin.y); |
| toX = Math.floor(end.x); |
| toY = Math.floor(end.y); |
| } |
| var dx = Math.abs(toX - fromX); |
| var dy = Math.abs(toY - fromY); |
| var error = Math.floor(-dx / 2); |
| var xStep = fromX < toX ? 1 : -1; |
| var yStep = fromY < toY ? 1 : -1; |
| var currentPixel = true; |
| |
| for (var x = fromX, y = fromY; x !== toX + xStep; x += xStep) { |
| |
| |
| |
| var realX = steep ? y : x; |
| var realY = steep ? x : y; |
| if (matrix.get(realX, realY) !== currentPixel) { |
| currentPixel = !currentPixel; |
| switchPoints.push({ x: realX, y: realY }); |
| if (switchPoints.length === length + 1) { |
| break; |
| } |
| } |
| error += dy; |
| if (error > 0) { |
| if (y === toY) { |
| break; |
| } |
| y += yStep; |
| error -= dx; |
| } |
| } |
| var distances = []; |
| for (var i = 0; i < length; i++) { |
| if (switchPoints[i] && switchPoints[i + 1]) { |
| distances.push(distance(switchPoints[i], switchPoints[i + 1])); |
| } |
| else { |
| distances.push(0); |
| } |
| } |
| return distances; |
| } |
| |
| |
| |
| function countBlackWhiteRun(origin, end, matrix, length) { |
| var _a; |
| var rise = end.y - origin.y; |
| var run = end.x - origin.x; |
| var towardsEnd = countBlackWhiteRunTowardsPoint(origin, end, matrix, Math.ceil(length / 2)); |
| var awayFromEnd = countBlackWhiteRunTowardsPoint(origin, { x: origin.x - run, y: origin.y - rise }, matrix, Math.ceil(length / 2)); |
| var middleValue = towardsEnd.shift() + awayFromEnd.shift() - 1; |
| return (_a = awayFromEnd.concat(middleValue)).concat.apply(_a, towardsEnd); |
| } |
| |
| |
| function scoreBlackWhiteRun(sequence, ratios) { |
| var averageSize = sum(sequence) / sum(ratios); |
| var error = 0; |
| ratios.forEach(function (ratio, i) { |
| error += Math.pow((sequence[i] - ratio * averageSize), 2); |
| }); |
| return { averageSize: averageSize, error: error }; |
| } |
| |
| |
| |
| function scorePattern(point, ratios, matrix) { |
| try { |
| var horizontalRun = countBlackWhiteRun(point, { x: -1, y: point.y }, matrix, ratios.length); |
| var verticalRun = countBlackWhiteRun(point, { x: point.x, y: -1 }, matrix, ratios.length); |
| var topLeftPoint = { |
| x: Math.max(0, point.x - point.y) - 1, |
| y: Math.max(0, point.y - point.x) - 1, |
| }; |
| var topLeftBottomRightRun = countBlackWhiteRun(point, topLeftPoint, matrix, ratios.length); |
| var bottomLeftPoint = { |
| x: Math.min(matrix.width, point.x + point.y) + 1, |
| y: Math.min(matrix.height, point.y + point.x) + 1, |
| }; |
| var bottomLeftTopRightRun = countBlackWhiteRun(point, bottomLeftPoint, matrix, ratios.length); |
| var horzError = scoreBlackWhiteRun(horizontalRun, ratios); |
| var vertError = scoreBlackWhiteRun(verticalRun, ratios); |
| var diagDownError = scoreBlackWhiteRun(topLeftBottomRightRun, ratios); |
| var diagUpError = scoreBlackWhiteRun(bottomLeftTopRightRun, ratios); |
| var ratioError = Math.sqrt(horzError.error * horzError.error + |
| vertError.error * vertError.error + |
| diagDownError.error * diagDownError.error + |
| diagUpError.error * diagUpError.error); |
| var avgSize = (horzError.averageSize + vertError.averageSize + diagDownError.averageSize + diagUpError.averageSize) / 4; |
| var sizeError = (Math.pow((horzError.averageSize - avgSize), 2) + |
| Math.pow((vertError.averageSize - avgSize), 2) + |
| Math.pow((diagDownError.averageSize - avgSize), 2) + |
| Math.pow((diagUpError.averageSize - avgSize), 2)) / avgSize; |
| return ratioError + sizeError; |
| } |
| catch (_a) { |
| return Infinity; |
| } |
| } |
| function recenterLocation(matrix, p) { |
| var leftX = Math.round(p.x); |
| while (matrix.get(leftX, Math.round(p.y))) { |
| leftX--; |
| } |
| var rightX = Math.round(p.x); |
| while (matrix.get(rightX, Math.round(p.y))) { |
| rightX++; |
| } |
| var x = (leftX + rightX) / 2; |
| var topY = Math.round(p.y); |
| while (matrix.get(Math.round(x), topY)) { |
| topY--; |
| } |
| var bottomY = Math.round(p.y); |
| while (matrix.get(Math.round(x), bottomY)) { |
| bottomY++; |
| } |
| var y = (topY + bottomY) / 2; |
| return { x: x, y: y }; |
| } |
| function locate(matrix) { |
| var finderPatternQuads = []; |
| var activeFinderPatternQuads = []; |
| var alignmentPatternQuads = []; |
| var activeAlignmentPatternQuads = []; |
| var _loop_1 = function (y) { |
| var length_1 = 0; |
| var lastBit = false; |
| var scans = [0, 0, 0, 0, 0]; |
| var _loop_2 = function (x) { |
| var v = matrix.get(x, y); |
| if (v === lastBit) { |
| length_1++; |
| } |
| else { |
| scans = [scans[1], scans[2], scans[3], scans[4], length_1]; |
| length_1 = 1; |
| lastBit = v; |
| |
| var averageFinderPatternBlocksize = sum(scans) / 7; |
| var validFinderPattern = Math.abs(scans[0] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && |
| Math.abs(scans[1] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && |
| Math.abs(scans[2] - 3 * averageFinderPatternBlocksize) < 3 * averageFinderPatternBlocksize && |
| Math.abs(scans[3] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && |
| Math.abs(scans[4] - averageFinderPatternBlocksize) < averageFinderPatternBlocksize && |
| !v; |
| |
| var averageAlignmentPatternBlocksize = sum(scans.slice(-3)) / 3; |
| var validAlignmentPattern = Math.abs(scans[2] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize && |
| Math.abs(scans[3] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize && |
| Math.abs(scans[4] - averageAlignmentPatternBlocksize) < averageAlignmentPatternBlocksize && |
| v; |
| if (validFinderPattern) { |
| |
| var endX_1 = x - scans[3] - scans[4]; |
| var startX_1 = endX_1 - scans[2]; |
| var line = { startX: startX_1, endX: endX_1, y: y }; |
| |
| |
| var matchingQuads = activeFinderPatternQuads.filter(function (q) { |
| return (startX_1 >= q.bottom.startX && startX_1 <= q.bottom.endX) || |
| (endX_1 >= q.bottom.startX && startX_1 <= q.bottom.endX) || |
| (startX_1 <= q.bottom.startX && endX_1 >= q.bottom.endX && ((scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO && |
| (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO)); |
| }); |
| if (matchingQuads.length > 0) { |
| matchingQuads[0].bottom = line; |
| } |
| else { |
| activeFinderPatternQuads.push({ top: line, bottom: line }); |
| } |
| } |
| if (validAlignmentPattern) { |
| |
| var endX_2 = x - scans[4]; |
| var startX_2 = endX_2 - scans[3]; |
| var line = { startX: startX_2, y: y, endX: endX_2 }; |
| |
| |
| var matchingQuads = activeAlignmentPatternQuads.filter(function (q) { |
| return (startX_2 >= q.bottom.startX && startX_2 <= q.bottom.endX) || |
| (endX_2 >= q.bottom.startX && startX_2 <= q.bottom.endX) || |
| (startX_2 <= q.bottom.startX && endX_2 >= q.bottom.endX && ((scans[2] / (q.bottom.endX - q.bottom.startX)) < MAX_QUAD_RATIO && |
| (scans[2] / (q.bottom.endX - q.bottom.startX)) > MIN_QUAD_RATIO)); |
| }); |
| if (matchingQuads.length > 0) { |
| matchingQuads[0].bottom = line; |
| } |
| else { |
| activeAlignmentPatternQuads.push({ top: line, bottom: line }); |
| } |
| } |
| } |
| }; |
| for (var x = -1; x <= matrix.width; x++) { |
| _loop_2(x); |
| } |
| finderPatternQuads.push.apply(finderPatternQuads, activeFinderPatternQuads.filter(function (q) { return q.bottom.y !== y && q.bottom.y - q.top.y >= 2; })); |
| activeFinderPatternQuads = activeFinderPatternQuads.filter(function (q) { return q.bottom.y === y; }); |
| alignmentPatternQuads.push.apply(alignmentPatternQuads, activeAlignmentPatternQuads.filter(function (q) { return q.bottom.y !== y; })); |
| activeAlignmentPatternQuads = activeAlignmentPatternQuads.filter(function (q) { return q.bottom.y === y; }); |
| }; |
| for (var y = 0; y <= matrix.height; y++) { |
| _loop_1(y); |
| } |
| finderPatternQuads.push.apply(finderPatternQuads, activeFinderPatternQuads.filter(function (q) { return q.bottom.y - q.top.y >= 2; })); |
| alignmentPatternQuads.push.apply(alignmentPatternQuads, activeAlignmentPatternQuads); |
| var finderPatternGroups = finderPatternQuads |
| .filter(function (q) { return q.bottom.y - q.top.y >= 2; }) |
| .map(function (q) { |
| var x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4; |
| var y = (q.top.y + q.bottom.y + 1) / 2; |
| if (!matrix.get(Math.round(x), Math.round(y))) { |
| return; |
| } |
| var lengths = [q.top.endX - q.top.startX, q.bottom.endX - q.bottom.startX, q.bottom.y - q.top.y + 1]; |
| var size = sum(lengths) / lengths.length; |
| var score = scorePattern({ x: Math.round(x), y: Math.round(y) }, [1, 1, 3, 1, 1], matrix); |
| return { score: score, x: x, y: y, size: size }; |
| }) |
| .filter(function (q) { return !!q; }) |
| .sort(function (a, b) { return a.score - b.score; }) |
| |
| .map(function (point, i, finderPatterns) { |
| if (i > MAX_FINDERPATTERNS_TO_SEARCH) { |
| return null; |
| } |
| var otherPoints = finderPatterns |
| .filter(function (p, ii) { return i !== ii; }) |
| .map(function (p) { return ({ x: p.x, y: p.y, score: p.score + (Math.pow((p.size - point.size), 2)) / point.size, size: p.size }); }) |
| .sort(function (a, b) { return a.score - b.score; }); |
| if (otherPoints.length < 2) { |
| return null; |
| } |
| var score = point.score + otherPoints[0].score + otherPoints[1].score; |
| return { points: [point].concat(otherPoints.slice(0, 2)), score: score }; |
| }) |
| .filter(function (q) { return !!q; }) |
| .sort(function (a, b) { return a.score - b.score; }); |
| if (finderPatternGroups.length === 0) { |
| return null; |
| } |
| var _a = reorderFinderPatterns(finderPatternGroups[0].points[0], finderPatternGroups[0].points[1], finderPatternGroups[0].points[2]), topRight = _a.topRight, topLeft = _a.topLeft, bottomLeft = _a.bottomLeft; |
| var alignment = findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft); |
| var result = []; |
| if (alignment) { |
| result.push({ |
| alignmentPattern: { x: alignment.alignmentPattern.x, y: alignment.alignmentPattern.y }, |
| bottomLeft: { x: bottomLeft.x, y: bottomLeft.y }, |
| dimension: alignment.dimension, |
| topLeft: { x: topLeft.x, y: topLeft.y }, |
| topRight: { x: topRight.x, y: topRight.y }, |
| }); |
| } |
| |
| |
| |
| |
| |
| var midTopRight = recenterLocation(matrix, topRight); |
| var midTopLeft = recenterLocation(matrix, topLeft); |
| var midBottomLeft = recenterLocation(matrix, bottomLeft); |
| var centeredAlignment = findAlignmentPattern(matrix, alignmentPatternQuads, midTopRight, midTopLeft, midBottomLeft); |
| if (centeredAlignment) { |
| result.push({ |
| alignmentPattern: { x: centeredAlignment.alignmentPattern.x, y: centeredAlignment.alignmentPattern.y }, |
| bottomLeft: { x: midBottomLeft.x, y: midBottomLeft.y }, |
| topLeft: { x: midTopLeft.x, y: midTopLeft.y }, |
| topRight: { x: midTopRight.x, y: midTopRight.y }, |
| dimension: centeredAlignment.dimension, |
| }); |
| } |
| if (result.length === 0) { |
| return null; |
| } |
| return result; |
| } |
| exports.locate = locate; |
| function findAlignmentPattern(matrix, alignmentPatternQuads, topRight, topLeft, bottomLeft) { |
| var _a; |
| |
| |
| var dimension; |
| var moduleSize; |
| try { |
| (_a = computeDimension(topLeft, topRight, bottomLeft, matrix), dimension = _a.dimension, moduleSize = _a.moduleSize); |
| } |
| catch (e) { |
| return null; |
| } |
| |
| var bottomRightFinderPattern = { |
| x: topRight.x - topLeft.x + bottomLeft.x, |
| y: topRight.y - topLeft.y + bottomLeft.y, |
| }; |
| var modulesBetweenFinderPatterns = ((distance(topLeft, bottomLeft) + distance(topLeft, topRight)) / 2 / moduleSize); |
| var correctionToTopLeft = 1 - (3 / modulesBetweenFinderPatterns); |
| var expectedAlignmentPattern = { |
| x: topLeft.x + correctionToTopLeft * (bottomRightFinderPattern.x - topLeft.x), |
| y: topLeft.y + correctionToTopLeft * (bottomRightFinderPattern.y - topLeft.y), |
| }; |
| var alignmentPatterns = alignmentPatternQuads |
| .map(function (q) { |
| var x = (q.top.startX + q.top.endX + q.bottom.startX + q.bottom.endX) / 4; |
| var y = (q.top.y + q.bottom.y + 1) / 2; |
| if (!matrix.get(Math.floor(x), Math.floor(y))) { |
| return; |
| } |
| var lengths = [q.top.endX - q.top.startX, q.bottom.endX - q.bottom.startX, (q.bottom.y - q.top.y + 1)]; |
| var size = sum(lengths) / lengths.length; |
| var sizeScore = scorePattern({ x: Math.floor(x), y: Math.floor(y) }, [1, 1, 1], matrix); |
| var score = sizeScore + distance({ x: x, y: y }, expectedAlignmentPattern); |
| return { x: x, y: y, score: score }; |
| }) |
| .filter(function (v) { return !!v; }) |
| .sort(function (a, b) { return a.score - b.score; }); |
| |
| |
| var alignmentPattern = modulesBetweenFinderPatterns >= 15 && alignmentPatterns.length ? alignmentPatterns[0] : expectedAlignmentPattern; |
| return { alignmentPattern: alignmentPattern, dimension: dimension }; |
| } |
| |
| |
| }) |
| ])["default"]; |
| }); |
| </script> |
| <script> |
| const CHUNK_SIZE = 256 * 1024; |
| const WHOLE_FILE_READ_LIMIT = 500 * 1024 * 1024; |
| const PARALLEL_CHANNELS = 3; |
| const CHUNK_ID_BYTES = 36; |
| const CHUNK_HEADER_BYTES = CHUNK_ID_BYTES + 8; |
| |
| function packChunk(id, offset, arrayBuffer) { |
| const combined = new Uint8Array(CHUNK_HEADER_BYTES + arrayBuffer.byteLength); |
| combined.set(new TextEncoder().encode(id), 0); |
| new DataView(combined.buffer).setFloat64(CHUNK_ID_BYTES, offset, true); |
| combined.set(new Uint8Array(arrayBuffer), CHUNK_HEADER_BYTES); |
| return combined.buffer; |
| } |
| |
| function unpackChunk(buffer) { |
| const id = new TextDecoder().decode(buffer.slice(0, CHUNK_ID_BYTES)); |
| const offset = new DataView(buffer).getFloat64(CHUNK_ID_BYTES, true); |
| return { id, offset, data: buffer.slice(CHUNK_HEADER_BYTES) }; |
| } |
| const ICE_SERVERS = [ |
| { urls: 'stun:stun.l.google.com:19302' }, |
| { urls: 'stun:stun1.l.google.com:19302' }, |
| { urls: 'stun:stun.cloudflare.com:3478' }, |
| { urls: 'stun:stun.nextcloud.com:443' }, |
| { urls: 'stun:stun.sipgate.net:3478' }, |
| { urls: 'stun:stun.ekiga.net:3478' } |
| ]; |
| const DEFAULT_SIGNAL_URL = 'wss://test.mosquitto.org:8081/mqtt'; |
| const SIGNAL_RELAYS = [ |
| 'wss://test.mosquitto.org:8081/mqtt', |
| 'wss://broker.emqx.io:8084/mqtt', |
| 'wss://broker.hivemq.com:8884/mqtt', |
| 'wss://public.mqtthq.com:8084/mqtt' |
| ]; |
| const SIGNAL_TOPIC_PREFIX = 'localdrop/v2'; |
| const SETTINGS_KEY = 'localdrop.settings.v2'; |
| |
| const TRANSLATIONS = { |
| ru: { |
| pageTitle: 'LocalDrop — локальная передача файлов', |
| appSubtitle: 'Передавайте файлы между устройствами по 6-значному коду.', |
| tileSendTitle: 'Отправить', |
| tileSendDesc: 'Создать код и ждать получателя', |
| tileReceiveTitle: 'Получить', |
| tileReceiveDesc: 'Ввести код и подключиться', |
| homeFootnote: 'После первого подключения устройства запомнят друг друга.', |
| settingsTitle: 'Настройки', |
| sectionDevice: 'Устройство', |
| deviceNameLabel: 'Имя этого устройства', |
| rememberLabel: 'Запомнить это устройство', |
| rememberTiny: 'Сохраняет настройки и список устройств в этом браузере.', |
| resetPeersButton: 'Сбросить сохранённые подключения', |
| resetPeersTiny: 'Забыть список запомненных устройств для быстрой отправки.', |
| resetPeersEmpty: 'Нет сохранённых устройств.', |
| resetPeersConfirm: 'Забыть все сохранённые устройства?', |
| resetPeersDone: 'Список сохранённых устройств очищен.', |
| sectionReceiving: 'Приём файлов', |
| autoAcceptLabel: 'Подключаться без подтверждения', |
| autoAcceptTiny: 'Запомненные устройства подключаются сразу, без запроса.', |
| autoDownloadLabel: 'Скачивать файлы автоматически', |
| autoDownloadTiny: 'Иначе — кнопка «Скачать» рядом с файлом.', |
| notificationsLabel: 'Уведомления о завершении', |
| notificationsTiny: 'Системное уведомление, когда передача закончится в свёрнутой вкладке.', |
| sectionAppearance: 'Оформление', |
| darkThemeLabel: 'Тёмная тема', |
| darkThemeTiny: 'Переключить оформление приложения.', |
| languageLabel: 'Язык', |
| languageTiny: 'Язык интерфейса приложения.', |
| langRu: 'Русский', |
| langEn: 'English', |
| sectionConnection: 'Соединение', |
| stunLabel: 'STUN-сервер', |
| stunAuto: 'Автоматически (перебрать все)', |
| stunTiny: 'Помогает найти прямой путь между устройствами.', |
| turnLabel: 'TURN-сервер (для передачи не в одной сети)', |
| turnTiny: 'Нужен, если получатель в другой сети (мобильный интернет, VPN, строгий NAT) и прямое соединение невозможно.', |
| turnUsernamePlaceholder: 'Логин', |
| turnPasswordPlaceholder: 'Пароль', |
| fillTestTurnButton: 'Подставить бесплатный тестовый TURN', |
| fillTestTurnTiny: 'Тестовый сервер общий и не для постоянного использования — лучше завести свой (coturn, Metered, Twilio, Xirsys).', |
| advancedSummary: 'Дополнительно', |
| relayTiny: 'Relay для авто-поиска устройств. При недоступности используются резервные серверы.', |
| settingsFootnote: 'Изменения сохраняются автоматически.', |
| backButton: 'Назад', |
| sendTitle: 'Отправить файлы', |
| sendCodeHint: 'Код комнаты — введите его на устройстве получателя', |
| sendDirectHint: 'Отправляем приглашение на {name}.', |
| sendManualHint: 'Получатель подключится автоматически после ввода кода.', |
| qrHint: 'Отсканируйте или нажмите на QR, чтобы скопировать ссылку', |
| qrCopied: 'Ссылка скопирована!', |
| scanQrButton: 'Сканировать QR-код', |
| closeScannerButton: 'Закрыть камеру', |
| cameraError: 'Не удалось получить доступ к камере.', |
| scannerHint: 'Наведите камеру на QR-код с экрана отправителя.', |
| quickSendLabel: 'Быстрая отправка', |
| receiversLabel: 'Получатели', |
| searchingStatus: 'Запускаем поиск...', |
| dropTitle: 'Перетащите файлы сюда', |
| dropSubtitle: 'или нажмите для выбора', |
| shareFolderButton: 'Поделиться папкой (без сразу загрузки)', |
| folderPickerUnsupported: 'Выбор папок не поддерживается в этом браузере — доступно в Chrome/Edge.', |
| folderSharedStatus: 'Расшарена папка «{name}». Получатель сам выберет, что скачать.', |
| openBrowserButton: 'Открыть обзор файлов', |
| folderSharedBanner: 'Отправитель поделился папкой «{name}»', |
| downloadPickedButton: 'Скачать выбранное', |
| emptyFolderLabel: 'Папка пуста', |
| browseErrorLabel: 'Не удалось открыть папку', |
| rootFolderLabel: 'Корень', |
| waitingReceiverButton: 'Ожидание получателя...', |
| sendFilesButton: 'Отправить файлы', |
| inviteSentStatus: 'Приглашение отправлено на {name}.', |
| waitingCodeStatus: 'Ждём получателя по коду.', |
| localModeStatus: 'Локальный режим — работает только между вкладками этого браузера.', |
| receiveTitle: 'Получить файлы', |
| receiveHint: 'Введите код с экрана отправителя.', |
| connectButton: 'Подключиться', |
| waitingCodeInputStatus: 'Ожидание кода комнаты.', |
| deviceLabel: 'Устройство:', |
| establishingStatus: 'Устанавливаем соединение...', |
| connectedToStatus: 'Подключено к {name}. Ждём файлы...', |
| incomingTransferTitle: 'Входящая передача', |
| incomingTransferDesc: '{name} хочет отправить вам файлы.', |
| declineButton: 'Отклонить', |
| unknownDevice: 'Неизвестное устройство', |
| rememberedDevice: 'Запомненное устройство', |
| codeErrorStatus: 'Код должен состоять из 6 символов.', |
| roomFoundStatus: 'Комната найдена, ждём подключения.', |
| localModeReceiveStatus: 'Локальный режим — только между вкладками этого браузера.', |
| doneStatusText: 'Готово', |
| downloadLink: 'Скачать', |
| connPathDirect: 'Прямое соединение', |
| connPathRelay: 'Через TURN-релей', |
| etaLabel: 'Осталось: {time}', |
| secondsSuffix: 'с', |
| speedSuffix: '/с', |
| notifyTransferSentBody: 'Файлы успешно отправлены.', |
| notifyTransferReceivedBody: 'Файлы получены.', |
| badgeIdle: 'Не подключено', |
| badgeWaiting: 'Ожидание получателя...', |
| badgeSignaling: 'Авто-поиск...', |
| badgeConnecting: 'Подключение...', |
| badgeConnected: 'Подключено', |
| badgeDone: 'Передача завершена', |
| badgeDisconnected: 'Соединение прервано', |
| badgeError: 'Ошибка соединения', |
| settingsButtonTitle: 'Настройки', |
| signalTimeout: 'Таймаут подключения: {url}', |
| signalConnError: 'Ошибка подключения: {url}', |
| signalClosed: 'Соединение закрыто: {url}', |
| signalAllFailed: 'Не удалось подключиться ни к одному signaling relay', |
| byteUnits: ['Б', 'КБ', 'МБ', 'ГБ'] |
| }, |
| en: { |
| pageTitle: 'LocalDrop — local file transfer', |
| appSubtitle: 'Send files between devices using a 6-character code.', |
| tileSendTitle: 'Send', |
| tileSendDesc: 'Create a code and wait for a receiver', |
| tileReceiveTitle: 'Receive', |
| tileReceiveDesc: 'Enter a code and connect', |
| homeFootnote: 'After the first connection, devices will remember each other.', |
| settingsTitle: 'Settings', |
| sectionDevice: 'Device', |
| deviceNameLabel: 'Name of this device', |
| rememberLabel: 'Remember this device', |
| rememberTiny: 'Saves settings and the device list in this browser.', |
| resetPeersButton: 'Reset saved connections', |
| resetPeersTiny: 'Forget the list of remembered devices used for quick sending.', |
| resetPeersEmpty: 'No saved devices yet.', |
| resetPeersConfirm: 'Forget all saved devices?', |
| resetPeersDone: 'Saved devices list cleared.', |
| sectionReceiving: 'Receiving files', |
| autoAcceptLabel: 'Connect without confirmation', |
| autoAcceptTiny: 'Remembered devices connect right away, without asking.', |
| autoDownloadLabel: 'Download files automatically', |
| autoDownloadTiny: 'Otherwise use the "Download" button next to the file.', |
| notificationsLabel: 'Completion notifications', |
| notificationsTiny: 'Show a system notification when a transfer finishes in a background tab.', |
| sectionAppearance: 'Appearance', |
| darkThemeLabel: 'Dark theme', |
| darkThemeTiny: 'Switch the app’s appearance.', |
| languageLabel: 'Language', |
| languageTiny: 'Interface language.', |
| langRu: 'Русский', |
| langEn: 'English', |
| sectionConnection: 'Connection', |
| stunLabel: 'STUN server', |
| stunAuto: 'Automatic (try all)', |
| stunTiny: 'Helps find a direct path between devices.', |
| turnLabel: 'TURN server (for transfers across networks)', |
| turnTiny: 'Needed if the receiver is on a different network (mobile data, VPN, strict NAT) and a direct connection isn’t possible.', |
| turnUsernamePlaceholder: 'Username', |
| turnPasswordPlaceholder: 'Password', |
| fillTestTurnButton: 'Fill in a free test TURN server', |
| fillTestTurnTiny: 'The test server is shared and not for permanent use — better to set up your own (coturn, Metered, Twilio, Xirsys).', |
| advancedSummary: 'Advanced', |
| relayTiny: 'Relay used for device discovery. Backup servers are tried automatically if it’s unavailable.', |
| settingsFootnote: 'Changes are saved automatically.', |
| backButton: 'Back', |
| sendTitle: 'Send files', |
| sendCodeHint: 'Room code — enter it on the receiver’s device', |
| sendDirectHint: 'Sending an invite to {name}.', |
| sendManualHint: 'The receiver will connect automatically once they enter the code.', |
| qrHint: 'Scan it, or click the QR to copy the link', |
| qrCopied: 'Link copied!', |
| scanQrButton: 'Scan QR code', |
| closeScannerButton: 'Close camera', |
| cameraError: 'Could not access the camera.', |
| scannerHint: 'Point the camera at the QR code on the sender’s screen.', |
| quickSendLabel: 'Quick send', |
| receiversLabel: 'Recipients', |
| searchingStatus: 'Starting search...', |
| dropTitle: 'Drag files here', |
| dropSubtitle: 'or click to choose', |
| shareFolderButton: 'Share a folder (nothing uploads yet)', |
| folderPickerUnsupported: 'Folder picking isn’t supported in this browser — available in Chrome/Edge.', |
| folderSharedStatus: 'Sharing folder “{name}”. The receiver picks what to download.', |
| openBrowserButton: 'Browse files', |
| folderSharedBanner: 'Sender shared a folder: “{name}”', |
| downloadPickedButton: 'Download selected', |
| emptyFolderLabel: 'This folder is empty', |
| browseErrorLabel: 'Could not open the folder', |
| rootFolderLabel: 'Root', |
| waitingReceiverButton: 'Waiting for receiver...', |
| sendFilesButton: 'Send files', |
| inviteSentStatus: 'Invite sent to {name}.', |
| waitingCodeStatus: 'Waiting for the receiver to enter the code.', |
| localModeStatus: 'Local mode — only works between tabs in this browser.', |
| receiveTitle: 'Receive files', |
| receiveHint: 'Enter the code from the sender’s screen.', |
| connectButton: 'Connect', |
| waitingCodeInputStatus: 'Waiting for a room code.', |
| deviceLabel: 'Device:', |
| establishingStatus: 'Establishing connection...', |
| connectedToStatus: 'Connected to {name}. Waiting for files...', |
| incomingTransferTitle: 'Incoming transfer', |
| incomingTransferDesc: '{name} wants to send you files.', |
| declineButton: 'Decline', |
| unknownDevice: 'Unknown device', |
| rememberedDevice: 'Remembered device', |
| codeErrorStatus: 'The code must be 6 characters long.', |
| roomFoundStatus: 'Room found, waiting to connect.', |
| localModeReceiveStatus: 'Local mode — only between tabs in this browser.', |
| doneStatusText: 'Done', |
| downloadLink: 'Download', |
| connPathDirect: 'Direct connection', |
| connPathRelay: 'Via TURN relay', |
| etaLabel: 'Remaining: {time}', |
| secondsSuffix: 's', |
| speedSuffix: '/s', |
| notifyTransferSentBody: 'Files sent successfully.', |
| notifyTransferReceivedBody: 'Files received.', |
| badgeIdle: 'Not connected', |
| badgeWaiting: 'Waiting for receiver...', |
| badgeSignaling: 'Searching...', |
| badgeConnecting: 'Connecting...', |
| badgeConnected: 'Connected', |
| badgeDone: 'Transfer complete', |
| badgeDisconnected: 'Connection lost', |
| badgeError: 'Connection error', |
| settingsButtonTitle: 'Settings', |
| signalTimeout: 'Connection timeout: {url}', |
| signalConnError: 'Connection error: {url}', |
| signalClosed: 'Connection closed: {url}', |
| signalAllFailed: 'Could not connect to any signaling relay', |
| byteUnits: ['B', 'KB', 'MB', 'GB'] |
| } |
| }; |
| |
| const $ = (selector, root = document) => root.querySelector(selector); |
| const app = $('#app'); |
| |
| let pc = null; |
| let channel = null; |
| let signaling = null; |
| let deviceListener = null; |
| let queued = []; |
| let transfers = new Map(); |
| let receiveBuffers = new Map(); |
| let connectionState = 'idle'; |
| let currentRole = null; |
| let senderPeers = new Map(); |
| let aggregateState = null; |
| let scannerStream = null; |
| let scannerFrame = null; |
| let sharedDirHandle = null; |
| let sharedFolderName = null; |
| let browseState = null; |
| let selectedBrowsePicks = new Set(); |
| |
| const icons = { |
| share: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.6 13.5 6.8 4M15.4 6.5l-6.8 4"/></svg>', |
| down: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><path d="M7 10l5 5 5-5"/><path d="M12 15V3"/></svg>', |
| back: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m12 19-7-7 7-7"/><path d="M19 12H5"/></svg>', |
| upload: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 16l-4-4-4 4"/><path d="M12 12v9"/><path d="M20.4 18.4A5 5 0 0 0 18 9h-1.3A8 8 0 1 0 4 16.3"/></svg>', |
| hash: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 9h16M4 15h16M10 3 8 21M16 3l-2 18"/></svg>', |
| send: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg>', |
| gear: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z"/></svg>' |
| }; |
| |
| function detectLang() { |
| return (navigator.language || '').toLowerCase().startsWith('ru') ? 'ru' : 'en'; |
| } |
| |
| function t(key, vars = {}) { |
| const lang = loadSettings().lang === 'en' ? 'en' : 'ru'; |
| const dict = TRANSLATIONS[lang] || TRANSLATIONS.ru; |
| let str = dict[key] ?? TRANSLATIONS.ru[key] ?? key; |
| Object.entries(vars).forEach(([k, v]) => { str = str.replaceAll(`{${k}}`, v); }); |
| return str; |
| } |
| |
| function defaultDeviceName() { |
| const platform = navigator.userAgentData?.platform || navigator.platform || 'device'; |
| return detectLang() === 'en' ? `My ${platform}` : `Моё ${platform}`; |
| } |
| |
| function effectiveTheme(settings) { |
| if (settings.theme === 'dark' || settings.theme === 'light') return settings.theme; |
| return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; |
| } |
| |
| function applyPreferences(settings) { |
| document.documentElement.setAttribute('data-theme', effectiveTheme(settings)); |
| document.documentElement.lang = settings.lang === 'en' ? 'en' : 'ru'; |
| document.title = t('pageTitle'); |
| } |
| |
| function loadSettings() { |
| try { |
| const saved = JSON.parse(localStorage.getItem(SETTINGS_KEY) || '{}'); |
| return { |
| remember: true, |
| deviceId: saved.deviceId || crypto.randomUUID(), |
| deviceName: saved.deviceName || defaultDeviceName(), |
| peers: Array.isArray(saved.peers) ? saved.peers : [], |
| ...saved, |
| signalUrl: saved.signalUrl || DEFAULT_SIGNAL_URL, |
| stunServer: saved.stunServer || 'auto', |
| turnUrl: saved.turnUrl || '', |
| turnUsername: saved.turnUsername || '', |
| turnCredential: saved.turnCredential || '', |
| autoAccept: saved.autoAccept || false, |
| autoDownload: saved.autoDownload ?? true, |
| notifications: saved.notifications ?? true, |
| theme: saved.theme || 'auto', |
| lang: saved.lang || detectLang() |
| }; |
| } catch { |
| return { |
| remember: true, deviceId: crypto.randomUUID(), deviceName: defaultDeviceName(), peers: [], |
| signalUrl: DEFAULT_SIGNAL_URL, stunServer: 'auto', turnUrl: '', turnUsername: '', turnCredential: '', |
| autoAccept: false, autoDownload: true, notifications: true, theme: 'auto', lang: detectLang() |
| }; |
| } |
| } |
| |
| function saveSettings(settings) { |
| if (settings.remember) { |
| localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings)); |
| } else { |
| localStorage.removeItem(SETTINGS_KEY); |
| } |
| } |
| |
| function savePeer(peer) { |
| if (!peer?.deviceId) return; |
| const settings = loadSettings(); |
| const nextPeer = { id: peer.deviceId, name: peer.deviceName || t('rememberedDevice'), lastSeen: Date.now() }; |
| settings.peers = [nextPeer, ...settings.peers.filter((item) => item.id !== nextPeer.id)].slice(0, 8); |
| saveSettings(settings); |
| } |
| |
| function localPeerInfo() { |
| const settings = loadSettings(); |
| return { deviceId: settings.deviceId, deviceName: settings.deviceName }; |
| } |
| |
| function escapeHtml(value) { |
| return String(value).replace(/[&<>"']/g, (char) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[char])); |
| } |
| |
| function formatBytes(bytes) { |
| const units = t('byteUnits'); |
| if (!bytes) return `0 ${units[0]}`; |
| const index = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1); |
| return `${(bytes / 1024 ** index).toFixed(index ? 1 : 0)} ${units[index]}`; |
| } |
| |
| function formatDuration(seconds) { |
| const total = Math.max(0, Math.round(seconds)); |
| if (total < 60) return `${total}${t('secondsSuffix')}`; |
| const m = Math.floor(total / 60); |
| const s = total % 60; |
| return `${m}:${String(s).padStart(2, '0')}`; |
| } |
| |
| function generateRoomCode() { |
| return Math.random().toString(36).replace(/[^a-z0-9]/gi, '').slice(2, 8).toUpperCase().padEnd(6, 'X'); |
| } |
| |
| function throttle(fn, wait) { |
| let last = 0; |
| let timer = null; |
| return (...args) => { |
| const now = Date.now(); |
| const remaining = wait - (now - last); |
| if (remaining <= 0) { |
| clearTimeout(timer); |
| timer = null; |
| last = now; |
| fn(...args); |
| } else if (!timer) { |
| timer = setTimeout(() => { |
| last = Date.now(); |
| timer = null; |
| fn(...args); |
| }, remaining); |
| } |
| }; |
| } |
| |
| function badge() { |
| const labels = { |
| idle: t('badgeIdle'), |
| waiting: t('badgeWaiting'), |
| signaling: t('badgeSignaling'), |
| connecting: t('badgeConnecting'), |
| connected: t('badgeConnected'), |
| done: t('badgeDone'), |
| disconnected: t('badgeDisconnected'), |
| error: t('badgeError') |
| }; |
| const pulse = ['waiting', 'signaling', 'connecting'].includes(connectionState) ? ' pulse' : ''; |
| return `<div class="badge ${connectionState}"><span class="dot${pulse}"></span>${labels[connectionState]}</div>`; |
| } |
| |
| function setConnectionState(nextState) { |
| connectionState = nextState; |
| const current = $('.badge'); |
| if (current) current.outerHTML = badge(); |
| } |
| |
| function showStatus(message, type = 'notice') { |
| const status = $('#status'); |
| if (status) { |
| status.className = type; |
| status.textContent = message; |
| } |
| } |
| |
| |
| |
| |
| |
| function ensureNotificationPermission() { |
| if (!('Notification' in window)) return; |
| if (Notification.permission === 'default') Notification.requestPermission().catch(() => {}); |
| } |
| |
| function notifyTransferComplete(bodyKey) { |
| if (!loadSettings().notifications) return; |
| if (!('Notification' in window) || document.visibilityState !== 'hidden') return; |
| if (Notification.permission !== 'granted') return; |
| try { |
| new Notification('LocalDrop', { body: t(bodyKey), icon: 'icons/icon-192.png' }); |
| } catch (error) { |
| console.warn('Notification error:', error); |
| } |
| } |
| |
| |
| |
| |
| |
| async function reportConnectionPath(peerConnection, onResult) { |
| try { |
| await new Promise((resolve) => setTimeout(resolve, 400)); |
| const stats = await peerConnection.getStats(); |
| let pairStats; |
| stats.forEach((report) => { |
| if (report.type === 'candidate-pair' && report.nominated && (report.state === 'succeeded' || report.selected)) { |
| pairStats = report; |
| } |
| }); |
| if (!pairStats) return; |
| const local = stats.get(pairStats.localCandidateId); |
| const remote = stats.get(pairStats.remoteCandidateId); |
| const relay = local?.candidateType === 'relay' || remote?.candidateType === 'relay'; |
| onResult(relay ? t('connPathRelay') : t('connPathDirect')); |
| } catch (error) { |
| console.warn('getStats error:', error); |
| } |
| } |
| |
| |
| |
| |
| |
| function renderAggregateProgress() { |
| const container = $('#aggregate'); |
| if (!container || !aggregateState) return; |
| const { totalBytes, sentBytes, startTime } = aggregateState; |
| const percent = totalBytes ? Math.min(100, Math.round((sentBytes / totalBytes) * 100)) : 0; |
| const elapsed = (Date.now() - startTime) / 1000; |
| const speed = elapsed > 0.4 ? sentBytes / elapsed : 0; |
| const remaining = speed > 0 ? (totalBytes - sentBytes) / speed : 0; |
| container.classList.remove('hidden'); |
| container.innerHTML = ` |
| <div class="aggregate-row"><span>${formatBytes(sentBytes)} / ${formatBytes(totalBytes)}</span><span>${percent}%</span></div> |
| <div class="progress"><div class="bar" style="width:${percent}%"></div></div> |
| <div class="aggregate-row tiny"> |
| <span>${speed > 0 ? `${formatBytes(speed)}${t('speedSuffix')}` : ''}</span> |
| <span>${percent < 100 && speed > 0 ? t('etaLabel', { time: formatDuration(remaining) }) : ''}</span> |
| </div>`; |
| } |
| |
| const throttledRenderAggregateProgress = throttle(renderAggregateProgress, 150); |
| |
| |
| |
| |
| |
| function renderQrCode(url) { |
| const container = $('#qrCode'); |
| if (!container || typeof qrcode !== 'function') return; |
| try { |
| const qr = qrcode(0, 'M'); |
| qr.addData(url); |
| qr.make(); |
| container.innerHTML = qr.createSvgTag({ cellSize: 4, margin: 2, scalable: true }); |
| const svg = container.querySelector('svg'); |
| if (svg) { svg.style.width = '150px'; svg.style.height = '150px'; } |
| } catch (error) { |
| console.warn('QR render error:', error); |
| } |
| } |
| |
| async function copyShareLink(url) { |
| try { |
| if (navigator.clipboard?.writeText) { |
| await navigator.clipboard.writeText(url); |
| } else { |
| const textarea = document.createElement('textarea'); |
| textarea.value = url; |
| textarea.style.position = 'fixed'; |
| textarea.style.opacity = '0'; |
| document.body.appendChild(textarea); |
| textarea.select(); |
| document.execCommand('copy'); |
| textarea.remove(); |
| } |
| const hint = $('#qrHint'); |
| if (hint) { |
| const original = hint.dataset.original || hint.textContent; |
| hint.dataset.original = original; |
| hint.textContent = t('qrCopied'); |
| setTimeout(() => { hint.textContent = hint.dataset.original; }, 1500); |
| } |
| } catch (error) { |
| console.warn('Clipboard error:', error); |
| } |
| } |
| |
| |
| |
| |
| |
| function extractRoomCode(rawText) { |
| if (!rawText) return null; |
| const text = rawText.trim(); |
| |
| try { |
| const url = new URL(text); |
| const fromParam = url.searchParams.get('code'); |
| if (fromParam && /^[A-Z0-9]{6}$/i.test(fromParam)) return fromParam.toUpperCase(); |
| } catch { |
| |
| } |
| |
| return /^[A-Z0-9]{6}$/i.test(text) ? text.toUpperCase() : null; |
| } |
| |
| function stopQrScanner() { |
| if (scannerFrame) cancelAnimationFrame(scannerFrame); |
| scannerFrame = null; |
| scannerStream?.getTracks().forEach((track) => track.stop()); |
| scannerStream = null; |
| $('#qrScanner')?.classList.add('hidden'); |
| } |
| |
| async function startQrScanner(onCode) { |
| const scanner = $('#qrScanner'); |
| const video = $('#qrVideo'); |
| if (!scanner || !video || typeof jsQR !== 'function') return; |
| |
| try { |
| scannerStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } }); |
| } catch (error) { |
| showStatus(t('cameraError'), 'error-box'); |
| return; |
| } |
| |
| scanner.classList.remove('hidden'); |
| video.srcObject = scannerStream; |
| await video.play(); |
| |
| const canvas = document.createElement('canvas'); |
| const ctx = canvas.getContext('2d', { willReadFrequently: true }); |
| |
| const tick = () => { |
| if (!scannerStream) return; |
| if (video.readyState === video.HAVE_ENOUGH_DATA) { |
| canvas.width = video.videoWidth; |
| canvas.height = video.videoHeight; |
| ctx.drawImage(video, 0, 0, canvas.width, canvas.height); |
| const frame = ctx.getImageData(0, 0, canvas.width, canvas.height); |
| const result = jsQR(frame.data, frame.width, frame.height); |
| const code = extractRoomCode(result?.data); |
| if (code) { |
| stopQrScanner(); |
| onCode(code); |
| return; |
| } |
| } |
| scannerFrame = requestAnimationFrame(tick); |
| }; |
| scannerFrame = requestAnimationFrame(tick); |
| } |
| |
| function encodeText(value) { |
| return new TextEncoder().encode(value); |
| } |
| |
| function decodeText(value) { |
| return new TextDecoder().decode(value); |
| } |
| |
| function encodeRemainingLength(length) { |
| const bytes = []; |
| do { |
| let byte = length % 128; |
| length = Math.floor(length / 128); |
| if (length > 0) byte |= 128; |
| bytes.push(byte); |
| } while (length > 0); |
| return bytes; |
| } |
| |
| function mqttString(value) { |
| const bytes = encodeText(value); |
| return [bytes.length >> 8, bytes.length & 255, ...bytes]; |
| } |
| |
| function mqttPacket(type, body = []) { |
| return new Uint8Array([type, ...encodeRemainingLength(body.length), ...body]); |
| } |
| |
| class LocalSignaling { |
| constructor({ roomCode, role, signalUrl, onSignal }) { |
| this.roomCode = roomCode; |
| this.role = role; |
| this.signalUrl = signalUrl || DEFAULT_SIGNAL_URL; |
| this.onSignal = onSignal; |
| this.clientId = crypto.randomUUID(); |
| this.topic = `${SIGNAL_TOPIC_PREFIX}/${roomCode.toLowerCase()}`; |
| this.channel = null; |
| this.socket = null; |
| this.ready = false; |
| this.queue = []; |
| this.keepAliveTimer = null; |
| this.packetId = 1; |
| } |
| |
| connect() { |
| if (this.signalUrl === 'browser') return this.connectBroadcastChannel(); |
| const preferred = this.signalUrl || DEFAULT_SIGNAL_URL; |
| const candidates = [preferred, ...SIGNAL_RELAYS.filter((url) => url !== preferred)]; |
| return this.connectWithFallback(candidates); |
| } |
| |
| async connectWithFallback(candidates) { |
| let lastError; |
| for (const url of candidates) { |
| try { |
| const result = await this.connectMqttWebSocket(url); |
| this.signalUrl = url; |
| return result; |
| } catch (error) { |
| lastError = error; |
| console.warn(`Signaling relay unavailable (${url}):`, error.message); |
| } |
| } |
| throw lastError || new Error(t('signalAllFailed')); |
| } |
| |
| connectBroadcastChannel() { |
| this.channel = new BroadcastChannel(`localdrop:${this.roomCode}`); |
| this.channel.onmessage = (event) => this.receive(event.data); |
| this.ready = true; |
| this.flush(); |
| return Promise.resolve('browser'); |
| } |
| |
| connectMqttWebSocket(url) { |
| return new Promise((resolve, reject) => { |
| let settled = false; |
| const settle = (fn, arg) => { if (!settled) { settled = true; clearTimeout(timeout); fn(arg); } }; |
| const timeout = setTimeout(() => { |
| settle(reject, new Error(t('signalTimeout', { url }))); |
| this.socket?.close(); |
| }, 6000); |
| |
| this.socket = new WebSocket(url, 'mqtt'); |
| this.socket.binaryType = 'arraybuffer'; |
| |
| this.socket.onopen = () => { |
| const clientId = `localdrop-${this.clientId.slice(0, 18)}`; |
| const variableHeader = [...mqttString('MQTT'), 4, 2, 0, 60]; |
| const payload = mqttString(clientId); |
| this.socket.send(mqttPacket(0x10, [...variableHeader, ...payload])); |
| }; |
| |
| this.socket.onmessage = (event) => { |
| const result = this.handleMqttPacket(new Uint8Array(event.data)); |
| if (result === 'ready') settle(resolve, 'network'); |
| }; |
| |
| this.socket.onerror = () => settle(reject, new Error(t('signalConnError', { url }))); |
| this.socket.onclose = () => { |
| clearInterval(this.keepAliveTimer); |
| if (!settled) { settle(reject, new Error(t('signalClosed', { url }))); return; } |
| if (connectionState !== 'connected' && connectionState !== 'idle') setConnectionState('error'); |
| }; |
| }); |
| } |
| |
| handleMqttPacket(packet) { |
| const type = packet[0] >> 4; |
| let multiplier = 1; |
| let value = 0; |
| let offset = 1; |
| let encodedByte; |
| |
| do { |
| encodedByte = packet[offset++]; |
| value += (encodedByte & 127) * multiplier; |
| multiplier *= 128; |
| } while ((encodedByte & 128) !== 0); |
| |
| if (type === 2) { |
| this.subscribe(); |
| this.keepAliveTimer = setInterval(() => this.socket?.send(mqttPacket(0xc0)), 30000); |
| } |
| |
| if (type === 9) { |
| this.ready = true; |
| this.sendRaw('join', {}); |
| this.flush(); |
| return 'ready'; |
| } |
| |
| if (type === 3) { |
| const topicLength = (packet[offset] << 8) + packet[offset + 1]; |
| offset += 2; |
| const topic = decodeText(packet.slice(offset, offset + topicLength)); |
| offset += topicLength; |
| if (topic !== this.topic) return null; |
| |
| try { |
| this.receive(JSON.parse(decodeText(packet.slice(offset)))); |
| } catch (error) { |
| console.warn('Signal parse error:', error); |
| } |
| } |
| |
| return null; |
| } |
| |
| subscribe() { |
| const id = this.packetId++; |
| const body = [id >> 8, id & 255, ...mqttString(this.topic), 0]; |
| this.socket.send(mqttPacket(0x82, body)); |
| } |
| |
| send(type, payload, to = null) { |
| if (!this.ready) { |
| this.queue.push({ type, payload, to }); |
| return; |
| } |
| this.sendRaw(type, payload, to); |
| } |
| |
| sendRaw(type, payload, to = null) { |
| const message = { room: this.roomCode, from: this.role, clientId: this.clientId, type, payload, to }; |
| if (this.socket?.readyState === WebSocket.OPEN) { |
| const payloadBytes = encodeText(JSON.stringify(message)); |
| this.socket.send(mqttPacket(0x30, [...mqttString(this.topic), ...payloadBytes])); |
| } |
| if (this.channel) this.channel.postMessage(message); |
| } |
| |
| flush() { |
| this.queue.splice(0).forEach((message) => this.sendRaw(message.type, message.payload, message.to)); |
| } |
| |
| receive(message) { |
| if (!message || message.room !== this.roomCode || message.clientId === this.clientId) return; |
| if (message.from === this.role) return; |
| if (message.to && message.to !== this.clientId) return; |
| this.onSignal(message.type, message.payload, message.clientId); |
| } |
| |
| close() { |
| clearInterval(this.keepAliveTimer); |
| this.channel?.close(); |
| this.socket?.close(); |
| } |
| } |
| |
| function reset() { |
| stopQrScanner(); |
| signaling?.close(); |
| deviceListener?.close(); |
| channel?.close(); |
| receiverChannels.forEach((ch) => ch.close()); |
| receiverChannels = []; |
| pc?.close(); |
| senderPeers.forEach((peer) => { peer.channels?.forEach((ch) => ch.close()); peer.pc?.close(); }); |
| senderPeers = new Map(); |
| signaling = null; |
| deviceListener = null; |
| channel = null; |
| pc = null; |
| queued = []; |
| transfers.clear(); |
| receiveBuffers.clear(); |
| connectionState = 'idle'; |
| currentRole = null; |
| aggregateState = null; |
| sharedDirHandle = null; |
| sharedFolderName = null; |
| browseState = null; |
| selectedBrowsePicks = new Set(); |
| } |
| |
| |
| function waitForIceGathering(target = pc) { |
| return new Promise((resolve) => { |
| if (!target || target.iceGatheringState === 'complete') { |
| resolve(); |
| return; |
| } |
| |
| const finish = () => { |
| if (target.iceGatheringState === 'complete') { |
| target.removeEventListener('icegatheringstatechange', finish); |
| resolve(); |
| } |
| }; |
| |
| target.addEventListener('icegatheringstatechange', finish); |
| setTimeout(resolve, 2500); |
| }); |
| } |
| |
| function getIceServers() { |
| const settings = loadSettings(); |
| const servers = settings.stunServer && settings.stunServer !== 'auto' ? [{ urls: settings.stunServer }] : [...ICE_SERVERS]; |
| if (settings.turnUrl) { |
| servers.push({ |
| urls: settings.turnUrl, |
| username: settings.turnUsername || undefined, |
| credential: settings.turnCredential || undefined |
| }); |
| } |
| return servers; |
| } |
| |
| function createPeerConnection() { |
| pc = new RTCPeerConnection({ iceServers: getIceServers() }); |
| |
| pc.onicecandidate = (event) => { |
| if (event.candidate) signaling?.send('ice-candidate', event.candidate.toJSON()); |
| }; |
| |
| pc.onconnectionstatechange = () => { |
| const state = pc.connectionState; |
| if (state === 'connected') { |
| setConnectionState('connected'); |
| return; |
| } |
| |
| |
| if (channel?.readyState === 'open') return; |
| if (state === 'disconnected') { |
| setTimeout(() => { |
| if (pc.connectionState === 'disconnected' && channel?.readyState !== 'open') { |
| setConnectionState(allTransfersDone() ? 'done' : 'disconnected'); |
| } |
| }, 4000); |
| return; |
| } |
| if (state === 'failed') setConnectionState(allTransfersDone() ? 'done' : 'error'); |
| if (state === 'closed') setConnectionState(allTransfersDone() ? 'done' : 'disconnected'); |
| }; |
| |
| return pc; |
| } |
| |
| let receiverChannels = []; |
| |
| function sendControl(message) { |
| const target = receiverChannels.find((ch) => ch.readyState === 'open') || channel; |
| target?.send(JSON.stringify(message)); |
| } |
| |
| function setupDataChannel(nextChannel) { |
| receiverChannels.push(nextChannel); |
| channel = nextChannel; |
| nextChannel.binaryType = 'arraybuffer'; |
| nextChannel.onopen = () => { |
| if (receiverChannels.filter((ch) => ch.readyState === 'open').length === 1) { |
| setConnectionState('connected'); |
| sendControl({ kind: 'peer-info', ...localPeerInfo() }); |
| reportConnectionPath(pc, (label) => { const el = $('#connPath'); if (el) el.textContent = label; }); |
| } |
| }; |
| nextChannel.onclose = () => { |
| if (!receiverChannels.some((ch) => ch.readyState === 'open')) { |
| setConnectionState(allTransfersDone() ? 'done' : 'disconnected'); |
| } |
| }; |
| nextChannel.onmessage = (event) => handleDataMessage(event.data); |
| } |
| |
| function allTransfersDone() { |
| if (transfers.size === 0) return false; |
| return [...transfers.values()].every((file) => file.status === 'done'); |
| } |
| |
| |
| |
| |
| |
| async function listSharedDirectory(pathSegments) { |
| let dir = sharedDirHandle; |
| for (const segment of pathSegments) dir = await dir.getDirectoryHandle(segment); |
| const entries = []; |
| for await (const [name, handle] of dir.entries()) { |
| if (handle.kind === 'file') { |
| const file = await handle.getFile(); |
| entries.push({ name, kind: 'file', size: file.size }); |
| } else { |
| entries.push({ name, kind: 'directory' }); |
| } |
| } |
| entries.sort((a, b) => (a.kind === b.kind ? a.name.localeCompare(b.name) : a.kind === 'directory' ? -1 : 1)); |
| return entries; |
| } |
| |
| async function handleBrowseRequest(dataChannel, pathSegments) { |
| if (!sharedDirHandle) return; |
| try { |
| const entries = await listSharedDirectory(pathSegments); |
| dataChannel.send(JSON.stringify({ kind: 'browse-response', path: pathSegments, entries })); |
| } catch (error) { |
| dataChannel.send(JSON.stringify({ kind: 'browse-response', path: pathSegments, entries: [], error: String(error) })); |
| } |
| } |
| |
| async function handleFileRequest(dataChannel, pathSegments, requestId) { |
| if (!sharedDirHandle) return; |
| try { |
| let dir = sharedDirHandle; |
| for (let i = 0; i < pathSegments.length - 1; i++) dir = await dir.getDirectoryHandle(pathSegments[i]); |
| const fileHandle = await dir.getFileHandle(pathSegments[pathSegments.length - 1]); |
| const file = await fileHandle.getFile(); |
| dataChannel.send(JSON.stringify({ kind: 'meta', id: requestId, name: file.name, size: file.size, type: file.type })); |
| const wholeBuffer = file.size <= WHOLE_FILE_READ_LIMIT ? await file.arrayBuffer() : null; |
| for (let offset = 0; offset < file.size; offset += CHUNK_SIZE) { |
| await waitForBufferedAmountLow(dataChannel); |
| const rawChunk = wholeBuffer |
| ? wholeBuffer.slice(offset, offset + CHUNK_SIZE) |
| : await file.slice(offset, offset + CHUNK_SIZE).arrayBuffer(); |
| dataChannel.send(packChunk(requestId, offset, rawChunk)); |
| } |
| dataChannel.send(JSON.stringify({ kind: 'done', id: requestId })); |
| } catch (error) { |
| dataChannel.send(JSON.stringify({ kind: 'file-error', id: requestId, message: String(error) })); |
| } |
| } |
| |
| |
| |
| |
| |
| function createSenderPeerConnection(clientId) { |
| const peerConnection = new RTCPeerConnection({ iceServers: getIceServers() }); |
| peerConnection.onicecandidate = (event) => { |
| if (event.candidate) signaling?.send('ice-candidate', event.candidate.toJSON(), clientId); |
| }; |
| peerConnection.onconnectionstatechange = () => { |
| const entry = senderPeers.get(clientId); |
| if (!entry) return; |
| if (['disconnected', 'failed', 'closed'].includes(peerConnection.connectionState) && entry.channel?.readyState !== 'open') { |
| entry.state = 'disconnected'; |
| renderReceiversList(); |
| updateSendButtonState(); |
| } |
| }; |
| return peerConnection; |
| } |
| |
| function setupSenderDataChannel(clientId, dataChannel) { |
| dataChannel.binaryType = 'arraybuffer'; |
| dataChannel.onopen = () => { |
| const entry = senderPeers.get(clientId); |
| if (!entry) return; |
| entry.openChannels = (entry.openChannels || 0) + 1; |
| if (entry.openChannels < entry.channels.length) return; |
| entry.state = 'connected'; |
| entry.channel.send(JSON.stringify({ kind: 'peer-info', ...localPeerInfo() })); |
| if (sharedDirHandle) entry.channel.send(JSON.stringify({ kind: 'folder-shared', name: sharedDirHandle.name })); |
| renderReceiversList(); |
| updateSendButtonState(); |
| reportConnectionPath(entry.pc, (label) => { entry.path = label; renderReceiversList(); }); |
| }; |
| dataChannel.onclose = () => { |
| const entry = senderPeers.get(clientId); |
| if (entry) { entry.state = 'disconnected'; renderReceiversList(); updateSendButtonState(); } |
| }; |
| dataChannel.onmessage = (event) => { |
| if (typeof event.data !== 'string') return; |
| try { |
| const message = JSON.parse(event.data); |
| if (message.kind === 'peer-info') { |
| const entry = senderPeers.get(clientId); |
| if (entry) entry.name = message.deviceName; |
| savePeer(message); |
| renderReceiversList(); |
| return; |
| } |
| if (message.kind === 'browse-request') { |
| handleBrowseRequest(dataChannel, message.path || []); |
| return; |
| } |
| if (message.kind === 'file-request') { |
| handleFileRequest(dataChannel, message.path || [], message.id); |
| return; |
| } |
| } catch (error) { |
| console.warn('Peer message parse error:', error); |
| } |
| }; |
| } |
| |
| function renderReceiversList() { |
| const container = $('#receiversList'); |
| if (!container) return; |
| const peers = [...senderPeers.values()]; |
| if (!peers.length) { container.innerHTML = ''; container.className = ''; return; } |
| container.className = 'peer-quick'; |
| container.innerHTML = ` |
| <div class="peer-quick-label">${t('receiversLabel')}</div> |
| <div class="peer-chips">${peers.map((peer) => ` |
| <span class="peer-chip receiver-chip ${peer.state}"> |
| <span class="receiver-dot"></span>${escapeHtml(peer.name || '…')}${peer.path ? ` · ${peer.path}` : ''} |
| </span>`).join('')}</div>`; |
| } |
| |
| function updateSendButtonState() { |
| const button = $('#sendFiles'); |
| if (!button) return; |
| const anyConnected = [...senderPeers.values()].some((peer) => peer.state === 'connected'); |
| button.disabled = !anyConnected; |
| button.innerHTML = anyConnected ? `${icons.send} ${t('sendFilesButton')}` : `${icons.send} ${t('waitingReceiverButton')}`; |
| } |
| |
| async function handleSignal(type, payload, fromClientId) { |
| if (currentRole === 'sender') { |
| if (type === 'receiver-ready') { |
| if (senderPeers.has(fromClientId)) return; |
| const peerConnection = createSenderPeerConnection(fromClientId); |
| const channels = Array.from({ length: PARALLEL_CHANNELS }, (_, i) => peerConnection.createDataChannel(`files-${i}`, { ordered: true })); |
| senderPeers.set(fromClientId, { pc: peerConnection, channels, channel: channels[0], openChannels: 0, name: null, path: '', state: 'connecting' }); |
| channels.forEach((ch) => setupSenderDataChannel(fromClientId, ch)); |
| renderReceiversList(); |
| await peerConnection.setLocalDescription(await peerConnection.createOffer()); |
| await waitForIceGathering(peerConnection); |
| signaling.send('offer', { sdp: peerConnection.localDescription.sdp, type: peerConnection.localDescription.type }, fromClientId); |
| return; |
| } |
| |
| if (type === 'answer') { |
| const entry = senderPeers.get(fromClientId); |
| if (entry) await entry.pc.setRemoteDescription(payload); |
| return; |
| } |
| |
| if (type === 'ice-candidate') { |
| const entry = senderPeers.get(fromClientId); |
| if (entry) { |
| try { await entry.pc.addIceCandidate(payload); } catch (error) { console.warn('ICE candidate error:', error); } |
| } |
| return; |
| } |
| } |
| |
| if (currentRole === 'receiver' && type === 'offer') { |
| createPeerConnection(); |
| pc.ondatachannel = (event) => setupDataChannel(event.channel); |
| await pc.setRemoteDescription(payload); |
| const answer = await pc.createAnswer(); |
| await pc.setLocalDescription(answer); |
| await waitForIceGathering(); |
| signaling.send('answer', { sdp: pc.localDescription.sdp, type: pc.localDescription.type }); |
| setConnectionState('connecting'); |
| } |
| |
| if (currentRole === 'receiver' && type === 'ice-candidate' && pc) { |
| try { |
| await pc.addIceCandidate(payload); |
| } catch (error) { |
| console.warn('ICE candidate error:', error); |
| } |
| } |
| } |
| |
| function renderHome() { |
| reset(); |
| const settings = loadSettings(); |
| applyPreferences(settings); |
| app.innerHTML = ` |
| <section class="screen home"> |
| <button class="icon-button settings-trigger" id="openSettings" aria-label="${t('settingsButtonTitle')}" title="${t('settingsButtonTitle')}">${icons.gear}</button> |
| <div class="brand"> |
| <div class="brand-row"><div class="logo">${icons.share}</div><h1>LocalDrop</h1></div> |
| <p class="muted">${t('appSubtitle')}</p> |
| </div> |
| <div class="tiles"> |
| <button class="tile send" id="send"><div class="tile-icon">${icons.share}</div><div><div class="tile-title">${t('tileSendTitle')}</div><div class="tile-desc">${t('tileSendDesc')}</div></div></button> |
| <button class="tile receive" id="receive"><div class="tile-icon">${icons.down}</div><div><div class="tile-title">${t('tileReceiveTitle')}</div><div class="tile-desc">${t('tileReceiveDesc')}</div></div></button> |
| </div> |
| <p class="footnote">${t('homeFootnote')}</p> |
| </section>`; |
| |
| $('#send').onclick = () => renderSend(loadSettings()); |
| $('#receive').onclick = () => renderReceive(loadSettings()); |
| $('#openSettings').onclick = () => renderSettings(loadSettings()); |
| startDeviceListener(settings); |
| } |
| |
| function renderSettings(settings) { |
| renderLayout(t('settingsTitle'), ` |
| <div class="card settings-card"> |
| <div class="section-title">${t('sectionDevice')}</div> |
| <label class="field-label" for="deviceName">${t('deviceNameLabel')}</label> |
| <input id="deviceName" class="plain-input" type="text" value="${escapeHtml(settings.deviceName)}" /> |
| <label class="switch-row"> |
| <span class="switch-label"> |
| <span class="field-label">${t('rememberLabel')}</span> |
| <span class="tiny">${t('rememberTiny')}</span> |
| </span> |
| <span class="switch"><input id="remember" type="checkbox" ${settings.remember ? 'checked' : ''} /><span class="switch-slider"></span></span> |
| </label> |
| <div class="field-divider"></div> |
| <button type="button" class="small-button" id="resetPeers" ${settings.peers.length ? '' : 'disabled'}>${t('resetPeersButton')}</button> |
| <p class="tiny">${settings.peers.length ? t('resetPeersTiny') : t('resetPeersEmpty')}</p> |
| </div> |
| |
| <div class="card settings-card"> |
| <div class="section-title">${t('sectionReceiving')}</div> |
| <label class="switch-row"> |
| <span class="switch-label"> |
| <span class="field-label">${t('autoAcceptLabel')}</span> |
| <span class="tiny">${t('autoAcceptTiny')}</span> |
| </span> |
| <span class="switch"><input id="autoAccept" type="checkbox" ${settings.autoAccept ? 'checked' : ''} /><span class="switch-slider"></span></span> |
| </label> |
| <label class="switch-row"> |
| <span class="switch-label"> |
| <span class="field-label">${t('autoDownloadLabel')}</span> |
| <span class="tiny">${t('autoDownloadTiny')}</span> |
| </span> |
| <span class="switch"><input id="autoDownload" type="checkbox" ${settings.autoDownload ? 'checked' : ''} /><span class="switch-slider"></span></span> |
| </label> |
| <label class="switch-row"> |
| <span class="switch-label"> |
| <span class="field-label">${t('notificationsLabel')}</span> |
| <span class="tiny">${t('notificationsTiny')}</span> |
| </span> |
| <span class="switch"><input id="notifications" type="checkbox" ${settings.notifications ? 'checked' : ''} /><span class="switch-slider"></span></span> |
| </label> |
| </div> |
| |
| <div class="card settings-card"> |
| <div class="section-title">${t('sectionAppearance')}</div> |
| <label class="switch-row"> |
| <span class="switch-label"> |
| <span class="field-label">${t('darkThemeLabel')}</span> |
| <span class="tiny">${t('darkThemeTiny')}</span> |
| </span> |
| <span class="switch"><input id="darkTheme" type="checkbox" ${effectiveTheme(settings) === 'dark' ? 'checked' : ''} /><span class="switch-slider"></span></span> |
| </label> |
| <label class="field-label" for="language">${t('languageLabel')}</label> |
| <select id="language" class="plain-input"> |
| <option value="ru" ${settings.lang === 'ru' ? 'selected' : ''}>${t('langRu')}</option> |
| <option value="en" ${settings.lang === 'en' ? 'selected' : ''}>${t('langEn')}</option> |
| </select> |
| <p class="tiny">${t('languageTiny')}</p> |
| </div> |
| |
| <div class="card settings-card"> |
| <div class="section-title">${t('sectionConnection')}</div> |
| <label class="field-label" for="stunServer">${t('stunLabel')}</label> |
| <select id="stunServer" class="plain-input"> |
| <option value="auto" ${settings.stunServer === 'auto' ? 'selected' : ''}>${t('stunAuto')}</option> |
| ${ICE_SERVERS.map((server) => `<option value="${server.urls}" ${settings.stunServer === server.urls ? 'selected' : ''}>${server.urls.replace('stun:', '')}</option>`).join('')} |
| </select> |
| <p class="tiny">${t('stunTiny')}</p> |
| |
| <div class="field-divider"></div> |
| |
| <label class="field-label" for="turnUrl">${t('turnLabel')}</label> |
| <p class="tiny">${t('turnTiny')}</p> |
| <div class="field-group"> |
| <input id="turnUrl" class="plain-input" type="text" value="${escapeHtml(settings.turnUrl)}" placeholder="turn:relay.example.com:3478" /> |
| <input id="turnUsername" class="plain-input" type="text" value="${escapeHtml(settings.turnUsername)}" placeholder="${t('turnUsernamePlaceholder')}" /> |
| <input id="turnCredential" class="plain-input" type="password" value="${escapeHtml(settings.turnCredential)}" placeholder="${t('turnPasswordPlaceholder')}" /> |
| </div> |
| <button type="button" class="small-button" id="fillTestTurn">${t('fillTestTurnButton')}</button> |
| <p class="tiny">${t('fillTestTurnTiny')}</p> |
| |
| <div class="field-divider"></div> |
| |
| <details class="advanced-settings"><summary>${t('advancedSummary')}</summary><input id="signalUrl" class="plain-input" type="url" value="${escapeHtml(settings.signalUrl)}" placeholder="wss://test.mosquitto.org:8081/mqtt" /><p class="tiny">${t('relayTiny')}</p></details> |
| </div> |
| <p class="footnote">${t('settingsFootnote')}</p>`); |
| |
| const persist = () => saveSettings({ |
| ...loadSettings(), |
| deviceName: ($('#deviceName').value || settings.deviceName).trim(), |
| remember: $('#remember').checked, |
| autoAccept: $('#autoAccept').checked, |
| autoDownload: $('#autoDownload').checked, |
| notifications: $('#notifications').checked, |
| theme: $('#darkTheme').checked ? 'dark' : 'light', |
| stunServer: $('#stunServer').value, |
| turnUrl: $('#turnUrl').value.trim(), |
| turnUsername: $('#turnUsername').value.trim(), |
| turnCredential: $('#turnCredential').value.trim(), |
| signalUrl: ($('#signalUrl').value || DEFAULT_SIGNAL_URL).trim() |
| }); |
| |
| $('#deviceName').onchange = persist; |
| $('#remember').onchange = persist; |
| $('#autoAccept').onchange = persist; |
| $('#autoDownload').onchange = persist; |
| $('#notifications').onchange = () => { persist(); ensureNotificationPermission(); }; |
| $('#darkTheme').onchange = () => { persist(); applyPreferences(loadSettings()); }; |
| $('#language').onchange = () => { |
| saveSettings({ ...loadSettings(), lang: $('#language').value }); |
| renderSettings(loadSettings()); |
| }; |
| $('#stunServer').onchange = persist; |
| $('#turnUrl').onchange = persist; |
| $('#turnUsername').onchange = persist; |
| $('#turnCredential').onchange = persist; |
| $('#signalUrl').onchange = persist; |
| $('#fillTestTurn').onclick = () => { |
| $('#turnUrl').value = 'turn:openrelay.metered.ca:80'; |
| $('#turnUsername').value = 'openrelayproject'; |
| $('#turnCredential').value = 'openrelayproject'; |
| persist(); |
| }; |
| $('#resetPeers').onclick = () => { |
| if (!settings.peers.length) return; |
| if (!confirm(t('resetPeersConfirm'))) return; |
| saveSettings({ ...loadSettings(), peers: [] }); |
| renderSettings(loadSettings()); |
| }; |
| } |
| |
| function renderLayout(title, body) { |
| applyPreferences(loadSettings()); |
| app.innerHTML = ` |
| <section class="screen"> |
| <button class="back" id="back">${icons.back} ${t('backButton')}</button> |
| <div class="header"><h2>${title}</h2>${badge()}</div> |
| ${body} |
| </section>`; |
| $('#back').onclick = () => { |
| reset(); |
| renderHome(); |
| }; |
| } |
| |
| async function renderSend(settings, directPeer = null) { |
| reset(); |
| currentRole = 'sender'; |
| ensureNotificationPermission(); |
| const roomCode = generateRoomCode(); |
| const shareUrl = `${location.origin}${location.pathname}?code=${roomCode}`; |
| |
| renderLayout(t('sendTitle'), ` |
| <div class="card center"> |
| <p class="muted">${t('sendCodeHint')}</p> |
| <div class="code-row">${roomCode.split('').map((char) => `<span class="code-char">${char}</span>`).join('')}</div> |
| <div id="qrCode" class="qr-wrap"></div> |
| <p class="tiny" id="qrHint">${t('qrHint')}</p> |
| <p class="tiny">${directPeer ? t('sendDirectHint', { name: escapeHtml(directPeer.name) }) : t('sendManualHint')}</p> |
| ${!directPeer && settings.peers.length ? `<div class="peer-quick"><div class="peer-quick-label">${t('quickSendLabel')}</div><div class="peer-chips">${settings.peers.map((peer) => `<button class="peer-chip" data-peer="${peer.id}">${escapeHtml(peer.name)}</button>`).join('')}</div></div>` : ''} |
| <div id="receiversList"></div> |
| </div> |
| <div id="status" class="notice">${t('searchingStatus')}</div> |
| <div class="drop" id="drop"><div class="icon">${icons.upload}</div><b>${t('dropTitle')}</b><span class="tiny">${t('dropSubtitle')}</span><input class="hidden" id="file" type="file" multiple></div> |
| <button type="button" class="small-button" id="shareFolder">${t('shareFolderButton')}</button> |
| <div id="folderShareStatus" class="tiny"></div> |
| <div class="queue" id="queue"></div> |
| <div class="card hidden" id="aggregate"></div> |
| <button class="button sky" id="sendFiles" disabled>${icons.send} ${t('waitingReceiverButton')}</button> |
| <div class="files" id="files"></div>`); |
| |
| renderQrCode(shareUrl); |
| const qrEl = $('#qrCode'); |
| if (qrEl) qrEl.onclick = () => copyShareLink(shareUrl); |
| |
| try { |
| signaling = new LocalSignaling({ roomCode, role: 'sender', signalUrl: settings.signalUrl, onSignal: handleSignal }); |
| const mode = await signaling.connect(); |
| setConnectionState('waiting'); |
| if (directPeer) await sendDirectInvite(settings, directPeer, roomCode); |
| showStatus(directPeer ? t('inviteSentStatus', { name: directPeer.name }) : (mode === 'network' ? t('waitingCodeStatus') : t('localModeStatus'))); |
| } catch (error) { |
| setConnectionState('error'); |
| showStatus(error.message, 'error-box'); |
| } |
| |
| const fileInput = $('#file'); |
| const drop = $('#drop'); |
| drop.onclick = () => fileInput.click(); |
| drop.ondragover = (event) => { event.preventDefault(); drop.classList.add('drag'); }; |
| drop.ondragleave = () => drop.classList.remove('drag'); |
| drop.ondrop = (event) => { event.preventDefault(); drop.classList.remove('drag'); addFiles(event.dataTransfer.files); }; |
| fileInput.onchange = (event) => addFiles(event.target.files); |
| $('#sendFiles').onclick = sendFiles; |
| $('#shareFolder').onclick = async () => { |
| if (!window.showDirectoryPicker) { |
| showStatus(t('folderPickerUnsupported'), 'error-box'); |
| return; |
| } |
| try { |
| sharedDirHandle = await window.showDirectoryPicker(); |
| const hint = $('#folderShareStatus'); |
| if (hint) hint.textContent = t('folderSharedStatus', { name: sharedDirHandle.name }); |
| senderPeers.forEach((peer) => { |
| if (peer.channel?.readyState === 'open') { |
| peer.channel.send(JSON.stringify({ kind: 'folder-shared', name: sharedDirHandle.name })); |
| } |
| }); |
| } catch (error) { |
| |
| } |
| }; |
| document.querySelectorAll('[data-peer]').forEach((button) => { |
| button.onclick = () => { |
| const peer = settings.peers.find((item) => item.id === button.dataset.peer); |
| renderSend(settings, peer); |
| }; |
| }); |
| } |
| |
| function renderReceive(settings, autoRoomCode = '', peerName = '') { |
| reset(); |
| currentRole = 'receiver'; |
| ensureNotificationPermission(); |
| |
| if (autoRoomCode && peerName) { |
| renderLayout(t('receiveTitle'), ` |
| <div class="card center"> |
| <div class="tile-icon" style="margin:0 auto 16px;background:var(--green-soft-bg);color:var(--green)">${icons.down}</div> |
| <p class="muted">${t('deviceLabel')} <b>${escapeHtml(peerName)}</b></p> |
| <div id="status" class="notice">${t('establishingStatus')}</div> |
| <div id="connPath" class="tiny"></div> |
| <div id="folderShareBanner" class="hidden"></div> |
| </div> |
| <div id="fileBrowser" class="hidden"></div> |
| <div class="card hidden" id="aggregate"></div> |
| <div class="files" id="files"></div>`); |
| joinRoom(settings, autoRoomCode); |
| return; |
| } |
| |
| renderLayout(t('receiveTitle'), ` |
| <div class="card center"> |
| <div class="tile-icon" style="margin:0 auto 16px;background:var(--green-soft-bg);color:var(--green)">${icons.hash}</div> |
| <p class="muted">${t('receiveHint')}</p> |
| <input id="roomInput" type="text" value="${autoRoomCode}" placeholder="XXXXXX" maxlength="6" autocomplete="one-time-code" /> |
| <button class="button green" id="join">${t('connectButton')}</button> |
| <button type="button" class="small-button" id="scanQr">${t('scanQrButton')}</button> |
| <div id="status" class="notice">${t('waitingCodeInputStatus')}</div> |
| <div id="connPath" class="tiny"></div> |
| <div id="folderShareBanner" class="hidden"></div> |
| <div class="hidden qr-scanner" id="qrScanner"> |
| <video id="qrVideo" playsinline muted></video> |
| <p class="tiny">${t('scannerHint')}</p> |
| <button type="button" class="small-button" id="closeScanner">${t('closeScannerButton')}</button> |
| </div> |
| </div> |
| <div id="fileBrowser" class="hidden"></div> |
| <div class="card hidden" id="aggregate"></div> |
| <div class="files" id="files"></div>`); |
| |
| const input = $('#roomInput'); |
| input.oninput = () => { input.value = input.value.toUpperCase().replace(/[^A-Z0-9]/g, '').slice(0, 6); }; |
| input.onkeydown = (event) => { if (event.key === 'Enter') joinRoom(settings); }; |
| $('#join').onclick = () => joinRoom(settings); |
| $('#scanQr').onclick = () => startQrScanner((code) => { |
| input.value = code; |
| joinRoom(settings); |
| }); |
| $('#closeScanner').onclick = stopQrScanner; |
| if (autoRoomCode) joinRoom(settings, autoRoomCode); |
| } |
| |
| async function sendDirectInvite(settings, peer, roomCode) { |
| const direct = new LocalSignaling({ roomCode: peer.id, role: 'sender', signalUrl: settings.signalUrl, onSignal: () => {} }); |
| await direct.connect(); |
| direct.send('direct-invite', { roomCode, from: localPeerInfo() }); |
| setTimeout(() => direct.close(), 1200); |
| } |
| |
| async function startDeviceListener(settings) { |
| if (!settings.remember) return; |
| try { |
| deviceListener = new LocalSignaling({ |
| roomCode: settings.deviceId, |
| role: 'device', |
| signalUrl: settings.signalUrl, |
| onSignal: (type, payload) => { |
| if (type !== 'direct-invite' || !payload?.roomCode) return; |
| document.querySelector('.invite-overlay')?.remove(); |
| if (loadSettings().autoAccept) { |
| if (payload.from) savePeer(payload.from); |
| renderReceive(loadSettings(), payload.roomCode, payload.from?.deviceName || t('unknownDevice')); |
| return; |
| } |
| showIncomingInvite(payload); |
| } |
| }); |
| await deviceListener.connect(); |
| } catch (error) { |
| console.warn('Device listener error:', error); |
| } |
| } |
| |
| function showIncomingInvite(payload) { |
| const name = payload.from?.deviceName || t('unknownDevice'); |
| const overlay = document.createElement('div'); |
| overlay.className = 'invite-overlay'; |
| overlay.innerHTML = ` |
| <div class="invite-card"> |
| <div class="tile-icon" style="margin:0 auto 16px;background:var(--accent-soft-bg);color:var(--accent)">${icons.down}</div> |
| <h3>${t('incomingTransferTitle')}</h3> |
| <p class="muted">${t('incomingTransferDesc', { name: escapeHtml(name) })}</p> |
| <div class="invite-actions"> |
| <button class="button green" id="acceptInvite">${t('connectButton')}</button> |
| <button class="small-button" id="declineInvite">${t('declineButton')}</button> |
| </div> |
| </div>`; |
| document.body.appendChild(overlay); |
| $('#acceptInvite', overlay).onclick = () => { |
| overlay.remove(); |
| if (payload.from) savePeer(payload.from); |
| renderReceive(loadSettings(), payload.roomCode, name); |
| }; |
| $('#declineInvite', overlay).onclick = () => overlay.remove(); |
| } |
| |
| async function joinRoom(settings, forcedRoomCode = '') { |
| const roomCode = (forcedRoomCode || $('#roomInput').value).trim().toUpperCase(); |
| if (roomCode.length !== 6) { |
| showStatus(t('codeErrorStatus'), 'error-box'); |
| return; |
| } |
| |
| try { |
| setConnectionState('signaling'); |
| signaling = new LocalSignaling({ roomCode, role: 'receiver', signalUrl: settings.signalUrl, onSignal: handleSignal }); |
| const mode = await signaling.connect(); |
| signaling.send('receiver-ready', {}); |
| showStatus(mode === 'network' ? t('roomFoundStatus') : t('localModeReceiveStatus')); |
| } catch (error) { |
| setConnectionState('error'); |
| showStatus(error.message, 'error-box'); |
| } |
| } |
| |
| function addFiles(fileList) { |
| queued.push(...Array.from(fileList || []).map((file) => ({ |
| id: crypto.randomUUID(), |
| file, |
| name: file.name, |
| size: file.size, |
| type: file.type, |
| transferred: 0, |
| status: 'queued' |
| }))); |
| renderQueue(); |
| } |
| |
| function renderQueue() { |
| const queue = $('#queue'); |
| if (!queue) return; |
| queue.innerHTML = queued.map((file) => ` |
| <div class="file-row"> |
| <div class="file-main"><div class="file-name">${file.name}</div><div class="tiny">${formatBytes(file.size)}</div></div> |
| <button class="remove" data-id="${file.id}">×</button> |
| </div>`).join(''); |
| queue.querySelectorAll('.remove').forEach((button) => { |
| button.onclick = () => { |
| queued = queued.filter((file) => file.id !== button.dataset.id); |
| renderQueue(); |
| }; |
| }); |
| } |
| |
| function waitForBufferedAmountLow(dataChannel, threshold = 8 * 1024 * 1024) { |
| if (dataChannel.bufferedAmount <= threshold) return Promise.resolve(); |
| return new Promise((resolve) => { |
| dataChannel.bufferedAmountLowThreshold = threshold; |
| const onLow = () => { |
| dataChannel.removeEventListener('bufferedamountlow', onLow); |
| resolve(); |
| }; |
| dataChannel.addEventListener('bufferedamountlow', onLow); |
| }); |
| } |
| |
| async function sendFiles() { |
| const activePeers = [...senderPeers.values()].filter((peer) => peer.state === 'connected' && peer.channel?.readyState === 'open'); |
| if (!activePeers.length || !queued.length) return; |
| |
| $('#sendFiles').disabled = true; |
| const totalBytesPerReceiver = queued.reduce((sum, file) => sum + file.size, 0); |
| activePeers.forEach((peer) => peer.channel.send(JSON.stringify({ kind: 'batch-meta', totalFiles: queued.length, totalBytes: totalBytesPerReceiver }))); |
| |
| aggregateState = { totalBytes: totalBytesPerReceiver * activePeers.length, sentBytes: 0, startTime: Date.now() }; |
| renderAggregateProgress(); |
| |
| for (const file of queued) { |
| transfers.set(file.id, { ...file, status: 'transferring' }); |
| renderTransfers(false); |
| |
| |
| |
| const wholeBuffer = file.size <= WHOLE_FILE_READ_LIMIT ? await file.file.arrayBuffer() : null; |
| |
| await Promise.all(activePeers.map(async (peer) => { |
| peer.channel.send(JSON.stringify({ kind: 'meta', id: file.id, name: file.name, size: file.size, type: file.type })); |
| const channels = peer.channels && peer.channels.length ? peer.channels : [peer.channel]; |
| await Promise.all(channels.map(async (ch, channelIndex) => { |
| for (let offset = channelIndex * CHUNK_SIZE; offset < file.size; offset += CHUNK_SIZE * channels.length) { |
| await waitForBufferedAmountLow(ch); |
| const rawChunk = wholeBuffer |
| ? wholeBuffer.slice(offset, offset + CHUNK_SIZE) |
| : await file.file.slice(offset, offset + CHUNK_SIZE).arrayBuffer(); |
| ch.send(packChunk(file.id, offset, rawChunk)); |
| aggregateState.sentBytes += rawChunk.byteLength; |
| throttledRenderAggregateProgress(); |
| } |
| })); |
| peer.channel.send(JSON.stringify({ kind: 'done', id: file.id })); |
| })); |
| |
| transfers.get(file.id).status = 'done'; |
| transfers.get(file.id).transferred = file.size; |
| renderTransfers(false); |
| } |
| |
| renderAggregateProgress(); |
| updateSendButtonState(); |
| notifyTransferComplete('notifyTransferSentBody'); |
| } |
| |
| |
| |
| |
| |
| function renderFolderShareBanner() { |
| const banner = $('#folderShareBanner'); |
| if (!banner || !sharedFolderName) return; |
| banner.classList.remove('hidden'); |
| banner.innerHTML = ` |
| <div class="card folder-banner"> |
| <p class="tiny">${t('folderSharedBanner', { name: escapeHtml(sharedFolderName) })}</p> |
| <button type="button" class="small-button" id="openBrowser">${t('openBrowserButton')}</button> |
| </div>`; |
| $('#openBrowser').onclick = () => { |
| browseState = { path: [], entries: [], loading: true }; |
| renderFileBrowser(); |
| sendControl({ kind: 'browse-request', path: [] }); |
| }; |
| } |
| |
| function renderFileBrowser() { |
| const container = $('#fileBrowser'); |
| if (!container || !browseState) return; |
| container.classList.remove('hidden'); |
| |
| const crumbs = [t('rootFolderLabel'), ...browseState.path]; |
| const breadcrumb = crumbs.map((label, index) => `<button type="button" class="crumb" data-depth="${index}">${escapeHtml(label)}</button>`).join('<span class="crumb-sep">/</span>'); |
| |
| const rows = browseState.error |
| ? `<p class="tiny">${t('browseErrorLabel')}</p>` |
| : (!browseState.entries.length |
| ? `<p class="tiny">${t('emptyFolderLabel')}</p>` |
| : browseState.entries.map((entry) => { |
| const pathKey = [...browseState.path, entry.name].join('/'); |
| if (entry.kind === 'directory') { |
| return `<button type="button" class="browser-row" data-open="${escapeHtml(pathKey)}"><span>📁 ${escapeHtml(entry.name)}</span></button>`; |
| } |
| const checked = selectedBrowsePicks.has(pathKey) ? 'checked' : ''; |
| return ` |
| <label class="browser-row"> |
| <input type="checkbox" data-pick="${escapeHtml(pathKey)}" ${checked} /> |
| <span>${escapeHtml(entry.name)}</span> |
| <span class="tiny browser-size">${formatBytes(entry.size)}</span> |
| </label>`; |
| }).join('')); |
| |
| container.innerHTML = ` |
| <div class="card"> |
| <div class="breadcrumb">${breadcrumb}</div> |
| <div class="browser-list">${rows}</div> |
| <button type="button" class="button green" id="downloadPicked" ${selectedBrowsePicks.size ? '' : 'disabled'}>${t('downloadPickedButton')}${selectedBrowsePicks.size ? ` (${selectedBrowsePicks.size})` : ''}</button> |
| </div>`; |
| |
| container.querySelectorAll('[data-open]').forEach((row) => { |
| row.onclick = () => { |
| const path = row.dataset.open.split('/'); |
| browseState = { path, entries: [], loading: true }; |
| renderFileBrowser(); |
| sendControl({ kind: 'browse-request', path }); |
| }; |
| }); |
| |
| container.querySelectorAll('.crumb').forEach((crumb) => { |
| crumb.onclick = () => { |
| const depth = Number(crumb.dataset.depth); |
| const path = browseState.path.slice(0, depth); |
| browseState = { path, entries: [], loading: true }; |
| renderFileBrowser(); |
| sendControl({ kind: 'browse-request', path }); |
| }; |
| }); |
| |
| container.querySelectorAll('[data-pick]').forEach((checkbox) => { |
| checkbox.onchange = () => { |
| if (checkbox.checked) selectedBrowsePicks.add(checkbox.dataset.pick); |
| else selectedBrowsePicks.delete(checkbox.dataset.pick); |
| renderFileBrowser(); |
| }; |
| }); |
| |
| const downloadButton = $('#downloadPicked'); |
| if (downloadButton) { |
| downloadButton.onclick = () => { |
| selectedBrowsePicks.forEach((pathKey) => { |
| const pathSegments = pathKey.split('/'); |
| const requestId = crypto.randomUUID(); |
| transfers.set(requestId, { id: requestId, name: pathSegments[pathSegments.length - 1], size: 0, transferred: 0, status: 'transferring' }); |
| sendControl({ kind: 'file-request', path: pathSegments, id: requestId }); |
| }); |
| selectedBrowsePicks.clear(); |
| renderTransfers(true); |
| renderFileBrowser(); |
| }; |
| } |
| } |
| |
| function renderTransfers(showDownloads = true) { |
| const files = $('#files'); |
| if (!files) return; |
| files.innerHTML = [...transfers.values()].map((file) => { |
| const percent = file.size ? Math.round((file.transferred / file.size) * 100) : 100; |
| const statusLabel = file.status === 'done' ? t('doneStatusText') : file.status === 'error' ? t('browseErrorLabel') : `${percent}%`; |
| return ` |
| <div class="file-row ${file.status === 'done' ? 'done' : ''} ${file.status === 'error' ? 'error' : ''}"> |
| <div class="file-main"> |
| <div class="file-name">${file.name}</div> |
| <div class="tiny">${formatBytes(file.size)}</div> |
| <div class="progress"><div class="bar" style="width:${percent}%"></div></div> |
| <div class="status-text">${statusLabel}</div> |
| </div> |
| ${showDownloads && file.url ? `<a class="download" href="${file.url}" download="${file.name}">${t('downloadLink')}</a>` : ''} |
| </div>`; |
| }).join(''); |
| } |
| |
| const throttledRenderTransfers = throttle(() => renderTransfers(true), 150); |
| |
| function handleDataMessage(data) { |
| if (typeof data === 'string') { |
| const message = JSON.parse(data); |
| |
| if (message.kind === 'peer-info') { |
| savePeer(message); |
| if (currentRole === 'receiver' && message.deviceName) { |
| showStatus(t('connectedToStatus', { name: message.deviceName }), 'notice'); |
| } |
| return; |
| } |
| |
| if (message.kind === 'folder-shared') { |
| sharedFolderName = message.name; |
| renderFolderShareBanner(); |
| return; |
| } |
| |
| if (message.kind === 'browse-response') { |
| browseState = { path: message.path || [], entries: message.entries || [], error: message.error || null }; |
| renderFileBrowser(); |
| return; |
| } |
| |
| if (message.kind === 'file-error') { |
| const transfer = transfers.get(message.id); |
| if (transfer) { transfer.status = 'error'; renderTransfers(true); } |
| return; |
| } |
| |
| if (message.kind === 'batch-meta') { |
| aggregateState = { totalBytes: message.totalBytes, sentBytes: 0, startTime: Date.now(), totalFiles: message.totalFiles, filesDone: 0 }; |
| renderAggregateProgress(); |
| return; |
| } |
| |
| if (message.kind === 'meta') { |
| receiveBuffers.set(message.id, { ...message, buffer: new Uint8Array(message.size), received: 0, doneSignaled: false }); |
| transfers.set(message.id, { id: message.id, name: message.name, size: message.size, type: message.type, transferred: 0, status: 'transferring' }); |
| renderTransfers(true); |
| } |
| |
| if (message.kind === 'done') { |
| const received = receiveBuffers.get(message.id); |
| if (!received) return; |
| received.doneSignaled = true; |
| if (received.received >= received.size) finalizeReceivedFile(message.id); |
| } |
| |
| return; |
| } |
| |
| const { id, offset, data: payload } = unpackChunk(data); |
| const received = receiveBuffers.get(id); |
| if (!received) return; |
| received.buffer.set(new Uint8Array(payload), offset); |
| received.received += payload.byteLength; |
| const transfer = transfers.get(id); |
| if (transfer) transfer.transferred = Math.min(received.received, received.size); |
| throttledRenderTransfers(); |
| if (aggregateState) { |
| aggregateState.sentBytes += payload.byteLength; |
| throttledRenderAggregateProgress(); |
| } |
| if (received.doneSignaled && received.received >= received.size) finalizeReceivedFile(id); |
| } |
| |
| function finalizeReceivedFile(id) { |
| const received = receiveBuffers.get(id); |
| if (!received || received.finalized) return; |
| received.finalized = true; |
| const blob = new Blob([received.buffer], { type: received.type || 'application/octet-stream' }); |
| const url = URL.createObjectURL(blob); |
| transfers.set(id, { ...transfers.get(id), transferred: received.size, status: 'done', url }); |
| renderTransfers(true); |
| if (loadSettings().autoDownload) { |
| const link = document.createElement('a'); |
| link.href = url; |
| link.download = received.name; |
| link.click(); |
| } |
| if (aggregateState) { |
| aggregateState.filesDone = (aggregateState.filesDone || 0) + 1; |
| renderAggregateProgress(); |
| if (aggregateState.totalFiles && aggregateState.filesDone >= aggregateState.totalFiles) { |
| notifyTransferComplete('notifyTransferReceivedBody'); |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| if ('serviceWorker' in navigator && location.protocol !== 'file:') { |
| window.addEventListener('load', () => { |
| navigator.serviceWorker.register('sw.js').catch(() => {}); |
| }); |
| } |
| |
| |
| |
| const deepLinkCode = new URLSearchParams(location.search).get('code'); |
| if (deepLinkCode && /^[A-Z0-9]{6}$/i.test(deepLinkCode)) { |
| renderReceive(loadSettings(), deepLinkCode.toUpperCase()); |
| } else { |
| renderHome(); |
| } |
| |
| </script> |
| </body> |
| </html> |
|
|