toyon 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -46
- package/bin/toyon.js +57 -13
- package/dist/bridge.js +1 -1
- package/dist/cli.js +1908 -71
- package/dist/daemon.js +6491 -4820
- package/dist/shell/assets/{Editor-D-PlbMSY.js → Editor-CgKsVXHS.js} +189 -179
- package/dist/shell/assets/{XTerm-CM_FJEwN.js → XTerm-CMRoVDAh.js} +1 -1
- package/dist/shell/assets/cssMode-Dg15kh0f.js +1 -0
- package/dist/shell/assets/{freemarker2-DVAK5zoJ.js → freemarker2-CU21n-BA.js} +2 -2
- package/dist/shell/assets/grammar-DGBFIuP2.js +12 -0
- package/dist/shell/assets/handlebars-DVAbWe34.js +1 -0
- package/dist/shell/assets/html-BkxU7kNX.js +1 -0
- package/dist/shell/assets/htmlMode-Brl4kLPo.js +1 -0
- package/dist/shell/assets/index-DUmxVabc.css +1 -0
- package/dist/shell/assets/index-WHwsRrlj.js +232 -0
- package/dist/shell/assets/javascript-DoIo3Pg8.js +1 -0
- package/dist/shell/assets/{jsonMode-HgW1GXQH.js → jsonMode-B9qq6lCy.js} +1 -1
- package/dist/shell/assets/liquid-Cn1aqWby.js +1 -0
- package/dist/shell/assets/{lspLanguageFeatures-CvNG6b_1.js → lspLanguageFeatures-C5ez8E_9.js} +1 -1
- package/dist/shell/assets/mdx-1MuVz0xd.js +1 -0
- package/dist/shell/assets/python-DFhVdcGk.js +1 -0
- package/dist/shell/assets/razor-BitqUXpg.js +1 -0
- package/dist/shell/assets/tsMode-loK_YDOL.js +1 -0
- package/dist/shell/assets/wasm-inlined-CG6Dc4jp.js +1 -0
- package/dist/shell/assets/xml-Cc4ljERX.js +1 -0
- package/dist/shell/assets/yaml-0hpVC8PU.js +1 -0
- package/dist/shell/index.html +35 -4
- package/dist/shell/manifest.json +1 -1
- package/package.json +2 -2
- package/dist/shell/assets/cssMode-Bkqyr9Lr.js +0 -1
- package/dist/shell/assets/handlebars-Bdtj7uMl.js +0 -1
- package/dist/shell/assets/html-B1pqTvyA.js +0 -1
- package/dist/shell/assets/htmlMode-CBtvzewS.js +0 -1
- package/dist/shell/assets/index-GBQLHG7z.css +0 -1
- package/dist/shell/assets/index-jy_zeFGs.js +0 -230
- package/dist/shell/assets/javascript-FNavUzsm.js +0 -1
- package/dist/shell/assets/liquid-6wkVlojW.js +0 -1
- package/dist/shell/assets/mdx-C-byKky3.js +0 -1
- package/dist/shell/assets/python-BEJMbP4i.js +0 -1
- package/dist/shell/assets/razor-DeXWW25R.js +0 -1
- package/dist/shell/assets/tsMode-DMwJnvD-.js +0 -11
- package/dist/shell/assets/typescript-Cj57ccSp.js +0 -1
- package/dist/shell/assets/workers-BZi9jqBp.js +0 -1
- package/dist/shell/assets/xml-DUDeQI0I.js +0 -1
- package/dist/shell/assets/yaml-BCD8Shg5.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -3,75 +3,14 @@
|
|
|
3
3
|
|
|
4
4
|
// src/cli.ts
|
|
5
5
|
import { existsSync as existsSync10 } from "fs";
|
|
6
|
-
import { join as
|
|
7
|
-
// package.json
|
|
8
|
-
var package_default = {
|
|
9
|
-
name: "toyon",
|
|
10
|
-
version: "0.2.0",
|
|
11
|
-
description: "Checking an agent's work means running it. Toyon gives every chat its own copy of your web app, with a live preview.",
|
|
12
|
-
license: "MIT",
|
|
13
|
-
type: "module",
|
|
14
|
-
homepage: "https://toyon.dev",
|
|
15
|
-
repository: {
|
|
16
|
-
type: "git",
|
|
17
|
-
url: "git+https://github.com/toyon-dev/toyon.git"
|
|
18
|
-
},
|
|
19
|
-
bugs: "https://github.com/toyon-dev/toyon/issues",
|
|
20
|
-
keywords: [
|
|
21
|
-
"ai",
|
|
22
|
-
"agents",
|
|
23
|
-
"claude-code",
|
|
24
|
-
"codex",
|
|
25
|
-
"opencode",
|
|
26
|
-
"git",
|
|
27
|
-
"worktree",
|
|
28
|
-
"preview",
|
|
29
|
-
"dev-server"
|
|
30
|
-
],
|
|
31
|
-
bin: {
|
|
32
|
-
toyon: "bin/toyon.js"
|
|
33
|
-
},
|
|
34
|
-
files: [
|
|
35
|
-
"bin",
|
|
36
|
-
"dist",
|
|
37
|
-
"cloud"
|
|
38
|
-
],
|
|
39
|
-
engines: {
|
|
40
|
-
node: ">=18"
|
|
41
|
-
},
|
|
42
|
-
os: [
|
|
43
|
-
"darwin",
|
|
44
|
-
"linux"
|
|
45
|
-
],
|
|
46
|
-
scripts: {
|
|
47
|
-
prepublishOnly: "bun ../../scripts/pack.ts"
|
|
48
|
-
},
|
|
49
|
-
dependencies: {
|
|
50
|
-
bun: "1.4.2",
|
|
51
|
-
"bun-pty": "0.4.10"
|
|
52
|
-
},
|
|
53
|
-
devDependencies: {
|
|
54
|
-
"@toyon/shared": "workspace:*"
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// src/app.ts
|
|
59
|
-
import { spawn as spawn2, spawnSync } from "child_process";
|
|
60
|
-
import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync2, rmSync, writeFileSync } from "fs";
|
|
61
|
-
import { homedir as homedir2 } from "os";
|
|
62
|
-
import { join as join3 } from "path";
|
|
63
|
-
|
|
64
|
-
// src/daemon.ts
|
|
65
|
-
import { spawn } from "child_process";
|
|
66
|
-
import { existsSync as existsSync2, mkdirSync, openSync, readFileSync } from "fs";
|
|
67
|
-
import { homedir } from "os";
|
|
68
|
-
import { join as join2 } from "path";
|
|
6
|
+
import { join as join8, resolve } from "path";
|
|
69
7
|
|
|
70
8
|
// ../shared/src/daemon.ts
|
|
71
9
|
var DAEMON_FILES = {
|
|
72
10
|
token: "token",
|
|
73
11
|
pid: "daemon.pid",
|
|
74
12
|
state: "state.json",
|
|
13
|
+
drafts: "drafts.json",
|
|
75
14
|
log: "daemon.log",
|
|
76
15
|
remote: "remote.json"
|
|
77
16
|
};
|
|
@@ -153,6 +92,114 @@ function bwrapBlockedAdvice(error, restricted) {
|
|
|
153
92
|
`);
|
|
154
93
|
}
|
|
155
94
|
|
|
95
|
+
// ../shared/src/update.ts
|
|
96
|
+
function installMethod(packageJson) {
|
|
97
|
+
if (!packageJson)
|
|
98
|
+
return "none";
|
|
99
|
+
const p = packageJson.replaceAll("\\", "/");
|
|
100
|
+
if (p.includes("/_npx/"))
|
|
101
|
+
return "npx";
|
|
102
|
+
if (p.includes("/.bun/install/global/"))
|
|
103
|
+
return "bun";
|
|
104
|
+
if (p.includes("/node_modules/toyon/"))
|
|
105
|
+
return "npm";
|
|
106
|
+
return "none";
|
|
107
|
+
}
|
|
108
|
+
function installCommand(method, version) {
|
|
109
|
+
if (method === "npm")
|
|
110
|
+
return ["npm", "install", "-g", `toyon@${version}`];
|
|
111
|
+
if (method === "bun")
|
|
112
|
+
return ["bun", "add", "-g", `toyon@${version}`];
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
function newer(a, b) {
|
|
116
|
+
const pa = parseVersion(a);
|
|
117
|
+
const pb = parseVersion(b);
|
|
118
|
+
if (!pa || !pb)
|
|
119
|
+
return false;
|
|
120
|
+
for (let i = 0;i < 3; i++) {
|
|
121
|
+
const x = pa.nums[i] ?? 0;
|
|
122
|
+
const y = pb.nums[i] ?? 0;
|
|
123
|
+
if (x !== y)
|
|
124
|
+
return x > y;
|
|
125
|
+
}
|
|
126
|
+
if (pa.pre === pb.pre)
|
|
127
|
+
return false;
|
|
128
|
+
if (pa.pre === null)
|
|
129
|
+
return true;
|
|
130
|
+
if (pb.pre === null)
|
|
131
|
+
return false;
|
|
132
|
+
return pa.pre > pb.pre;
|
|
133
|
+
}
|
|
134
|
+
function parseVersion(v) {
|
|
135
|
+
const m = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/.exec(v.trim());
|
|
136
|
+
if (!m)
|
|
137
|
+
return null;
|
|
138
|
+
return { nums: [Number(m[1]), Number(m[2]), Number(m[3])], pre: m[4] ?? null };
|
|
139
|
+
}
|
|
140
|
+
// package.json
|
|
141
|
+
var package_default = {
|
|
142
|
+
name: "toyon",
|
|
143
|
+
version: "0.4.0",
|
|
144
|
+
description: "Toyon is where coding agents work on your web app while you check each change by using it. Every chat gets its own running copy with a live preview.",
|
|
145
|
+
license: "MIT",
|
|
146
|
+
type: "module",
|
|
147
|
+
homepage: "https://toyon.dev",
|
|
148
|
+
repository: {
|
|
149
|
+
type: "git",
|
|
150
|
+
url: "git+https://github.com/toyon-dev/toyon.git"
|
|
151
|
+
},
|
|
152
|
+
bugs: "https://github.com/toyon-dev/toyon/issues",
|
|
153
|
+
keywords: [
|
|
154
|
+
"ai",
|
|
155
|
+
"agents",
|
|
156
|
+
"claude-code",
|
|
157
|
+
"codex",
|
|
158
|
+
"opencode",
|
|
159
|
+
"git",
|
|
160
|
+
"worktree",
|
|
161
|
+
"preview",
|
|
162
|
+
"dev-server"
|
|
163
|
+
],
|
|
164
|
+
bin: {
|
|
165
|
+
toyon: "bin/toyon.js"
|
|
166
|
+
},
|
|
167
|
+
files: [
|
|
168
|
+
"bin",
|
|
169
|
+
"dist",
|
|
170
|
+
"cloud"
|
|
171
|
+
],
|
|
172
|
+
engines: {
|
|
173
|
+
node: ">=18"
|
|
174
|
+
},
|
|
175
|
+
os: [
|
|
176
|
+
"darwin",
|
|
177
|
+
"linux"
|
|
178
|
+
],
|
|
179
|
+
scripts: {
|
|
180
|
+
prepublishOnly: "bun ../../scripts/pack.ts"
|
|
181
|
+
},
|
|
182
|
+
dependencies: {
|
|
183
|
+
bun: "1.4.2",
|
|
184
|
+
"bun-pty": "0.4.10"
|
|
185
|
+
},
|
|
186
|
+
devDependencies: {
|
|
187
|
+
"@toyon/shared": "workspace:*"
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// src/app.ts
|
|
192
|
+
import { spawn as spawn2, spawnSync } from "child_process";
|
|
193
|
+
import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync2, rmSync, writeFileSync } from "fs";
|
|
194
|
+
import { homedir as homedir2 } from "os";
|
|
195
|
+
import { join as join3 } from "path";
|
|
196
|
+
|
|
197
|
+
// src/daemon.ts
|
|
198
|
+
import { spawn } from "child_process";
|
|
199
|
+
import { existsSync as existsSync2, mkdirSync, openSync, readFileSync } from "fs";
|
|
200
|
+
import { homedir } from "os";
|
|
201
|
+
import { join as join2 } from "path";
|
|
202
|
+
|
|
156
203
|
// src/layout.ts
|
|
157
204
|
import { existsSync } from "fs";
|
|
158
205
|
import { dirname, join } from "path";
|
|
@@ -404,7 +451,19 @@ exec /bin/bash "$(dirname "$0")/../Resources/launch.sh"
|
|
|
404
451
|
}
|
|
405
452
|
|
|
406
453
|
// src/args.ts
|
|
407
|
-
var VERBS = new Set([
|
|
454
|
+
var VERBS = new Set([
|
|
455
|
+
"stop",
|
|
456
|
+
"restart",
|
|
457
|
+
"update",
|
|
458
|
+
"doctor",
|
|
459
|
+
"logs",
|
|
460
|
+
"version",
|
|
461
|
+
"uninstall",
|
|
462
|
+
"remote",
|
|
463
|
+
"pair",
|
|
464
|
+
"deploy",
|
|
465
|
+
"help"
|
|
466
|
+
]);
|
|
408
467
|
var DEFAULT_LOG_LINES = 100;
|
|
409
468
|
function parseArgs(argv) {
|
|
410
469
|
if (argv.includes("--help") || argv.includes("-h"))
|
|
@@ -416,8 +475,10 @@ function parseArgs(argv) {
|
|
|
416
475
|
switch (first) {
|
|
417
476
|
case "stop":
|
|
418
477
|
case "restart":
|
|
478
|
+
case "update":
|
|
419
479
|
case "doctor":
|
|
420
480
|
case "version":
|
|
481
|
+
case "pair":
|
|
421
482
|
case "help":
|
|
422
483
|
if (rest.length > 0)
|
|
423
484
|
return { kind: "error", message: `toyon ${first} takes no arguments` };
|
|
@@ -544,8 +605,10 @@ usage
|
|
|
544
605
|
toyon [path] start the daemon if it is not running, register the repo at path
|
|
545
606
|
(default: the current directory) and open the shell
|
|
546
607
|
toyon stop stop the daemon and every dev server and agent it runs
|
|
547
|
-
toyon restart stop the daemon and start it again
|
|
548
|
-
|
|
608
|
+
toyon restart stop the daemon and start it again from what is installed now; every
|
|
609
|
+
shell reconnects on its own
|
|
610
|
+
toyon update install the newest Toyon the way this one was installed, then restart
|
|
611
|
+
the daemon onto it once no chat is mid-reply
|
|
549
612
|
toyon doctor check the daemon, the token, the shell build and the tools Toyon needs
|
|
550
613
|
toyon logs [-f] [-n N] print the daemon log; -f keeps following it, -n sets how many lines
|
|
551
614
|
toyon version print the CLI version, and the daemon's if one is running
|
|
@@ -559,6 +622,9 @@ usage
|
|
|
559
622
|
toyon remote --tailscale
|
|
560
623
|
open the shell from your tailnet at this machine's Tailscale name:
|
|
561
624
|
sets up tailscale serve for Toyon and ports 10001-10008
|
|
625
|
+
toyon pair print a QR code to scan with your phone's camera: it opens the shell
|
|
626
|
+
at the remote name, signed in, and adds it to toyon.cloud; the code
|
|
627
|
+
works once and lasts 2 minutes
|
|
562
628
|
toyon deploy fly up <name> [--region code] [--repo url]
|
|
563
629
|
run Toyon on your own Fly account at https://name.fly.dev with your own
|
|
564
630
|
keys; --repo clones that repository onto it the first time
|
|
@@ -574,6 +640,7 @@ options for toyon [path]
|
|
|
574
640
|
environment
|
|
575
641
|
TOYON_HOME where state lives (default ~/.toyon)
|
|
576
642
|
TOYON_PORT the daemon's port (default 4141)
|
|
643
|
+
TOYON_UPDATES off stops Toyon checking for and installing updates on this machine
|
|
577
644
|
`;
|
|
578
645
|
|
|
579
646
|
// src/deploy/fly.ts
|
|
@@ -977,7 +1044,12 @@ async function doctor() {
|
|
|
977
1044
|
lines.push(line(true, "running", `${running} of ${total} worktrees started; the rest start when opened`));
|
|
978
1045
|
}
|
|
979
1046
|
if (version !== package_default.version) {
|
|
980
|
-
lines.push(line(false, "version", `cli is ${package_default.version} and the daemon is ${version}; \`toyon
|
|
1047
|
+
lines.push(line(false, "version", `cli is ${package_default.version} and the daemon is ${version}; \`toyon restart\` brings them level`));
|
|
1048
|
+
}
|
|
1049
|
+
if (h.updates?.managed) {
|
|
1050
|
+
lines.push(line(true, "updates", "off for this machine (TOYON_UPDATES=off)"));
|
|
1051
|
+
} else if (h.updates?.unreachable) {
|
|
1052
|
+
lines.push(line(false, "updates", `npm could not get toyon from ${h.updates.unreachable}, so Toyon cannot update itself; if you may use the public registry, run npm install -g toyon --registry=https://registry.npmjs.org/`));
|
|
981
1053
|
}
|
|
982
1054
|
}
|
|
983
1055
|
const token = readToken();
|
|
@@ -1045,6 +1117,1666 @@ async function logs(opts) {
|
|
|
1045
1117
|
}
|
|
1046
1118
|
}
|
|
1047
1119
|
|
|
1120
|
+
// ../../node_modules/.bun/qrcode-generator@2.0.4/node_modules/qrcode-generator/dist/qrcode.mjs
|
|
1121
|
+
var qrcode = function(typeNumber, errorCorrectionLevel) {
|
|
1122
|
+
const PAD0 = 236;
|
|
1123
|
+
const PAD1 = 17;
|
|
1124
|
+
let _typeNumber = typeNumber;
|
|
1125
|
+
const _errorCorrectionLevel = QRErrorCorrectionLevel[errorCorrectionLevel];
|
|
1126
|
+
let _modules = null;
|
|
1127
|
+
let _moduleCount = 0;
|
|
1128
|
+
let _dataCache = null;
|
|
1129
|
+
const _dataList = [];
|
|
1130
|
+
const _this = {};
|
|
1131
|
+
const makeImpl = function(test, maskPattern) {
|
|
1132
|
+
_moduleCount = _typeNumber * 4 + 17;
|
|
1133
|
+
_modules = function(moduleCount) {
|
|
1134
|
+
const modules = new Array(moduleCount);
|
|
1135
|
+
for (let row = 0;row < moduleCount; row += 1) {
|
|
1136
|
+
modules[row] = new Array(moduleCount);
|
|
1137
|
+
for (let col = 0;col < moduleCount; col += 1) {
|
|
1138
|
+
modules[row][col] = null;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
return modules;
|
|
1142
|
+
}(_moduleCount);
|
|
1143
|
+
setupPositionProbePattern(0, 0);
|
|
1144
|
+
setupPositionProbePattern(_moduleCount - 7, 0);
|
|
1145
|
+
setupPositionProbePattern(0, _moduleCount - 7);
|
|
1146
|
+
setupPositionAdjustPattern();
|
|
1147
|
+
setupTimingPattern();
|
|
1148
|
+
setupTypeInfo(test, maskPattern);
|
|
1149
|
+
if (_typeNumber >= 7) {
|
|
1150
|
+
setupTypeNumber(test);
|
|
1151
|
+
}
|
|
1152
|
+
if (_dataCache == null) {
|
|
1153
|
+
_dataCache = createData(_typeNumber, _errorCorrectionLevel, _dataList);
|
|
1154
|
+
}
|
|
1155
|
+
mapData(_dataCache, maskPattern);
|
|
1156
|
+
};
|
|
1157
|
+
const setupPositionProbePattern = function(row, col) {
|
|
1158
|
+
for (let r = -1;r <= 7; r += 1) {
|
|
1159
|
+
if (row + r <= -1 || _moduleCount <= row + r)
|
|
1160
|
+
continue;
|
|
1161
|
+
for (let c = -1;c <= 7; c += 1) {
|
|
1162
|
+
if (col + c <= -1 || _moduleCount <= col + c)
|
|
1163
|
+
continue;
|
|
1164
|
+
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) {
|
|
1165
|
+
_modules[row + r][col + c] = true;
|
|
1166
|
+
} else {
|
|
1167
|
+
_modules[row + r][col + c] = false;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
const getBestMaskPattern = function() {
|
|
1173
|
+
let minLostPoint = 0;
|
|
1174
|
+
let pattern = 0;
|
|
1175
|
+
for (let i = 0;i < 8; i += 1) {
|
|
1176
|
+
makeImpl(true, i);
|
|
1177
|
+
const lostPoint = QRUtil.getLostPoint(_this);
|
|
1178
|
+
if (i == 0 || minLostPoint > lostPoint) {
|
|
1179
|
+
minLostPoint = lostPoint;
|
|
1180
|
+
pattern = i;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return pattern;
|
|
1184
|
+
};
|
|
1185
|
+
const setupTimingPattern = function() {
|
|
1186
|
+
for (let r = 8;r < _moduleCount - 8; r += 1) {
|
|
1187
|
+
if (_modules[r][6] != null) {
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
_modules[r][6] = r % 2 == 0;
|
|
1191
|
+
}
|
|
1192
|
+
for (let c = 8;c < _moduleCount - 8; c += 1) {
|
|
1193
|
+
if (_modules[6][c] != null) {
|
|
1194
|
+
continue;
|
|
1195
|
+
}
|
|
1196
|
+
_modules[6][c] = c % 2 == 0;
|
|
1197
|
+
}
|
|
1198
|
+
};
|
|
1199
|
+
const setupPositionAdjustPattern = function() {
|
|
1200
|
+
const pos = QRUtil.getPatternPosition(_typeNumber);
|
|
1201
|
+
for (let i = 0;i < pos.length; i += 1) {
|
|
1202
|
+
for (let j = 0;j < pos.length; j += 1) {
|
|
1203
|
+
const row = pos[i];
|
|
1204
|
+
const col = pos[j];
|
|
1205
|
+
if (_modules[row][col] != null) {
|
|
1206
|
+
continue;
|
|
1207
|
+
}
|
|
1208
|
+
for (let r = -2;r <= 2; r += 1) {
|
|
1209
|
+
for (let c = -2;c <= 2; c += 1) {
|
|
1210
|
+
if (r == -2 || r == 2 || c == -2 || c == 2 || r == 0 && c == 0) {
|
|
1211
|
+
_modules[row + r][col + c] = true;
|
|
1212
|
+
} else {
|
|
1213
|
+
_modules[row + r][col + c] = false;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
const setupTypeNumber = function(test) {
|
|
1221
|
+
const bits = QRUtil.getBCHTypeNumber(_typeNumber);
|
|
1222
|
+
for (let i = 0;i < 18; i += 1) {
|
|
1223
|
+
const mod = !test && (bits >> i & 1) == 1;
|
|
1224
|
+
_modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod;
|
|
1225
|
+
}
|
|
1226
|
+
for (let i = 0;i < 18; i += 1) {
|
|
1227
|
+
const mod = !test && (bits >> i & 1) == 1;
|
|
1228
|
+
_modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
|
|
1229
|
+
}
|
|
1230
|
+
};
|
|
1231
|
+
const setupTypeInfo = function(test, maskPattern) {
|
|
1232
|
+
const data = _errorCorrectionLevel << 3 | maskPattern;
|
|
1233
|
+
const bits = QRUtil.getBCHTypeInfo(data);
|
|
1234
|
+
for (let i = 0;i < 15; i += 1) {
|
|
1235
|
+
const mod = !test && (bits >> i & 1) == 1;
|
|
1236
|
+
if (i < 6) {
|
|
1237
|
+
_modules[i][8] = mod;
|
|
1238
|
+
} else if (i < 8) {
|
|
1239
|
+
_modules[i + 1][8] = mod;
|
|
1240
|
+
} else {
|
|
1241
|
+
_modules[_moduleCount - 15 + i][8] = mod;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
for (let i = 0;i < 15; i += 1) {
|
|
1245
|
+
const mod = !test && (bits >> i & 1) == 1;
|
|
1246
|
+
if (i < 8) {
|
|
1247
|
+
_modules[8][_moduleCount - i - 1] = mod;
|
|
1248
|
+
} else if (i < 9) {
|
|
1249
|
+
_modules[8][15 - i - 1 + 1] = mod;
|
|
1250
|
+
} else {
|
|
1251
|
+
_modules[8][15 - i - 1] = mod;
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
_modules[_moduleCount - 8][8] = !test;
|
|
1255
|
+
};
|
|
1256
|
+
const mapData = function(data, maskPattern) {
|
|
1257
|
+
let inc = -1;
|
|
1258
|
+
let row = _moduleCount - 1;
|
|
1259
|
+
let bitIndex = 7;
|
|
1260
|
+
let byteIndex = 0;
|
|
1261
|
+
const maskFunc = QRUtil.getMaskFunction(maskPattern);
|
|
1262
|
+
for (let col = _moduleCount - 1;col > 0; col -= 2) {
|
|
1263
|
+
if (col == 6)
|
|
1264
|
+
col -= 1;
|
|
1265
|
+
while (true) {
|
|
1266
|
+
for (let c = 0;c < 2; c += 1) {
|
|
1267
|
+
if (_modules[row][col - c] == null) {
|
|
1268
|
+
let dark = false;
|
|
1269
|
+
if (byteIndex < data.length) {
|
|
1270
|
+
dark = (data[byteIndex] >>> bitIndex & 1) == 1;
|
|
1271
|
+
}
|
|
1272
|
+
const mask = maskFunc(row, col - c);
|
|
1273
|
+
if (mask) {
|
|
1274
|
+
dark = !dark;
|
|
1275
|
+
}
|
|
1276
|
+
_modules[row][col - c] = dark;
|
|
1277
|
+
bitIndex -= 1;
|
|
1278
|
+
if (bitIndex == -1) {
|
|
1279
|
+
byteIndex += 1;
|
|
1280
|
+
bitIndex = 7;
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
row += inc;
|
|
1285
|
+
if (row < 0 || _moduleCount <= row) {
|
|
1286
|
+
row -= inc;
|
|
1287
|
+
inc = -inc;
|
|
1288
|
+
break;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
};
|
|
1293
|
+
const createBytes = function(buffer, rsBlocks) {
|
|
1294
|
+
let offset = 0;
|
|
1295
|
+
let maxDcCount = 0;
|
|
1296
|
+
let maxEcCount = 0;
|
|
1297
|
+
const dcdata = new Array(rsBlocks.length);
|
|
1298
|
+
const ecdata = new Array(rsBlocks.length);
|
|
1299
|
+
for (let r = 0;r < rsBlocks.length; r += 1) {
|
|
1300
|
+
const dcCount = rsBlocks[r].dataCount;
|
|
1301
|
+
const ecCount = rsBlocks[r].totalCount - dcCount;
|
|
1302
|
+
maxDcCount = Math.max(maxDcCount, dcCount);
|
|
1303
|
+
maxEcCount = Math.max(maxEcCount, ecCount);
|
|
1304
|
+
dcdata[r] = new Array(dcCount);
|
|
1305
|
+
for (let i = 0;i < dcdata[r].length; i += 1) {
|
|
1306
|
+
dcdata[r][i] = 255 & buffer.getBuffer()[i + offset];
|
|
1307
|
+
}
|
|
1308
|
+
offset += dcCount;
|
|
1309
|
+
const rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
|
|
1310
|
+
const rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1);
|
|
1311
|
+
const modPoly = rawPoly.mod(rsPoly);
|
|
1312
|
+
ecdata[r] = new Array(rsPoly.getLength() - 1);
|
|
1313
|
+
for (let i = 0;i < ecdata[r].length; i += 1) {
|
|
1314
|
+
const modIndex = i + modPoly.getLength() - ecdata[r].length;
|
|
1315
|
+
ecdata[r][i] = modIndex >= 0 ? modPoly.getAt(modIndex) : 0;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
let totalCodeCount = 0;
|
|
1319
|
+
for (let i = 0;i < rsBlocks.length; i += 1) {
|
|
1320
|
+
totalCodeCount += rsBlocks[i].totalCount;
|
|
1321
|
+
}
|
|
1322
|
+
const data = new Array(totalCodeCount);
|
|
1323
|
+
let index = 0;
|
|
1324
|
+
for (let i = 0;i < maxDcCount; i += 1) {
|
|
1325
|
+
for (let r = 0;r < rsBlocks.length; r += 1) {
|
|
1326
|
+
if (i < dcdata[r].length) {
|
|
1327
|
+
data[index] = dcdata[r][i];
|
|
1328
|
+
index += 1;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
for (let i = 0;i < maxEcCount; i += 1) {
|
|
1333
|
+
for (let r = 0;r < rsBlocks.length; r += 1) {
|
|
1334
|
+
if (i < ecdata[r].length) {
|
|
1335
|
+
data[index] = ecdata[r][i];
|
|
1336
|
+
index += 1;
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
return data;
|
|
1341
|
+
};
|
|
1342
|
+
const createData = function(typeNumber, errorCorrectionLevel, dataList) {
|
|
1343
|
+
const rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectionLevel);
|
|
1344
|
+
const buffer = qrBitBuffer();
|
|
1345
|
+
for (let i = 0;i < dataList.length; i += 1) {
|
|
1346
|
+
const data = dataList[i];
|
|
1347
|
+
buffer.put(data.getMode(), 4);
|
|
1348
|
+
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber));
|
|
1349
|
+
data.write(buffer);
|
|
1350
|
+
}
|
|
1351
|
+
let totalDataCount = 0;
|
|
1352
|
+
for (let i = 0;i < rsBlocks.length; i += 1) {
|
|
1353
|
+
totalDataCount += rsBlocks[i].dataCount;
|
|
1354
|
+
}
|
|
1355
|
+
if (buffer.getLengthInBits() > totalDataCount * 8) {
|
|
1356
|
+
throw "code length overflow. (" + buffer.getLengthInBits() + ">" + totalDataCount * 8 + ")";
|
|
1357
|
+
}
|
|
1358
|
+
if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
|
|
1359
|
+
buffer.put(0, 4);
|
|
1360
|
+
}
|
|
1361
|
+
while (buffer.getLengthInBits() % 8 != 0) {
|
|
1362
|
+
buffer.putBit(false);
|
|
1363
|
+
}
|
|
1364
|
+
while (true) {
|
|
1365
|
+
if (buffer.getLengthInBits() >= totalDataCount * 8) {
|
|
1366
|
+
break;
|
|
1367
|
+
}
|
|
1368
|
+
buffer.put(PAD0, 8);
|
|
1369
|
+
if (buffer.getLengthInBits() >= totalDataCount * 8) {
|
|
1370
|
+
break;
|
|
1371
|
+
}
|
|
1372
|
+
buffer.put(PAD1, 8);
|
|
1373
|
+
}
|
|
1374
|
+
return createBytes(buffer, rsBlocks);
|
|
1375
|
+
};
|
|
1376
|
+
_this.addData = function(data, mode) {
|
|
1377
|
+
mode = mode || "Byte";
|
|
1378
|
+
let newData = null;
|
|
1379
|
+
switch (mode) {
|
|
1380
|
+
case "Numeric":
|
|
1381
|
+
newData = qrNumber(data);
|
|
1382
|
+
break;
|
|
1383
|
+
case "Alphanumeric":
|
|
1384
|
+
newData = qrAlphaNum(data);
|
|
1385
|
+
break;
|
|
1386
|
+
case "Byte":
|
|
1387
|
+
newData = qr8BitByte(data);
|
|
1388
|
+
break;
|
|
1389
|
+
case "Kanji":
|
|
1390
|
+
newData = qrKanji(data);
|
|
1391
|
+
break;
|
|
1392
|
+
default:
|
|
1393
|
+
throw "mode:" + mode;
|
|
1394
|
+
}
|
|
1395
|
+
_dataList.push(newData);
|
|
1396
|
+
_dataCache = null;
|
|
1397
|
+
};
|
|
1398
|
+
_this.isDark = function(row, col) {
|
|
1399
|
+
if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) {
|
|
1400
|
+
throw row + "," + col;
|
|
1401
|
+
}
|
|
1402
|
+
return _modules[row][col];
|
|
1403
|
+
};
|
|
1404
|
+
_this.getModuleCount = function() {
|
|
1405
|
+
return _moduleCount;
|
|
1406
|
+
};
|
|
1407
|
+
_this.make = function() {
|
|
1408
|
+
if (_typeNumber < 1) {
|
|
1409
|
+
let typeNumber = 1;
|
|
1410
|
+
for (;typeNumber < 40; typeNumber++) {
|
|
1411
|
+
const rsBlocks = QRRSBlock.getRSBlocks(typeNumber, _errorCorrectionLevel);
|
|
1412
|
+
const buffer = qrBitBuffer();
|
|
1413
|
+
for (let i = 0;i < _dataList.length; i++) {
|
|
1414
|
+
const data = _dataList[i];
|
|
1415
|
+
buffer.put(data.getMode(), 4);
|
|
1416
|
+
buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber));
|
|
1417
|
+
data.write(buffer);
|
|
1418
|
+
}
|
|
1419
|
+
let totalDataCount = 0;
|
|
1420
|
+
for (let i = 0;i < rsBlocks.length; i++) {
|
|
1421
|
+
totalDataCount += rsBlocks[i].dataCount;
|
|
1422
|
+
}
|
|
1423
|
+
if (buffer.getLengthInBits() <= totalDataCount * 8) {
|
|
1424
|
+
break;
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
_typeNumber = typeNumber;
|
|
1428
|
+
}
|
|
1429
|
+
makeImpl(false, getBestMaskPattern());
|
|
1430
|
+
};
|
|
1431
|
+
_this.createTableTag = function(cellSize, margin) {
|
|
1432
|
+
cellSize = cellSize || 2;
|
|
1433
|
+
margin = typeof margin == "undefined" ? cellSize * 4 : margin;
|
|
1434
|
+
let qrHtml = "";
|
|
1435
|
+
qrHtml += '<table style="';
|
|
1436
|
+
qrHtml += " border-width: 0px; border-style: none;";
|
|
1437
|
+
qrHtml += " border-collapse: collapse;";
|
|
1438
|
+
qrHtml += " padding: 0px; margin: " + margin + "px;";
|
|
1439
|
+
qrHtml += '">';
|
|
1440
|
+
qrHtml += "<tbody>";
|
|
1441
|
+
for (let r = 0;r < _this.getModuleCount(); r += 1) {
|
|
1442
|
+
qrHtml += "<tr>";
|
|
1443
|
+
for (let c = 0;c < _this.getModuleCount(); c += 1) {
|
|
1444
|
+
qrHtml += '<td style="';
|
|
1445
|
+
qrHtml += " border-width: 0px; border-style: none;";
|
|
1446
|
+
qrHtml += " border-collapse: collapse;";
|
|
1447
|
+
qrHtml += " padding: 0px; margin: 0px;";
|
|
1448
|
+
qrHtml += " width: " + cellSize + "px;";
|
|
1449
|
+
qrHtml += " height: " + cellSize + "px;";
|
|
1450
|
+
qrHtml += " background-color: ";
|
|
1451
|
+
qrHtml += _this.isDark(r, c) ? "#000000" : "#ffffff";
|
|
1452
|
+
qrHtml += ";";
|
|
1453
|
+
qrHtml += '"/>';
|
|
1454
|
+
}
|
|
1455
|
+
qrHtml += "</tr>";
|
|
1456
|
+
}
|
|
1457
|
+
qrHtml += "</tbody>";
|
|
1458
|
+
qrHtml += "</table>";
|
|
1459
|
+
return qrHtml;
|
|
1460
|
+
};
|
|
1461
|
+
_this.createSvgTag = function(cellSize, margin, alt, title) {
|
|
1462
|
+
let opts = {};
|
|
1463
|
+
if (typeof arguments[0] == "object") {
|
|
1464
|
+
opts = arguments[0];
|
|
1465
|
+
cellSize = opts.cellSize;
|
|
1466
|
+
margin = opts.margin;
|
|
1467
|
+
alt = opts.alt;
|
|
1468
|
+
title = opts.title;
|
|
1469
|
+
}
|
|
1470
|
+
cellSize = cellSize || 2;
|
|
1471
|
+
margin = typeof margin == "undefined" ? cellSize * 4 : margin;
|
|
1472
|
+
alt = typeof alt === "string" ? { text: alt } : alt || {};
|
|
1473
|
+
alt.text = alt.text || null;
|
|
1474
|
+
alt.id = alt.text ? alt.id || "qrcode-description" : null;
|
|
1475
|
+
title = typeof title === "string" ? { text: title } : title || {};
|
|
1476
|
+
title.text = title.text || null;
|
|
1477
|
+
title.id = title.text ? title.id || "qrcode-title" : null;
|
|
1478
|
+
const size = _this.getModuleCount() * cellSize + margin * 2;
|
|
1479
|
+
let c, mc, r, mr, qrSvg = "", rect;
|
|
1480
|
+
rect = "l" + cellSize + ",0 0," + cellSize + " -" + cellSize + ",0 0,-" + cellSize + "z ";
|
|
1481
|
+
qrSvg += '<svg version="1.1" xmlns="http://www.w3.org/2000/svg"';
|
|
1482
|
+
qrSvg += !opts.scalable ? ' width="' + size + 'px" height="' + size + 'px"' : "";
|
|
1483
|
+
qrSvg += ' viewBox="0 0 ' + size + " " + size + '" ';
|
|
1484
|
+
qrSvg += ' preserveAspectRatio="xMinYMin meet"';
|
|
1485
|
+
qrSvg += title.text || alt.text ? ' role="img" aria-labelledby="' + escapeXml([title.id, alt.id].join(" ").trim()) + '"' : "";
|
|
1486
|
+
qrSvg += ">";
|
|
1487
|
+
qrSvg += title.text ? '<title id="' + escapeXml(title.id) + '">' + escapeXml(title.text) + "</title>" : "";
|
|
1488
|
+
qrSvg += alt.text ? '<description id="' + escapeXml(alt.id) + '">' + escapeXml(alt.text) + "</description>" : "";
|
|
1489
|
+
qrSvg += '<rect width="100%" height="100%" fill="white" cx="0" cy="0"/>';
|
|
1490
|
+
qrSvg += '<path d="';
|
|
1491
|
+
for (r = 0;r < _this.getModuleCount(); r += 1) {
|
|
1492
|
+
mr = r * cellSize + margin;
|
|
1493
|
+
for (c = 0;c < _this.getModuleCount(); c += 1) {
|
|
1494
|
+
if (_this.isDark(r, c)) {
|
|
1495
|
+
mc = c * cellSize + margin;
|
|
1496
|
+
qrSvg += "M" + mc + "," + mr + rect;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
qrSvg += '" stroke="transparent" fill="black"/>';
|
|
1501
|
+
qrSvg += "</svg>";
|
|
1502
|
+
return qrSvg;
|
|
1503
|
+
};
|
|
1504
|
+
_this.createDataURL = function(cellSize, margin) {
|
|
1505
|
+
cellSize = cellSize || 2;
|
|
1506
|
+
margin = typeof margin == "undefined" ? cellSize * 4 : margin;
|
|
1507
|
+
const size = _this.getModuleCount() * cellSize + margin * 2;
|
|
1508
|
+
const min = margin;
|
|
1509
|
+
const max = size - margin;
|
|
1510
|
+
return createDataURL(size, size, function(x, y) {
|
|
1511
|
+
if (min <= x && x < max && min <= y && y < max) {
|
|
1512
|
+
const c = Math.floor((x - min) / cellSize);
|
|
1513
|
+
const r = Math.floor((y - min) / cellSize);
|
|
1514
|
+
return _this.isDark(r, c) ? 0 : 1;
|
|
1515
|
+
} else {
|
|
1516
|
+
return 1;
|
|
1517
|
+
}
|
|
1518
|
+
});
|
|
1519
|
+
};
|
|
1520
|
+
_this.createImgTag = function(cellSize, margin, alt) {
|
|
1521
|
+
cellSize = cellSize || 2;
|
|
1522
|
+
margin = typeof margin == "undefined" ? cellSize * 4 : margin;
|
|
1523
|
+
const size = _this.getModuleCount() * cellSize + margin * 2;
|
|
1524
|
+
let img = "";
|
|
1525
|
+
img += "<img";
|
|
1526
|
+
img += ' src="';
|
|
1527
|
+
img += _this.createDataURL(cellSize, margin);
|
|
1528
|
+
img += '"';
|
|
1529
|
+
img += ' width="';
|
|
1530
|
+
img += size;
|
|
1531
|
+
img += '"';
|
|
1532
|
+
img += ' height="';
|
|
1533
|
+
img += size;
|
|
1534
|
+
img += '"';
|
|
1535
|
+
if (alt) {
|
|
1536
|
+
img += ' alt="';
|
|
1537
|
+
img += escapeXml(alt);
|
|
1538
|
+
img += '"';
|
|
1539
|
+
}
|
|
1540
|
+
img += "/>";
|
|
1541
|
+
return img;
|
|
1542
|
+
};
|
|
1543
|
+
const escapeXml = function(s) {
|
|
1544
|
+
let escaped = "";
|
|
1545
|
+
for (let i = 0;i < s.length; i += 1) {
|
|
1546
|
+
const c = s.charAt(i);
|
|
1547
|
+
switch (c) {
|
|
1548
|
+
case "<":
|
|
1549
|
+
escaped += "<";
|
|
1550
|
+
break;
|
|
1551
|
+
case ">":
|
|
1552
|
+
escaped += ">";
|
|
1553
|
+
break;
|
|
1554
|
+
case "&":
|
|
1555
|
+
escaped += "&";
|
|
1556
|
+
break;
|
|
1557
|
+
case '"':
|
|
1558
|
+
escaped += """;
|
|
1559
|
+
break;
|
|
1560
|
+
default:
|
|
1561
|
+
escaped += c;
|
|
1562
|
+
break;
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
return escaped;
|
|
1566
|
+
};
|
|
1567
|
+
const _createHalfASCII = function(margin) {
|
|
1568
|
+
const cellSize = 1;
|
|
1569
|
+
margin = typeof margin == "undefined" ? cellSize * 2 : margin;
|
|
1570
|
+
const size = _this.getModuleCount() * cellSize + margin * 2;
|
|
1571
|
+
const min = margin;
|
|
1572
|
+
const max = size - margin;
|
|
1573
|
+
let y, x, r1, r2, p;
|
|
1574
|
+
const blocks = {
|
|
1575
|
+
"\u2588\u2588": "\u2588",
|
|
1576
|
+
"\u2588 ": "\u2580",
|
|
1577
|
+
" \u2588": "\u2584",
|
|
1578
|
+
" ": " "
|
|
1579
|
+
};
|
|
1580
|
+
const blocksLastLineNoMargin = {
|
|
1581
|
+
"\u2588\u2588": "\u2580",
|
|
1582
|
+
"\u2588 ": "\u2580",
|
|
1583
|
+
" \u2588": " ",
|
|
1584
|
+
" ": " "
|
|
1585
|
+
};
|
|
1586
|
+
let ascii = "";
|
|
1587
|
+
for (y = 0;y < size; y += 2) {
|
|
1588
|
+
r1 = Math.floor((y - min) / cellSize);
|
|
1589
|
+
r2 = Math.floor((y + 1 - min) / cellSize);
|
|
1590
|
+
for (x = 0;x < size; x += 1) {
|
|
1591
|
+
p = "\u2588";
|
|
1592
|
+
if (min <= x && x < max && min <= y && y < max && _this.isDark(r1, Math.floor((x - min) / cellSize))) {
|
|
1593
|
+
p = " ";
|
|
1594
|
+
}
|
|
1595
|
+
if (min <= x && x < max && min <= y + 1 && y + 1 < max && _this.isDark(r2, Math.floor((x - min) / cellSize))) {
|
|
1596
|
+
p += " ";
|
|
1597
|
+
} else {
|
|
1598
|
+
p += "\u2588";
|
|
1599
|
+
}
|
|
1600
|
+
ascii += margin < 1 && y + 1 >= max ? blocksLastLineNoMargin[p] : blocks[p];
|
|
1601
|
+
}
|
|
1602
|
+
ascii += `
|
|
1603
|
+
`;
|
|
1604
|
+
}
|
|
1605
|
+
if (size % 2 && margin > 0) {
|
|
1606
|
+
return ascii.substring(0, ascii.length - size - 1) + Array(size + 1).join("\u2580");
|
|
1607
|
+
}
|
|
1608
|
+
return ascii.substring(0, ascii.length - 1);
|
|
1609
|
+
};
|
|
1610
|
+
_this.createASCII = function(cellSize, margin) {
|
|
1611
|
+
cellSize = cellSize || 1;
|
|
1612
|
+
if (cellSize < 2) {
|
|
1613
|
+
return _createHalfASCII(margin);
|
|
1614
|
+
}
|
|
1615
|
+
cellSize -= 1;
|
|
1616
|
+
margin = typeof margin == "undefined" ? cellSize * 2 : margin;
|
|
1617
|
+
const size = _this.getModuleCount() * cellSize + margin * 2;
|
|
1618
|
+
const min = margin;
|
|
1619
|
+
const max = size - margin;
|
|
1620
|
+
let y, x, r, p;
|
|
1621
|
+
const white = Array(cellSize + 1).join("\u2588\u2588");
|
|
1622
|
+
const black = Array(cellSize + 1).join(" ");
|
|
1623
|
+
let ascii = "";
|
|
1624
|
+
let line = "";
|
|
1625
|
+
for (y = 0;y < size; y += 1) {
|
|
1626
|
+
r = Math.floor((y - min) / cellSize);
|
|
1627
|
+
line = "";
|
|
1628
|
+
for (x = 0;x < size; x += 1) {
|
|
1629
|
+
p = 1;
|
|
1630
|
+
if (min <= x && x < max && min <= y && y < max && _this.isDark(r, Math.floor((x - min) / cellSize))) {
|
|
1631
|
+
p = 0;
|
|
1632
|
+
}
|
|
1633
|
+
line += p ? white : black;
|
|
1634
|
+
}
|
|
1635
|
+
for (r = 0;r < cellSize; r += 1) {
|
|
1636
|
+
ascii += line + `
|
|
1637
|
+
`;
|
|
1638
|
+
}
|
|
1639
|
+
}
|
|
1640
|
+
return ascii.substring(0, ascii.length - 1);
|
|
1641
|
+
};
|
|
1642
|
+
_this.renderTo2dContext = function(context, cellSize) {
|
|
1643
|
+
cellSize = cellSize || 2;
|
|
1644
|
+
const length = _this.getModuleCount();
|
|
1645
|
+
for (let row = 0;row < length; row++) {
|
|
1646
|
+
for (let col = 0;col < length; col++) {
|
|
1647
|
+
context.fillStyle = _this.isDark(row, col) ? "black" : "white";
|
|
1648
|
+
context.fillRect(col * cellSize, row * cellSize, cellSize, cellSize);
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
};
|
|
1652
|
+
return _this;
|
|
1653
|
+
};
|
|
1654
|
+
qrcode.stringToBytes = function(s) {
|
|
1655
|
+
const bytes = [];
|
|
1656
|
+
for (let i = 0;i < s.length; i += 1) {
|
|
1657
|
+
const c = s.charCodeAt(i);
|
|
1658
|
+
bytes.push(c & 255);
|
|
1659
|
+
}
|
|
1660
|
+
return bytes;
|
|
1661
|
+
};
|
|
1662
|
+
qrcode.createStringToBytes = function(unicodeData, numChars) {
|
|
1663
|
+
const unicodeMap = function() {
|
|
1664
|
+
const bin = base64DecodeInputStream(unicodeData);
|
|
1665
|
+
const read = function() {
|
|
1666
|
+
const b = bin.read();
|
|
1667
|
+
if (b == -1)
|
|
1668
|
+
throw "eof";
|
|
1669
|
+
return b;
|
|
1670
|
+
};
|
|
1671
|
+
let count = 0;
|
|
1672
|
+
const unicodeMap = {};
|
|
1673
|
+
while (true) {
|
|
1674
|
+
const b0 = bin.read();
|
|
1675
|
+
if (b0 == -1)
|
|
1676
|
+
break;
|
|
1677
|
+
const b1 = read();
|
|
1678
|
+
const b2 = read();
|
|
1679
|
+
const b3 = read();
|
|
1680
|
+
const k = String.fromCharCode(b0 << 8 | b1);
|
|
1681
|
+
const v = b2 << 8 | b3;
|
|
1682
|
+
unicodeMap[k] = v;
|
|
1683
|
+
count += 1;
|
|
1684
|
+
}
|
|
1685
|
+
if (count != numChars) {
|
|
1686
|
+
throw count + " != " + numChars;
|
|
1687
|
+
}
|
|
1688
|
+
return unicodeMap;
|
|
1689
|
+
}();
|
|
1690
|
+
const unknownChar = 63;
|
|
1691
|
+
return function(s) {
|
|
1692
|
+
const bytes = [];
|
|
1693
|
+
for (let i = 0;i < s.length; i += 1) {
|
|
1694
|
+
const c = s.charCodeAt(i);
|
|
1695
|
+
if (c < 128) {
|
|
1696
|
+
bytes.push(c);
|
|
1697
|
+
} else {
|
|
1698
|
+
const b = unicodeMap[s.charAt(i)];
|
|
1699
|
+
if (typeof b == "number") {
|
|
1700
|
+
if ((b & 255) == b) {
|
|
1701
|
+
bytes.push(b);
|
|
1702
|
+
} else {
|
|
1703
|
+
bytes.push(b >>> 8);
|
|
1704
|
+
bytes.push(b & 255);
|
|
1705
|
+
}
|
|
1706
|
+
} else {
|
|
1707
|
+
bytes.push(unknownChar);
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
return bytes;
|
|
1712
|
+
};
|
|
1713
|
+
};
|
|
1714
|
+
var QRMode = {
|
|
1715
|
+
MODE_NUMBER: 1 << 0,
|
|
1716
|
+
MODE_ALPHA_NUM: 1 << 1,
|
|
1717
|
+
MODE_8BIT_BYTE: 1 << 2,
|
|
1718
|
+
MODE_KANJI: 1 << 3
|
|
1719
|
+
};
|
|
1720
|
+
var QRErrorCorrectionLevel = {
|
|
1721
|
+
L: 1,
|
|
1722
|
+
M: 0,
|
|
1723
|
+
Q: 3,
|
|
1724
|
+
H: 2
|
|
1725
|
+
};
|
|
1726
|
+
var QRMaskPattern = {
|
|
1727
|
+
PATTERN000: 0,
|
|
1728
|
+
PATTERN001: 1,
|
|
1729
|
+
PATTERN010: 2,
|
|
1730
|
+
PATTERN011: 3,
|
|
1731
|
+
PATTERN100: 4,
|
|
1732
|
+
PATTERN101: 5,
|
|
1733
|
+
PATTERN110: 6,
|
|
1734
|
+
PATTERN111: 7
|
|
1735
|
+
};
|
|
1736
|
+
var QRUtil = function() {
|
|
1737
|
+
const PATTERN_POSITION_TABLE = [
|
|
1738
|
+
[],
|
|
1739
|
+
[6, 18],
|
|
1740
|
+
[6, 22],
|
|
1741
|
+
[6, 26],
|
|
1742
|
+
[6, 30],
|
|
1743
|
+
[6, 34],
|
|
1744
|
+
[6, 22, 38],
|
|
1745
|
+
[6, 24, 42],
|
|
1746
|
+
[6, 26, 46],
|
|
1747
|
+
[6, 28, 50],
|
|
1748
|
+
[6, 30, 54],
|
|
1749
|
+
[6, 32, 58],
|
|
1750
|
+
[6, 34, 62],
|
|
1751
|
+
[6, 26, 46, 66],
|
|
1752
|
+
[6, 26, 48, 70],
|
|
1753
|
+
[6, 26, 50, 74],
|
|
1754
|
+
[6, 30, 54, 78],
|
|
1755
|
+
[6, 30, 56, 82],
|
|
1756
|
+
[6, 30, 58, 86],
|
|
1757
|
+
[6, 34, 62, 90],
|
|
1758
|
+
[6, 28, 50, 72, 94],
|
|
1759
|
+
[6, 26, 50, 74, 98],
|
|
1760
|
+
[6, 30, 54, 78, 102],
|
|
1761
|
+
[6, 28, 54, 80, 106],
|
|
1762
|
+
[6, 32, 58, 84, 110],
|
|
1763
|
+
[6, 30, 58, 86, 114],
|
|
1764
|
+
[6, 34, 62, 90, 118],
|
|
1765
|
+
[6, 26, 50, 74, 98, 122],
|
|
1766
|
+
[6, 30, 54, 78, 102, 126],
|
|
1767
|
+
[6, 26, 52, 78, 104, 130],
|
|
1768
|
+
[6, 30, 56, 82, 108, 134],
|
|
1769
|
+
[6, 34, 60, 86, 112, 138],
|
|
1770
|
+
[6, 30, 58, 86, 114, 142],
|
|
1771
|
+
[6, 34, 62, 90, 118, 146],
|
|
1772
|
+
[6, 30, 54, 78, 102, 126, 150],
|
|
1773
|
+
[6, 24, 50, 76, 102, 128, 154],
|
|
1774
|
+
[6, 28, 54, 80, 106, 132, 158],
|
|
1775
|
+
[6, 32, 58, 84, 110, 136, 162],
|
|
1776
|
+
[6, 26, 54, 82, 110, 138, 166],
|
|
1777
|
+
[6, 30, 58, 86, 114, 142, 170]
|
|
1778
|
+
];
|
|
1779
|
+
const G15 = 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0;
|
|
1780
|
+
const G18 = 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0;
|
|
1781
|
+
const G15_MASK = 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1;
|
|
1782
|
+
const _this = {};
|
|
1783
|
+
const getBCHDigit = function(data) {
|
|
1784
|
+
let digit = 0;
|
|
1785
|
+
while (data != 0) {
|
|
1786
|
+
digit += 1;
|
|
1787
|
+
data >>>= 1;
|
|
1788
|
+
}
|
|
1789
|
+
return digit;
|
|
1790
|
+
};
|
|
1791
|
+
_this.getBCHTypeInfo = function(data) {
|
|
1792
|
+
let d = data << 10;
|
|
1793
|
+
while (getBCHDigit(d) - getBCHDigit(G15) >= 0) {
|
|
1794
|
+
d ^= G15 << getBCHDigit(d) - getBCHDigit(G15);
|
|
1795
|
+
}
|
|
1796
|
+
return (data << 10 | d) ^ G15_MASK;
|
|
1797
|
+
};
|
|
1798
|
+
_this.getBCHTypeNumber = function(data) {
|
|
1799
|
+
let d = data << 12;
|
|
1800
|
+
while (getBCHDigit(d) - getBCHDigit(G18) >= 0) {
|
|
1801
|
+
d ^= G18 << getBCHDigit(d) - getBCHDigit(G18);
|
|
1802
|
+
}
|
|
1803
|
+
return data << 12 | d;
|
|
1804
|
+
};
|
|
1805
|
+
_this.getPatternPosition = function(typeNumber) {
|
|
1806
|
+
return PATTERN_POSITION_TABLE[typeNumber - 1];
|
|
1807
|
+
};
|
|
1808
|
+
_this.getMaskFunction = function(maskPattern) {
|
|
1809
|
+
switch (maskPattern) {
|
|
1810
|
+
case QRMaskPattern.PATTERN000:
|
|
1811
|
+
return function(i, j) {
|
|
1812
|
+
return (i + j) % 2 == 0;
|
|
1813
|
+
};
|
|
1814
|
+
case QRMaskPattern.PATTERN001:
|
|
1815
|
+
return function(i, j) {
|
|
1816
|
+
return i % 2 == 0;
|
|
1817
|
+
};
|
|
1818
|
+
case QRMaskPattern.PATTERN010:
|
|
1819
|
+
return function(i, j) {
|
|
1820
|
+
return j % 3 == 0;
|
|
1821
|
+
};
|
|
1822
|
+
case QRMaskPattern.PATTERN011:
|
|
1823
|
+
return function(i, j) {
|
|
1824
|
+
return (i + j) % 3 == 0;
|
|
1825
|
+
};
|
|
1826
|
+
case QRMaskPattern.PATTERN100:
|
|
1827
|
+
return function(i, j) {
|
|
1828
|
+
return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
|
|
1829
|
+
};
|
|
1830
|
+
case QRMaskPattern.PATTERN101:
|
|
1831
|
+
return function(i, j) {
|
|
1832
|
+
return i * j % 2 + i * j % 3 == 0;
|
|
1833
|
+
};
|
|
1834
|
+
case QRMaskPattern.PATTERN110:
|
|
1835
|
+
return function(i, j) {
|
|
1836
|
+
return (i * j % 2 + i * j % 3) % 2 == 0;
|
|
1837
|
+
};
|
|
1838
|
+
case QRMaskPattern.PATTERN111:
|
|
1839
|
+
return function(i, j) {
|
|
1840
|
+
return (i * j % 3 + (i + j) % 2) % 2 == 0;
|
|
1841
|
+
};
|
|
1842
|
+
default:
|
|
1843
|
+
throw "bad maskPattern:" + maskPattern;
|
|
1844
|
+
}
|
|
1845
|
+
};
|
|
1846
|
+
_this.getErrorCorrectPolynomial = function(errorCorrectLength) {
|
|
1847
|
+
let a = qrPolynomial([1], 0);
|
|
1848
|
+
for (let i = 0;i < errorCorrectLength; i += 1) {
|
|
1849
|
+
a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0));
|
|
1850
|
+
}
|
|
1851
|
+
return a;
|
|
1852
|
+
};
|
|
1853
|
+
_this.getLengthInBits = function(mode, type) {
|
|
1854
|
+
if (1 <= type && type < 10) {
|
|
1855
|
+
switch (mode) {
|
|
1856
|
+
case QRMode.MODE_NUMBER:
|
|
1857
|
+
return 10;
|
|
1858
|
+
case QRMode.MODE_ALPHA_NUM:
|
|
1859
|
+
return 9;
|
|
1860
|
+
case QRMode.MODE_8BIT_BYTE:
|
|
1861
|
+
return 8;
|
|
1862
|
+
case QRMode.MODE_KANJI:
|
|
1863
|
+
return 8;
|
|
1864
|
+
default:
|
|
1865
|
+
throw "mode:" + mode;
|
|
1866
|
+
}
|
|
1867
|
+
} else if (type < 27) {
|
|
1868
|
+
switch (mode) {
|
|
1869
|
+
case QRMode.MODE_NUMBER:
|
|
1870
|
+
return 12;
|
|
1871
|
+
case QRMode.MODE_ALPHA_NUM:
|
|
1872
|
+
return 11;
|
|
1873
|
+
case QRMode.MODE_8BIT_BYTE:
|
|
1874
|
+
return 16;
|
|
1875
|
+
case QRMode.MODE_KANJI:
|
|
1876
|
+
return 10;
|
|
1877
|
+
default:
|
|
1878
|
+
throw "mode:" + mode;
|
|
1879
|
+
}
|
|
1880
|
+
} else if (type < 41) {
|
|
1881
|
+
switch (mode) {
|
|
1882
|
+
case QRMode.MODE_NUMBER:
|
|
1883
|
+
return 14;
|
|
1884
|
+
case QRMode.MODE_ALPHA_NUM:
|
|
1885
|
+
return 13;
|
|
1886
|
+
case QRMode.MODE_8BIT_BYTE:
|
|
1887
|
+
return 16;
|
|
1888
|
+
case QRMode.MODE_KANJI:
|
|
1889
|
+
return 12;
|
|
1890
|
+
default:
|
|
1891
|
+
throw "mode:" + mode;
|
|
1892
|
+
}
|
|
1893
|
+
} else {
|
|
1894
|
+
throw "type:" + type;
|
|
1895
|
+
}
|
|
1896
|
+
};
|
|
1897
|
+
_this.getLostPoint = function(qrcode) {
|
|
1898
|
+
const moduleCount = qrcode.getModuleCount();
|
|
1899
|
+
let lostPoint = 0;
|
|
1900
|
+
for (let row = 0;row < moduleCount; row += 1) {
|
|
1901
|
+
for (let col = 0;col < moduleCount; col += 1) {
|
|
1902
|
+
let sameCount = 0;
|
|
1903
|
+
const dark = qrcode.isDark(row, col);
|
|
1904
|
+
for (let r = -1;r <= 1; r += 1) {
|
|
1905
|
+
if (row + r < 0 || moduleCount <= row + r) {
|
|
1906
|
+
continue;
|
|
1907
|
+
}
|
|
1908
|
+
for (let c = -1;c <= 1; c += 1) {
|
|
1909
|
+
if (col + c < 0 || moduleCount <= col + c) {
|
|
1910
|
+
continue;
|
|
1911
|
+
}
|
|
1912
|
+
if (r == 0 && c == 0) {
|
|
1913
|
+
continue;
|
|
1914
|
+
}
|
|
1915
|
+
if (dark == qrcode.isDark(row + r, col + c)) {
|
|
1916
|
+
sameCount += 1;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
if (sameCount > 5) {
|
|
1921
|
+
lostPoint += 3 + sameCount - 5;
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
for (let row = 0;row < moduleCount - 1; row += 1) {
|
|
1926
|
+
for (let col = 0;col < moduleCount - 1; col += 1) {
|
|
1927
|
+
let count = 0;
|
|
1928
|
+
if (qrcode.isDark(row, col))
|
|
1929
|
+
count += 1;
|
|
1930
|
+
if (qrcode.isDark(row + 1, col))
|
|
1931
|
+
count += 1;
|
|
1932
|
+
if (qrcode.isDark(row, col + 1))
|
|
1933
|
+
count += 1;
|
|
1934
|
+
if (qrcode.isDark(row + 1, col + 1))
|
|
1935
|
+
count += 1;
|
|
1936
|
+
if (count == 0 || count == 4) {
|
|
1937
|
+
lostPoint += 3;
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
for (let row = 0;row < moduleCount; row += 1) {
|
|
1942
|
+
for (let col = 0;col < moduleCount - 6; col += 1) {
|
|
1943
|
+
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)) {
|
|
1944
|
+
lostPoint += 40;
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
for (let col = 0;col < moduleCount; col += 1) {
|
|
1949
|
+
for (let row = 0;row < moduleCount - 6; row += 1) {
|
|
1950
|
+
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)) {
|
|
1951
|
+
lostPoint += 40;
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
}
|
|
1955
|
+
let darkCount = 0;
|
|
1956
|
+
for (let col = 0;col < moduleCount; col += 1) {
|
|
1957
|
+
for (let row = 0;row < moduleCount; row += 1) {
|
|
1958
|
+
if (qrcode.isDark(row, col)) {
|
|
1959
|
+
darkCount += 1;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
const ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
|
|
1964
|
+
lostPoint += ratio * 10;
|
|
1965
|
+
return lostPoint;
|
|
1966
|
+
};
|
|
1967
|
+
return _this;
|
|
1968
|
+
}();
|
|
1969
|
+
var QRMath = function() {
|
|
1970
|
+
const EXP_TABLE = new Array(256);
|
|
1971
|
+
const LOG_TABLE = new Array(256);
|
|
1972
|
+
for (let i = 0;i < 8; i += 1) {
|
|
1973
|
+
EXP_TABLE[i] = 1 << i;
|
|
1974
|
+
}
|
|
1975
|
+
for (let i = 8;i < 256; i += 1) {
|
|
1976
|
+
EXP_TABLE[i] = EXP_TABLE[i - 4] ^ EXP_TABLE[i - 5] ^ EXP_TABLE[i - 6] ^ EXP_TABLE[i - 8];
|
|
1977
|
+
}
|
|
1978
|
+
for (let i = 0;i < 255; i += 1) {
|
|
1979
|
+
LOG_TABLE[EXP_TABLE[i]] = i;
|
|
1980
|
+
}
|
|
1981
|
+
const _this = {};
|
|
1982
|
+
_this.glog = function(n) {
|
|
1983
|
+
if (n < 1) {
|
|
1984
|
+
throw "glog(" + n + ")";
|
|
1985
|
+
}
|
|
1986
|
+
return LOG_TABLE[n];
|
|
1987
|
+
};
|
|
1988
|
+
_this.gexp = function(n) {
|
|
1989
|
+
while (n < 0) {
|
|
1990
|
+
n += 255;
|
|
1991
|
+
}
|
|
1992
|
+
while (n >= 256) {
|
|
1993
|
+
n -= 255;
|
|
1994
|
+
}
|
|
1995
|
+
return EXP_TABLE[n];
|
|
1996
|
+
};
|
|
1997
|
+
return _this;
|
|
1998
|
+
}();
|
|
1999
|
+
var qrPolynomial = function(num, shift) {
|
|
2000
|
+
if (typeof num.length == "undefined") {
|
|
2001
|
+
throw num.length + "/" + shift;
|
|
2002
|
+
}
|
|
2003
|
+
const _num = function() {
|
|
2004
|
+
let offset = 0;
|
|
2005
|
+
while (offset < num.length && num[offset] == 0) {
|
|
2006
|
+
offset += 1;
|
|
2007
|
+
}
|
|
2008
|
+
const _num = new Array(num.length - offset + shift);
|
|
2009
|
+
for (let i = 0;i < num.length - offset; i += 1) {
|
|
2010
|
+
_num[i] = num[i + offset];
|
|
2011
|
+
}
|
|
2012
|
+
return _num;
|
|
2013
|
+
}();
|
|
2014
|
+
const _this = {};
|
|
2015
|
+
_this.getAt = function(index) {
|
|
2016
|
+
return _num[index];
|
|
2017
|
+
};
|
|
2018
|
+
_this.getLength = function() {
|
|
2019
|
+
return _num.length;
|
|
2020
|
+
};
|
|
2021
|
+
_this.multiply = function(e) {
|
|
2022
|
+
const num = new Array(_this.getLength() + e.getLength() - 1);
|
|
2023
|
+
for (let i = 0;i < _this.getLength(); i += 1) {
|
|
2024
|
+
for (let j = 0;j < e.getLength(); j += 1) {
|
|
2025
|
+
num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i)) + QRMath.glog(e.getAt(j)));
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
return qrPolynomial(num, 0);
|
|
2029
|
+
};
|
|
2030
|
+
_this.mod = function(e) {
|
|
2031
|
+
if (_this.getLength() - e.getLength() < 0) {
|
|
2032
|
+
return _this;
|
|
2033
|
+
}
|
|
2034
|
+
const ratio = QRMath.glog(_this.getAt(0)) - QRMath.glog(e.getAt(0));
|
|
2035
|
+
const num = new Array(_this.getLength());
|
|
2036
|
+
for (let i = 0;i < _this.getLength(); i += 1) {
|
|
2037
|
+
num[i] = _this.getAt(i);
|
|
2038
|
+
}
|
|
2039
|
+
for (let i = 0;i < e.getLength(); i += 1) {
|
|
2040
|
+
num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i)) + ratio);
|
|
2041
|
+
}
|
|
2042
|
+
return qrPolynomial(num, 0).mod(e);
|
|
2043
|
+
};
|
|
2044
|
+
return _this;
|
|
2045
|
+
};
|
|
2046
|
+
var QRRSBlock = function() {
|
|
2047
|
+
const RS_BLOCK_TABLE = [
|
|
2048
|
+
[1, 26, 19],
|
|
2049
|
+
[1, 26, 16],
|
|
2050
|
+
[1, 26, 13],
|
|
2051
|
+
[1, 26, 9],
|
|
2052
|
+
[1, 44, 34],
|
|
2053
|
+
[1, 44, 28],
|
|
2054
|
+
[1, 44, 22],
|
|
2055
|
+
[1, 44, 16],
|
|
2056
|
+
[1, 70, 55],
|
|
2057
|
+
[1, 70, 44],
|
|
2058
|
+
[2, 35, 17],
|
|
2059
|
+
[2, 35, 13],
|
|
2060
|
+
[1, 100, 80],
|
|
2061
|
+
[2, 50, 32],
|
|
2062
|
+
[2, 50, 24],
|
|
2063
|
+
[4, 25, 9],
|
|
2064
|
+
[1, 134, 108],
|
|
2065
|
+
[2, 67, 43],
|
|
2066
|
+
[2, 33, 15, 2, 34, 16],
|
|
2067
|
+
[2, 33, 11, 2, 34, 12],
|
|
2068
|
+
[2, 86, 68],
|
|
2069
|
+
[4, 43, 27],
|
|
2070
|
+
[4, 43, 19],
|
|
2071
|
+
[4, 43, 15],
|
|
2072
|
+
[2, 98, 78],
|
|
2073
|
+
[4, 49, 31],
|
|
2074
|
+
[2, 32, 14, 4, 33, 15],
|
|
2075
|
+
[4, 39, 13, 1, 40, 14],
|
|
2076
|
+
[2, 121, 97],
|
|
2077
|
+
[2, 60, 38, 2, 61, 39],
|
|
2078
|
+
[4, 40, 18, 2, 41, 19],
|
|
2079
|
+
[4, 40, 14, 2, 41, 15],
|
|
2080
|
+
[2, 146, 116],
|
|
2081
|
+
[3, 58, 36, 2, 59, 37],
|
|
2082
|
+
[4, 36, 16, 4, 37, 17],
|
|
2083
|
+
[4, 36, 12, 4, 37, 13],
|
|
2084
|
+
[2, 86, 68, 2, 87, 69],
|
|
2085
|
+
[4, 69, 43, 1, 70, 44],
|
|
2086
|
+
[6, 43, 19, 2, 44, 20],
|
|
2087
|
+
[6, 43, 15, 2, 44, 16],
|
|
2088
|
+
[4, 101, 81],
|
|
2089
|
+
[1, 80, 50, 4, 81, 51],
|
|
2090
|
+
[4, 50, 22, 4, 51, 23],
|
|
2091
|
+
[3, 36, 12, 8, 37, 13],
|
|
2092
|
+
[2, 116, 92, 2, 117, 93],
|
|
2093
|
+
[6, 58, 36, 2, 59, 37],
|
|
2094
|
+
[4, 46, 20, 6, 47, 21],
|
|
2095
|
+
[7, 42, 14, 4, 43, 15],
|
|
2096
|
+
[4, 133, 107],
|
|
2097
|
+
[8, 59, 37, 1, 60, 38],
|
|
2098
|
+
[8, 44, 20, 4, 45, 21],
|
|
2099
|
+
[12, 33, 11, 4, 34, 12],
|
|
2100
|
+
[3, 145, 115, 1, 146, 116],
|
|
2101
|
+
[4, 64, 40, 5, 65, 41],
|
|
2102
|
+
[11, 36, 16, 5, 37, 17],
|
|
2103
|
+
[11, 36, 12, 5, 37, 13],
|
|
2104
|
+
[5, 109, 87, 1, 110, 88],
|
|
2105
|
+
[5, 65, 41, 5, 66, 42],
|
|
2106
|
+
[5, 54, 24, 7, 55, 25],
|
|
2107
|
+
[11, 36, 12, 7, 37, 13],
|
|
2108
|
+
[5, 122, 98, 1, 123, 99],
|
|
2109
|
+
[7, 73, 45, 3, 74, 46],
|
|
2110
|
+
[15, 43, 19, 2, 44, 20],
|
|
2111
|
+
[3, 45, 15, 13, 46, 16],
|
|
2112
|
+
[1, 135, 107, 5, 136, 108],
|
|
2113
|
+
[10, 74, 46, 1, 75, 47],
|
|
2114
|
+
[1, 50, 22, 15, 51, 23],
|
|
2115
|
+
[2, 42, 14, 17, 43, 15],
|
|
2116
|
+
[5, 150, 120, 1, 151, 121],
|
|
2117
|
+
[9, 69, 43, 4, 70, 44],
|
|
2118
|
+
[17, 50, 22, 1, 51, 23],
|
|
2119
|
+
[2, 42, 14, 19, 43, 15],
|
|
2120
|
+
[3, 141, 113, 4, 142, 114],
|
|
2121
|
+
[3, 70, 44, 11, 71, 45],
|
|
2122
|
+
[17, 47, 21, 4, 48, 22],
|
|
2123
|
+
[9, 39, 13, 16, 40, 14],
|
|
2124
|
+
[3, 135, 107, 5, 136, 108],
|
|
2125
|
+
[3, 67, 41, 13, 68, 42],
|
|
2126
|
+
[15, 54, 24, 5, 55, 25],
|
|
2127
|
+
[15, 43, 15, 10, 44, 16],
|
|
2128
|
+
[4, 144, 116, 4, 145, 117],
|
|
2129
|
+
[17, 68, 42],
|
|
2130
|
+
[17, 50, 22, 6, 51, 23],
|
|
2131
|
+
[19, 46, 16, 6, 47, 17],
|
|
2132
|
+
[2, 139, 111, 7, 140, 112],
|
|
2133
|
+
[17, 74, 46],
|
|
2134
|
+
[7, 54, 24, 16, 55, 25],
|
|
2135
|
+
[34, 37, 13],
|
|
2136
|
+
[4, 151, 121, 5, 152, 122],
|
|
2137
|
+
[4, 75, 47, 14, 76, 48],
|
|
2138
|
+
[11, 54, 24, 14, 55, 25],
|
|
2139
|
+
[16, 45, 15, 14, 46, 16],
|
|
2140
|
+
[6, 147, 117, 4, 148, 118],
|
|
2141
|
+
[6, 73, 45, 14, 74, 46],
|
|
2142
|
+
[11, 54, 24, 16, 55, 25],
|
|
2143
|
+
[30, 46, 16, 2, 47, 17],
|
|
2144
|
+
[8, 132, 106, 4, 133, 107],
|
|
2145
|
+
[8, 75, 47, 13, 76, 48],
|
|
2146
|
+
[7, 54, 24, 22, 55, 25],
|
|
2147
|
+
[22, 45, 15, 13, 46, 16],
|
|
2148
|
+
[10, 142, 114, 2, 143, 115],
|
|
2149
|
+
[19, 74, 46, 4, 75, 47],
|
|
2150
|
+
[28, 50, 22, 6, 51, 23],
|
|
2151
|
+
[33, 46, 16, 4, 47, 17],
|
|
2152
|
+
[8, 152, 122, 4, 153, 123],
|
|
2153
|
+
[22, 73, 45, 3, 74, 46],
|
|
2154
|
+
[8, 53, 23, 26, 54, 24],
|
|
2155
|
+
[12, 45, 15, 28, 46, 16],
|
|
2156
|
+
[3, 147, 117, 10, 148, 118],
|
|
2157
|
+
[3, 73, 45, 23, 74, 46],
|
|
2158
|
+
[4, 54, 24, 31, 55, 25],
|
|
2159
|
+
[11, 45, 15, 31, 46, 16],
|
|
2160
|
+
[7, 146, 116, 7, 147, 117],
|
|
2161
|
+
[21, 73, 45, 7, 74, 46],
|
|
2162
|
+
[1, 53, 23, 37, 54, 24],
|
|
2163
|
+
[19, 45, 15, 26, 46, 16],
|
|
2164
|
+
[5, 145, 115, 10, 146, 116],
|
|
2165
|
+
[19, 75, 47, 10, 76, 48],
|
|
2166
|
+
[15, 54, 24, 25, 55, 25],
|
|
2167
|
+
[23, 45, 15, 25, 46, 16],
|
|
2168
|
+
[13, 145, 115, 3, 146, 116],
|
|
2169
|
+
[2, 74, 46, 29, 75, 47],
|
|
2170
|
+
[42, 54, 24, 1, 55, 25],
|
|
2171
|
+
[23, 45, 15, 28, 46, 16],
|
|
2172
|
+
[17, 145, 115],
|
|
2173
|
+
[10, 74, 46, 23, 75, 47],
|
|
2174
|
+
[10, 54, 24, 35, 55, 25],
|
|
2175
|
+
[19, 45, 15, 35, 46, 16],
|
|
2176
|
+
[17, 145, 115, 1, 146, 116],
|
|
2177
|
+
[14, 74, 46, 21, 75, 47],
|
|
2178
|
+
[29, 54, 24, 19, 55, 25],
|
|
2179
|
+
[11, 45, 15, 46, 46, 16],
|
|
2180
|
+
[13, 145, 115, 6, 146, 116],
|
|
2181
|
+
[14, 74, 46, 23, 75, 47],
|
|
2182
|
+
[44, 54, 24, 7, 55, 25],
|
|
2183
|
+
[59, 46, 16, 1, 47, 17],
|
|
2184
|
+
[12, 151, 121, 7, 152, 122],
|
|
2185
|
+
[12, 75, 47, 26, 76, 48],
|
|
2186
|
+
[39, 54, 24, 14, 55, 25],
|
|
2187
|
+
[22, 45, 15, 41, 46, 16],
|
|
2188
|
+
[6, 151, 121, 14, 152, 122],
|
|
2189
|
+
[6, 75, 47, 34, 76, 48],
|
|
2190
|
+
[46, 54, 24, 10, 55, 25],
|
|
2191
|
+
[2, 45, 15, 64, 46, 16],
|
|
2192
|
+
[17, 152, 122, 4, 153, 123],
|
|
2193
|
+
[29, 74, 46, 14, 75, 47],
|
|
2194
|
+
[49, 54, 24, 10, 55, 25],
|
|
2195
|
+
[24, 45, 15, 46, 46, 16],
|
|
2196
|
+
[4, 152, 122, 18, 153, 123],
|
|
2197
|
+
[13, 74, 46, 32, 75, 47],
|
|
2198
|
+
[48, 54, 24, 14, 55, 25],
|
|
2199
|
+
[42, 45, 15, 32, 46, 16],
|
|
2200
|
+
[20, 147, 117, 4, 148, 118],
|
|
2201
|
+
[40, 75, 47, 7, 76, 48],
|
|
2202
|
+
[43, 54, 24, 22, 55, 25],
|
|
2203
|
+
[10, 45, 15, 67, 46, 16],
|
|
2204
|
+
[19, 148, 118, 6, 149, 119],
|
|
2205
|
+
[18, 75, 47, 31, 76, 48],
|
|
2206
|
+
[34, 54, 24, 34, 55, 25],
|
|
2207
|
+
[20, 45, 15, 61, 46, 16]
|
|
2208
|
+
];
|
|
2209
|
+
const qrRSBlock = function(totalCount, dataCount) {
|
|
2210
|
+
const _this = {};
|
|
2211
|
+
_this.totalCount = totalCount;
|
|
2212
|
+
_this.dataCount = dataCount;
|
|
2213
|
+
return _this;
|
|
2214
|
+
};
|
|
2215
|
+
const _this = {};
|
|
2216
|
+
const getRsBlockTable = function(typeNumber, errorCorrectionLevel) {
|
|
2217
|
+
switch (errorCorrectionLevel) {
|
|
2218
|
+
case QRErrorCorrectionLevel.L:
|
|
2219
|
+
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
|
|
2220
|
+
case QRErrorCorrectionLevel.M:
|
|
2221
|
+
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
|
|
2222
|
+
case QRErrorCorrectionLevel.Q:
|
|
2223
|
+
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
|
|
2224
|
+
case QRErrorCorrectionLevel.H:
|
|
2225
|
+
return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
|
|
2226
|
+
default:
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
};
|
|
2230
|
+
_this.getRSBlocks = function(typeNumber, errorCorrectionLevel) {
|
|
2231
|
+
const rsBlock = getRsBlockTable(typeNumber, errorCorrectionLevel);
|
|
2232
|
+
if (typeof rsBlock == "undefined") {
|
|
2233
|
+
throw "bad rs block @ typeNumber:" + typeNumber + "/errorCorrectionLevel:" + errorCorrectionLevel;
|
|
2234
|
+
}
|
|
2235
|
+
const length = rsBlock.length / 3;
|
|
2236
|
+
const list = [];
|
|
2237
|
+
for (let i = 0;i < length; i += 1) {
|
|
2238
|
+
const count = rsBlock[i * 3 + 0];
|
|
2239
|
+
const totalCount = rsBlock[i * 3 + 1];
|
|
2240
|
+
const dataCount = rsBlock[i * 3 + 2];
|
|
2241
|
+
for (let j = 0;j < count; j += 1) {
|
|
2242
|
+
list.push(qrRSBlock(totalCount, dataCount));
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
return list;
|
|
2246
|
+
};
|
|
2247
|
+
return _this;
|
|
2248
|
+
}();
|
|
2249
|
+
var qrBitBuffer = function() {
|
|
2250
|
+
const _buffer = [];
|
|
2251
|
+
let _length = 0;
|
|
2252
|
+
const _this = {};
|
|
2253
|
+
_this.getBuffer = function() {
|
|
2254
|
+
return _buffer;
|
|
2255
|
+
};
|
|
2256
|
+
_this.getAt = function(index) {
|
|
2257
|
+
const bufIndex = Math.floor(index / 8);
|
|
2258
|
+
return (_buffer[bufIndex] >>> 7 - index % 8 & 1) == 1;
|
|
2259
|
+
};
|
|
2260
|
+
_this.put = function(num, length) {
|
|
2261
|
+
for (let i = 0;i < length; i += 1) {
|
|
2262
|
+
_this.putBit((num >>> length - i - 1 & 1) == 1);
|
|
2263
|
+
}
|
|
2264
|
+
};
|
|
2265
|
+
_this.getLengthInBits = function() {
|
|
2266
|
+
return _length;
|
|
2267
|
+
};
|
|
2268
|
+
_this.putBit = function(bit) {
|
|
2269
|
+
const bufIndex = Math.floor(_length / 8);
|
|
2270
|
+
if (_buffer.length <= bufIndex) {
|
|
2271
|
+
_buffer.push(0);
|
|
2272
|
+
}
|
|
2273
|
+
if (bit) {
|
|
2274
|
+
_buffer[bufIndex] |= 128 >>> _length % 8;
|
|
2275
|
+
}
|
|
2276
|
+
_length += 1;
|
|
2277
|
+
};
|
|
2278
|
+
return _this;
|
|
2279
|
+
};
|
|
2280
|
+
var qrNumber = function(data) {
|
|
2281
|
+
const _mode = QRMode.MODE_NUMBER;
|
|
2282
|
+
const _data = data;
|
|
2283
|
+
const _this = {};
|
|
2284
|
+
_this.getMode = function() {
|
|
2285
|
+
return _mode;
|
|
2286
|
+
};
|
|
2287
|
+
_this.getLength = function(buffer) {
|
|
2288
|
+
return _data.length;
|
|
2289
|
+
};
|
|
2290
|
+
_this.write = function(buffer) {
|
|
2291
|
+
const data = _data;
|
|
2292
|
+
let i = 0;
|
|
2293
|
+
while (i + 2 < data.length) {
|
|
2294
|
+
buffer.put(strToNum(data.substring(i, i + 3)), 10);
|
|
2295
|
+
i += 3;
|
|
2296
|
+
}
|
|
2297
|
+
if (i < data.length) {
|
|
2298
|
+
if (data.length - i == 1) {
|
|
2299
|
+
buffer.put(strToNum(data.substring(i, i + 1)), 4);
|
|
2300
|
+
} else if (data.length - i == 2) {
|
|
2301
|
+
buffer.put(strToNum(data.substring(i, i + 2)), 7);
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
};
|
|
2305
|
+
const strToNum = function(s) {
|
|
2306
|
+
let num = 0;
|
|
2307
|
+
for (let i = 0;i < s.length; i += 1) {
|
|
2308
|
+
num = num * 10 + chatToNum(s.charAt(i));
|
|
2309
|
+
}
|
|
2310
|
+
return num;
|
|
2311
|
+
};
|
|
2312
|
+
const chatToNum = function(c) {
|
|
2313
|
+
if ("0" <= c && c <= "9") {
|
|
2314
|
+
return c.charCodeAt(0) - 48;
|
|
2315
|
+
}
|
|
2316
|
+
throw "illegal char :" + c;
|
|
2317
|
+
};
|
|
2318
|
+
return _this;
|
|
2319
|
+
};
|
|
2320
|
+
var qrAlphaNum = function(data) {
|
|
2321
|
+
const _mode = QRMode.MODE_ALPHA_NUM;
|
|
2322
|
+
const _data = data;
|
|
2323
|
+
const _this = {};
|
|
2324
|
+
_this.getMode = function() {
|
|
2325
|
+
return _mode;
|
|
2326
|
+
};
|
|
2327
|
+
_this.getLength = function(buffer) {
|
|
2328
|
+
return _data.length;
|
|
2329
|
+
};
|
|
2330
|
+
_this.write = function(buffer) {
|
|
2331
|
+
const s = _data;
|
|
2332
|
+
let i = 0;
|
|
2333
|
+
while (i + 1 < s.length) {
|
|
2334
|
+
buffer.put(getCode(s.charAt(i)) * 45 + getCode(s.charAt(i + 1)), 11);
|
|
2335
|
+
i += 2;
|
|
2336
|
+
}
|
|
2337
|
+
if (i < s.length) {
|
|
2338
|
+
buffer.put(getCode(s.charAt(i)), 6);
|
|
2339
|
+
}
|
|
2340
|
+
};
|
|
2341
|
+
const getCode = function(c) {
|
|
2342
|
+
if ("0" <= c && c <= "9") {
|
|
2343
|
+
return c.charCodeAt(0) - 48;
|
|
2344
|
+
} else if ("A" <= c && c <= "Z") {
|
|
2345
|
+
return c.charCodeAt(0) - 65 + 10;
|
|
2346
|
+
} else {
|
|
2347
|
+
switch (c) {
|
|
2348
|
+
case " ":
|
|
2349
|
+
return 36;
|
|
2350
|
+
case "$":
|
|
2351
|
+
return 37;
|
|
2352
|
+
case "%":
|
|
2353
|
+
return 38;
|
|
2354
|
+
case "*":
|
|
2355
|
+
return 39;
|
|
2356
|
+
case "+":
|
|
2357
|
+
return 40;
|
|
2358
|
+
case "-":
|
|
2359
|
+
return 41;
|
|
2360
|
+
case ".":
|
|
2361
|
+
return 42;
|
|
2362
|
+
case "/":
|
|
2363
|
+
return 43;
|
|
2364
|
+
case ":":
|
|
2365
|
+
return 44;
|
|
2366
|
+
default:
|
|
2367
|
+
throw "illegal char :" + c;
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
};
|
|
2371
|
+
return _this;
|
|
2372
|
+
};
|
|
2373
|
+
var qr8BitByte = function(data) {
|
|
2374
|
+
const _mode = QRMode.MODE_8BIT_BYTE;
|
|
2375
|
+
const _data = data;
|
|
2376
|
+
const _bytes = qrcode.stringToBytes(data);
|
|
2377
|
+
const _this = {};
|
|
2378
|
+
_this.getMode = function() {
|
|
2379
|
+
return _mode;
|
|
2380
|
+
};
|
|
2381
|
+
_this.getLength = function(buffer) {
|
|
2382
|
+
return _bytes.length;
|
|
2383
|
+
};
|
|
2384
|
+
_this.write = function(buffer) {
|
|
2385
|
+
for (let i = 0;i < _bytes.length; i += 1) {
|
|
2386
|
+
buffer.put(_bytes[i], 8);
|
|
2387
|
+
}
|
|
2388
|
+
};
|
|
2389
|
+
return _this;
|
|
2390
|
+
};
|
|
2391
|
+
var qrKanji = function(data) {
|
|
2392
|
+
const _mode = QRMode.MODE_KANJI;
|
|
2393
|
+
const _data = data;
|
|
2394
|
+
const stringToBytes = qrcode.stringToBytes;
|
|
2395
|
+
(function(c, code) {
|
|
2396
|
+
const test = stringToBytes(c);
|
|
2397
|
+
if (test.length != 2 || (test[0] << 8 | test[1]) != code) {
|
|
2398
|
+
throw "sjis not supported.";
|
|
2399
|
+
}
|
|
2400
|
+
})("\u53CB", 38726);
|
|
2401
|
+
const _bytes = stringToBytes(data);
|
|
2402
|
+
const _this = {};
|
|
2403
|
+
_this.getMode = function() {
|
|
2404
|
+
return _mode;
|
|
2405
|
+
};
|
|
2406
|
+
_this.getLength = function(buffer) {
|
|
2407
|
+
return ~~(_bytes.length / 2);
|
|
2408
|
+
};
|
|
2409
|
+
_this.write = function(buffer) {
|
|
2410
|
+
const data = _bytes;
|
|
2411
|
+
let i = 0;
|
|
2412
|
+
while (i + 1 < data.length) {
|
|
2413
|
+
let c = (255 & data[i]) << 8 | 255 & data[i + 1];
|
|
2414
|
+
if (33088 <= c && c <= 40956) {
|
|
2415
|
+
c -= 33088;
|
|
2416
|
+
} else if (57408 <= c && c <= 60351) {
|
|
2417
|
+
c -= 49472;
|
|
2418
|
+
} else {
|
|
2419
|
+
throw "illegal char at " + (i + 1) + "/" + c;
|
|
2420
|
+
}
|
|
2421
|
+
c = (c >>> 8 & 255) * 192 + (c & 255);
|
|
2422
|
+
buffer.put(c, 13);
|
|
2423
|
+
i += 2;
|
|
2424
|
+
}
|
|
2425
|
+
if (i < data.length) {
|
|
2426
|
+
throw "illegal char at " + (i + 1);
|
|
2427
|
+
}
|
|
2428
|
+
};
|
|
2429
|
+
return _this;
|
|
2430
|
+
};
|
|
2431
|
+
var byteArrayOutputStream = function() {
|
|
2432
|
+
const _bytes = [];
|
|
2433
|
+
const _this = {};
|
|
2434
|
+
_this.writeByte = function(b) {
|
|
2435
|
+
_bytes.push(b & 255);
|
|
2436
|
+
};
|
|
2437
|
+
_this.writeShort = function(i) {
|
|
2438
|
+
_this.writeByte(i);
|
|
2439
|
+
_this.writeByte(i >>> 8);
|
|
2440
|
+
};
|
|
2441
|
+
_this.writeBytes = function(b, off, len) {
|
|
2442
|
+
off = off || 0;
|
|
2443
|
+
len = len || b.length;
|
|
2444
|
+
for (let i = 0;i < len; i += 1) {
|
|
2445
|
+
_this.writeByte(b[i + off]);
|
|
2446
|
+
}
|
|
2447
|
+
};
|
|
2448
|
+
_this.writeString = function(s) {
|
|
2449
|
+
for (let i = 0;i < s.length; i += 1) {
|
|
2450
|
+
_this.writeByte(s.charCodeAt(i));
|
|
2451
|
+
}
|
|
2452
|
+
};
|
|
2453
|
+
_this.toByteArray = function() {
|
|
2454
|
+
return _bytes;
|
|
2455
|
+
};
|
|
2456
|
+
_this.toString = function() {
|
|
2457
|
+
let s = "";
|
|
2458
|
+
s += "[";
|
|
2459
|
+
for (let i = 0;i < _bytes.length; i += 1) {
|
|
2460
|
+
if (i > 0) {
|
|
2461
|
+
s += ",";
|
|
2462
|
+
}
|
|
2463
|
+
s += _bytes[i];
|
|
2464
|
+
}
|
|
2465
|
+
s += "]";
|
|
2466
|
+
return s;
|
|
2467
|
+
};
|
|
2468
|
+
return _this;
|
|
2469
|
+
};
|
|
2470
|
+
var base64EncodeOutputStream = function() {
|
|
2471
|
+
let _buffer = 0;
|
|
2472
|
+
let _buflen = 0;
|
|
2473
|
+
let _length = 0;
|
|
2474
|
+
let _base64 = "";
|
|
2475
|
+
const _this = {};
|
|
2476
|
+
const writeEncoded = function(b) {
|
|
2477
|
+
_base64 += String.fromCharCode(encode(b & 63));
|
|
2478
|
+
};
|
|
2479
|
+
const encode = function(n) {
|
|
2480
|
+
if (n < 0) {
|
|
2481
|
+
throw "n:" + n;
|
|
2482
|
+
} else if (n < 26) {
|
|
2483
|
+
return 65 + n;
|
|
2484
|
+
} else if (n < 52) {
|
|
2485
|
+
return 97 + (n - 26);
|
|
2486
|
+
} else if (n < 62) {
|
|
2487
|
+
return 48 + (n - 52);
|
|
2488
|
+
} else if (n == 62) {
|
|
2489
|
+
return 43;
|
|
2490
|
+
} else if (n == 63) {
|
|
2491
|
+
return 47;
|
|
2492
|
+
} else {
|
|
2493
|
+
throw "n:" + n;
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
_this.writeByte = function(n) {
|
|
2497
|
+
_buffer = _buffer << 8 | n & 255;
|
|
2498
|
+
_buflen += 8;
|
|
2499
|
+
_length += 1;
|
|
2500
|
+
while (_buflen >= 6) {
|
|
2501
|
+
writeEncoded(_buffer >>> _buflen - 6);
|
|
2502
|
+
_buflen -= 6;
|
|
2503
|
+
}
|
|
2504
|
+
};
|
|
2505
|
+
_this.flush = function() {
|
|
2506
|
+
if (_buflen > 0) {
|
|
2507
|
+
writeEncoded(_buffer << 6 - _buflen);
|
|
2508
|
+
_buffer = 0;
|
|
2509
|
+
_buflen = 0;
|
|
2510
|
+
}
|
|
2511
|
+
if (_length % 3 != 0) {
|
|
2512
|
+
const padlen = 3 - _length % 3;
|
|
2513
|
+
for (let i = 0;i < padlen; i += 1) {
|
|
2514
|
+
_base64 += "=";
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
};
|
|
2518
|
+
_this.toString = function() {
|
|
2519
|
+
return _base64;
|
|
2520
|
+
};
|
|
2521
|
+
return _this;
|
|
2522
|
+
};
|
|
2523
|
+
var base64DecodeInputStream = function(str) {
|
|
2524
|
+
const _str = str;
|
|
2525
|
+
let _pos = 0;
|
|
2526
|
+
let _buffer = 0;
|
|
2527
|
+
let _buflen = 0;
|
|
2528
|
+
const _this = {};
|
|
2529
|
+
_this.read = function() {
|
|
2530
|
+
while (_buflen < 8) {
|
|
2531
|
+
if (_pos >= _str.length) {
|
|
2532
|
+
if (_buflen == 0) {
|
|
2533
|
+
return -1;
|
|
2534
|
+
}
|
|
2535
|
+
throw "unexpected end of file./" + _buflen;
|
|
2536
|
+
}
|
|
2537
|
+
const c = _str.charAt(_pos);
|
|
2538
|
+
_pos += 1;
|
|
2539
|
+
if (c == "=") {
|
|
2540
|
+
_buflen = 0;
|
|
2541
|
+
return -1;
|
|
2542
|
+
} else if (c.match(/^\s$/)) {
|
|
2543
|
+
continue;
|
|
2544
|
+
}
|
|
2545
|
+
_buffer = _buffer << 6 | decode(c.charCodeAt(0));
|
|
2546
|
+
_buflen += 6;
|
|
2547
|
+
}
|
|
2548
|
+
const n = _buffer >>> _buflen - 8 & 255;
|
|
2549
|
+
_buflen -= 8;
|
|
2550
|
+
return n;
|
|
2551
|
+
};
|
|
2552
|
+
const decode = function(c) {
|
|
2553
|
+
if (65 <= c && c <= 90) {
|
|
2554
|
+
return c - 65;
|
|
2555
|
+
} else if (97 <= c && c <= 122) {
|
|
2556
|
+
return c - 97 + 26;
|
|
2557
|
+
} else if (48 <= c && c <= 57) {
|
|
2558
|
+
return c - 48 + 52;
|
|
2559
|
+
} else if (c == 43) {
|
|
2560
|
+
return 62;
|
|
2561
|
+
} else if (c == 47) {
|
|
2562
|
+
return 63;
|
|
2563
|
+
} else {
|
|
2564
|
+
throw "c:" + c;
|
|
2565
|
+
}
|
|
2566
|
+
};
|
|
2567
|
+
return _this;
|
|
2568
|
+
};
|
|
2569
|
+
var gifImage = function(width, height) {
|
|
2570
|
+
const _width = width;
|
|
2571
|
+
const _height = height;
|
|
2572
|
+
const _data = new Array(width * height);
|
|
2573
|
+
const _this = {};
|
|
2574
|
+
_this.setPixel = function(x, y, pixel) {
|
|
2575
|
+
_data[y * _width + x] = pixel;
|
|
2576
|
+
};
|
|
2577
|
+
_this.write = function(out) {
|
|
2578
|
+
out.writeString("GIF87a");
|
|
2579
|
+
out.writeShort(_width);
|
|
2580
|
+
out.writeShort(_height);
|
|
2581
|
+
out.writeByte(128);
|
|
2582
|
+
out.writeByte(0);
|
|
2583
|
+
out.writeByte(0);
|
|
2584
|
+
out.writeByte(0);
|
|
2585
|
+
out.writeByte(0);
|
|
2586
|
+
out.writeByte(0);
|
|
2587
|
+
out.writeByte(255);
|
|
2588
|
+
out.writeByte(255);
|
|
2589
|
+
out.writeByte(255);
|
|
2590
|
+
out.writeString(",");
|
|
2591
|
+
out.writeShort(0);
|
|
2592
|
+
out.writeShort(0);
|
|
2593
|
+
out.writeShort(_width);
|
|
2594
|
+
out.writeShort(_height);
|
|
2595
|
+
out.writeByte(0);
|
|
2596
|
+
const lzwMinCodeSize = 2;
|
|
2597
|
+
const raster = getLZWRaster(lzwMinCodeSize);
|
|
2598
|
+
out.writeByte(lzwMinCodeSize);
|
|
2599
|
+
let offset = 0;
|
|
2600
|
+
while (raster.length - offset > 255) {
|
|
2601
|
+
out.writeByte(255);
|
|
2602
|
+
out.writeBytes(raster, offset, 255);
|
|
2603
|
+
offset += 255;
|
|
2604
|
+
}
|
|
2605
|
+
out.writeByte(raster.length - offset);
|
|
2606
|
+
out.writeBytes(raster, offset, raster.length - offset);
|
|
2607
|
+
out.writeByte(0);
|
|
2608
|
+
out.writeString(";");
|
|
2609
|
+
};
|
|
2610
|
+
const bitOutputStream = function(out) {
|
|
2611
|
+
const _out = out;
|
|
2612
|
+
let _bitLength = 0;
|
|
2613
|
+
let _bitBuffer = 0;
|
|
2614
|
+
const _this = {};
|
|
2615
|
+
_this.write = function(data, length) {
|
|
2616
|
+
if (data >>> length != 0) {
|
|
2617
|
+
throw "length over";
|
|
2618
|
+
}
|
|
2619
|
+
while (_bitLength + length >= 8) {
|
|
2620
|
+
_out.writeByte(255 & (data << _bitLength | _bitBuffer));
|
|
2621
|
+
length -= 8 - _bitLength;
|
|
2622
|
+
data >>>= 8 - _bitLength;
|
|
2623
|
+
_bitBuffer = 0;
|
|
2624
|
+
_bitLength = 0;
|
|
2625
|
+
}
|
|
2626
|
+
_bitBuffer = data << _bitLength | _bitBuffer;
|
|
2627
|
+
_bitLength = _bitLength + length;
|
|
2628
|
+
};
|
|
2629
|
+
_this.flush = function() {
|
|
2630
|
+
if (_bitLength > 0) {
|
|
2631
|
+
_out.writeByte(_bitBuffer);
|
|
2632
|
+
}
|
|
2633
|
+
};
|
|
2634
|
+
return _this;
|
|
2635
|
+
};
|
|
2636
|
+
const getLZWRaster = function(lzwMinCodeSize) {
|
|
2637
|
+
const clearCode = 1 << lzwMinCodeSize;
|
|
2638
|
+
const endCode = (1 << lzwMinCodeSize) + 1;
|
|
2639
|
+
let bitLength = lzwMinCodeSize + 1;
|
|
2640
|
+
const table = lzwTable();
|
|
2641
|
+
for (let i = 0;i < clearCode; i += 1) {
|
|
2642
|
+
table.add(String.fromCharCode(i));
|
|
2643
|
+
}
|
|
2644
|
+
table.add(String.fromCharCode(clearCode));
|
|
2645
|
+
table.add(String.fromCharCode(endCode));
|
|
2646
|
+
const byteOut = byteArrayOutputStream();
|
|
2647
|
+
const bitOut = bitOutputStream(byteOut);
|
|
2648
|
+
bitOut.write(clearCode, bitLength);
|
|
2649
|
+
let dataIndex = 0;
|
|
2650
|
+
let s = String.fromCharCode(_data[dataIndex]);
|
|
2651
|
+
dataIndex += 1;
|
|
2652
|
+
while (dataIndex < _data.length) {
|
|
2653
|
+
const c = String.fromCharCode(_data[dataIndex]);
|
|
2654
|
+
dataIndex += 1;
|
|
2655
|
+
if (table.contains(s + c)) {
|
|
2656
|
+
s = s + c;
|
|
2657
|
+
} else {
|
|
2658
|
+
bitOut.write(table.indexOf(s), bitLength);
|
|
2659
|
+
if (table.size() < 4095) {
|
|
2660
|
+
if (table.size() == 1 << bitLength) {
|
|
2661
|
+
bitLength += 1;
|
|
2662
|
+
}
|
|
2663
|
+
table.add(s + c);
|
|
2664
|
+
}
|
|
2665
|
+
s = c;
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
bitOut.write(table.indexOf(s), bitLength);
|
|
2669
|
+
bitOut.write(endCode, bitLength);
|
|
2670
|
+
bitOut.flush();
|
|
2671
|
+
return byteOut.toByteArray();
|
|
2672
|
+
};
|
|
2673
|
+
const lzwTable = function() {
|
|
2674
|
+
const _map = {};
|
|
2675
|
+
let _size = 0;
|
|
2676
|
+
const _this = {};
|
|
2677
|
+
_this.add = function(key) {
|
|
2678
|
+
if (_this.contains(key)) {
|
|
2679
|
+
throw "dup key:" + key;
|
|
2680
|
+
}
|
|
2681
|
+
_map[key] = _size;
|
|
2682
|
+
_size += 1;
|
|
2683
|
+
};
|
|
2684
|
+
_this.size = function() {
|
|
2685
|
+
return _size;
|
|
2686
|
+
};
|
|
2687
|
+
_this.indexOf = function(key) {
|
|
2688
|
+
return _map[key];
|
|
2689
|
+
};
|
|
2690
|
+
_this.contains = function(key) {
|
|
2691
|
+
return typeof _map[key] != "undefined";
|
|
2692
|
+
};
|
|
2693
|
+
return _this;
|
|
2694
|
+
};
|
|
2695
|
+
return _this;
|
|
2696
|
+
};
|
|
2697
|
+
var createDataURL = function(width, height, getPixel) {
|
|
2698
|
+
const gif = gifImage(width, height);
|
|
2699
|
+
for (let y = 0;y < height; y += 1) {
|
|
2700
|
+
for (let x = 0;x < width; x += 1) {
|
|
2701
|
+
gif.setPixel(x, y, getPixel(x, y));
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
const b = byteArrayOutputStream();
|
|
2705
|
+
gif.write(b);
|
|
2706
|
+
const base64 = base64EncodeOutputStream();
|
|
2707
|
+
const bytes = b.toByteArray();
|
|
2708
|
+
for (let i = 0;i < bytes.length; i += 1) {
|
|
2709
|
+
base64.writeByte(bytes[i]);
|
|
2710
|
+
}
|
|
2711
|
+
base64.flush();
|
|
2712
|
+
return "data:image/gif;base64," + base64;
|
|
2713
|
+
};
|
|
2714
|
+
var qrcode_default = qrcode;
|
|
2715
|
+
var stringToBytes = qrcode.stringToBytes;
|
|
2716
|
+
|
|
2717
|
+
// ../shared/src/qr.ts
|
|
2718
|
+
function qrModules(text) {
|
|
2719
|
+
const qr = qrcode_default(0, "M");
|
|
2720
|
+
qr.addData(text, "Byte");
|
|
2721
|
+
qr.make();
|
|
2722
|
+
const n = qr.getModuleCount();
|
|
2723
|
+
return Array.from({ length: n }, (_, r) => Array.from({ length: n }, (_, c) => qr.isDark(r, c)));
|
|
2724
|
+
}
|
|
2725
|
+
function qrText(modules, margin = 2) {
|
|
2726
|
+
const n = modules.length + margin * 2;
|
|
2727
|
+
const light = (r, c) => {
|
|
2728
|
+
const row = modules[r - margin];
|
|
2729
|
+
const v = row?.[c - margin];
|
|
2730
|
+
return v === undefined ? true : !v;
|
|
2731
|
+
};
|
|
2732
|
+
const lines = [];
|
|
2733
|
+
for (let r = 0;r < n; r += 2) {
|
|
2734
|
+
let line = "";
|
|
2735
|
+
for (let c = 0;c < n; c++) {
|
|
2736
|
+
const top = light(r, c);
|
|
2737
|
+
const bottom = r + 1 < n ? light(r + 1, c) : true;
|
|
2738
|
+
line += top && bottom ? "\u2588" : top ? "\u2580" : bottom ? "\u2584" : " ";
|
|
2739
|
+
}
|
|
2740
|
+
lines.push(line);
|
|
2741
|
+
}
|
|
2742
|
+
return lines.join(`
|
|
2743
|
+
`);
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
// src/pair.ts
|
|
2747
|
+
async function printPairCode() {
|
|
2748
|
+
const token = readToken();
|
|
2749
|
+
if (!token)
|
|
2750
|
+
return "daemon token missing; `toyon doctor` says where it looked";
|
|
2751
|
+
let res;
|
|
2752
|
+
try {
|
|
2753
|
+
res = await fetch(`${base}/pair`, { method: "POST", headers: { authorization: `Bearer ${token}` } });
|
|
2754
|
+
} catch {
|
|
2755
|
+
return "Toyon is not running. Start it with `toyon`, then run `toyon pair`.";
|
|
2756
|
+
}
|
|
2757
|
+
if (!res.ok)
|
|
2758
|
+
return await res.text() || `the daemon refused a pairing code (${res.status})`;
|
|
2759
|
+
const mint = await res.json();
|
|
2760
|
+
console.log(`
|
|
2761
|
+
${qrText(qrModules(mint.url))}
|
|
2762
|
+
`);
|
|
2763
|
+
console.log("Scan with your phone's camera. The code works once and lasts 2 minutes.");
|
|
2764
|
+
console.log(mint.url);
|
|
2765
|
+
return null;
|
|
2766
|
+
}
|
|
2767
|
+
async function pair() {
|
|
2768
|
+
if (!await health()) {
|
|
2769
|
+
console.error("toyon: Toyon is not running. Start it with `toyon`, then run `toyon pair`.");
|
|
2770
|
+
return 1;
|
|
2771
|
+
}
|
|
2772
|
+
const refused = await printPairCode();
|
|
2773
|
+
if (refused) {
|
|
2774
|
+
console.error(`toyon: ${refused}`);
|
|
2775
|
+
return 1;
|
|
2776
|
+
}
|
|
2777
|
+
return 0;
|
|
2778
|
+
}
|
|
2779
|
+
|
|
1048
2780
|
// src/remote.ts
|
|
1049
2781
|
import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
1050
2782
|
|
|
@@ -1246,8 +2978,15 @@ async function remote(cmd) {
|
|
|
1246
2978
|
console.log(`add it to your list at toyon.cloud: ${add}`);
|
|
1247
2979
|
openUrl(add);
|
|
1248
2980
|
}
|
|
1249
|
-
if (h && !same(h.remote, r))
|
|
2981
|
+
if (h && !same(h.remote, r)) {
|
|
1250
2982
|
console.log("the daemon reads this at start; `toyon stop` then `toyon` applies it");
|
|
2983
|
+
if (r)
|
|
2984
|
+
console.log("after that, `toyon pair` shows a code to scan with your phone");
|
|
2985
|
+
} else if (h && r) {
|
|
2986
|
+
const refused = await printPairCode();
|
|
2987
|
+
if (refused)
|
|
2988
|
+
console.error(`toyon: ${refused}`);
|
|
2989
|
+
}
|
|
1251
2990
|
return 0;
|
|
1252
2991
|
}
|
|
1253
2992
|
|
|
@@ -1373,11 +3112,97 @@ async function uninstall(opts) {
|
|
|
1373
3112
|
return 0;
|
|
1374
3113
|
}
|
|
1375
3114
|
|
|
3115
|
+
// src/update.ts
|
|
3116
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
3117
|
+
import { join as join7 } from "path";
|
|
3118
|
+
var WAIT_MS2 = 15000;
|
|
3119
|
+
async function update() {
|
|
3120
|
+
if (process.env.TOYON_UPDATES === "off") {
|
|
3121
|
+
console.error("updates are turned off for this machine (TOYON_UPDATES=off)");
|
|
3122
|
+
return 1;
|
|
3123
|
+
}
|
|
3124
|
+
const method = installMethod(packaged ? join7(here, "..", "package.json") : null);
|
|
3125
|
+
if (method === "none") {
|
|
3126
|
+
console.error("toyon update works on a global npm or bun install, and this Toyon is not one; update it the way it was installed");
|
|
3127
|
+
return 1;
|
|
3128
|
+
}
|
|
3129
|
+
const latest = latestVersion();
|
|
3130
|
+
if (latest === null) {
|
|
3131
|
+
console.error("could not ask npm for the newest Toyon; check that npm is on your PATH and its registry answers");
|
|
3132
|
+
return 1;
|
|
3133
|
+
}
|
|
3134
|
+
const behind = newer(latest, package_default.version);
|
|
3135
|
+
if (method === "npx") {
|
|
3136
|
+
console.log(behind ? `toyon ${latest} is out; npx runs the version you name, so run npx toyon@${latest}` : `toyon ${package_default.version} is the newest`);
|
|
3137
|
+
return 0;
|
|
3138
|
+
}
|
|
3139
|
+
if (behind) {
|
|
3140
|
+
const command = installCommand(method, latest) ?? [];
|
|
3141
|
+
const [cmd, ...args] = command;
|
|
3142
|
+
if (!cmd)
|
|
3143
|
+
return 1;
|
|
3144
|
+
console.log(`installing toyon ${latest}: ${command.join(" ")}`);
|
|
3145
|
+
const r = spawnSync2(cmd, args, { stdio: "inherit" });
|
|
3146
|
+
if (r.status !== 0) {
|
|
3147
|
+
console.error(`the install did not finish; run ${command.join(" ")} yourself to see why`);
|
|
3148
|
+
return r.status ?? 1;
|
|
3149
|
+
}
|
|
3150
|
+
} else {
|
|
3151
|
+
console.log(`toyon ${package_default.version} is the newest`);
|
|
3152
|
+
}
|
|
3153
|
+
return restartOnto(behind ? latest : package_default.version);
|
|
3154
|
+
}
|
|
3155
|
+
function latestVersion() {
|
|
3156
|
+
const r = spawnSync2("npm", ["view", "toyon", "version", "--json"], { encoding: "utf8" });
|
|
3157
|
+
if (r.status !== 0)
|
|
3158
|
+
return null;
|
|
3159
|
+
try {
|
|
3160
|
+
const v = JSON.parse(r.stdout);
|
|
3161
|
+
return typeof v === "string" ? v : null;
|
|
3162
|
+
} catch {
|
|
3163
|
+
return null;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
async function restartOnto(version) {
|
|
3167
|
+
const h = await health();
|
|
3168
|
+
if (!h) {
|
|
3169
|
+
console.log(`Toyon is not running; \`toyon\` starts ${version}`);
|
|
3170
|
+
return 0;
|
|
3171
|
+
}
|
|
3172
|
+
if (h.version === version) {
|
|
3173
|
+
console.log(`the daemon is already ${version}`);
|
|
3174
|
+
return 0;
|
|
3175
|
+
}
|
|
3176
|
+
const token = readToken();
|
|
3177
|
+
if (!token) {
|
|
3178
|
+
console.error("the daemon token is missing, so the daemon cannot be asked to restart; `toyon restart` does it by hand");
|
|
3179
|
+
return 1;
|
|
3180
|
+
}
|
|
3181
|
+
const res = await fetch(`${base}/restart?token=${token}`, { method: "POST" }).catch(() => null);
|
|
3182
|
+
if (res && res.status === 409) {
|
|
3183
|
+
console.error(await res.text());
|
|
3184
|
+
return 1;
|
|
3185
|
+
}
|
|
3186
|
+
const deadline = Date.now() + WAIT_MS2;
|
|
3187
|
+
while (Date.now() < deadline) {
|
|
3188
|
+
await Bun.sleep(500);
|
|
3189
|
+
if ((await health())?.version === version) {
|
|
3190
|
+
console.log(`restarted Toyon on ${version}`);
|
|
3191
|
+
return 0;
|
|
3192
|
+
}
|
|
3193
|
+
}
|
|
3194
|
+
console.log(`Toyon restarts on ${version} once the chat replying now finishes`);
|
|
3195
|
+
return 0;
|
|
3196
|
+
}
|
|
3197
|
+
|
|
1376
3198
|
// src/cli.ts
|
|
3199
|
+
function behind(daemonVersion) {
|
|
3200
|
+
return daemonVersion === undefined || newer(package_default.version, daemonVersion);
|
|
3201
|
+
}
|
|
1377
3202
|
async function open(cmd) {
|
|
1378
3203
|
const explicit = cmd.path !== null;
|
|
1379
3204
|
const target = resolve(cmd.path ?? process.cwd());
|
|
1380
|
-
const register = explicit || existsSync10(
|
|
3205
|
+
const register = explicit || existsSync10(join8(target, ".git"));
|
|
1381
3206
|
if (process.platform === "linux") {
|
|
1382
3207
|
const missing = missingSandboxTools();
|
|
1383
3208
|
const blocked = missing.length === 0 ? bwrapStartError() : null;
|
|
@@ -1386,12 +3211,15 @@ async function open(cmd) {
|
|
|
1386
3211
|
else if (blocked)
|
|
1387
3212
|
console.log(bwrapBlockedAdvice(blocked, userNamespacesRestricted()));
|
|
1388
3213
|
}
|
|
1389
|
-
|
|
3214
|
+
const running = await health();
|
|
3215
|
+
if (!running) {
|
|
1390
3216
|
console.log("starting Toyon daemon\u2026");
|
|
1391
3217
|
if (!await startDaemon()) {
|
|
1392
3218
|
console.error(`daemon failed to start; \`toyon logs\` shows why (${logFile})`);
|
|
1393
3219
|
return 1;
|
|
1394
3220
|
}
|
|
3221
|
+
} else if (behind(running.version)) {
|
|
3222
|
+
console.log(`toyon: the running daemon is ${running.version ?? "older"}; \`toyon restart\` starts ${package_default.version}`);
|
|
1395
3223
|
}
|
|
1396
3224
|
const token = readToken();
|
|
1397
3225
|
if (!token) {
|
|
@@ -1442,13 +3270,20 @@ async function run(cmd) {
|
|
|
1442
3270
|
return 2;
|
|
1443
3271
|
case "version": {
|
|
1444
3272
|
const h = await health();
|
|
1445
|
-
|
|
3273
|
+
if (!h)
|
|
3274
|
+
console.log(`toyon ${package_default.version}`);
|
|
3275
|
+
else if (!behind(h.version))
|
|
3276
|
+
console.log(`toyon ${package_default.version} (daemon ${h.version} running)`);
|
|
3277
|
+
else
|
|
3278
|
+
console.log(`toyon ${package_default.version} (daemon ${h.version ?? "?"} running; \`toyon restart\` to update)`);
|
|
1446
3279
|
return 0;
|
|
1447
3280
|
}
|
|
1448
3281
|
case "stop":
|
|
1449
3282
|
return stop();
|
|
1450
3283
|
case "restart":
|
|
1451
3284
|
return restart();
|
|
3285
|
+
case "update":
|
|
3286
|
+
return update();
|
|
1452
3287
|
case "doctor":
|
|
1453
3288
|
return doctor();
|
|
1454
3289
|
case "logs":
|
|
@@ -1457,6 +3292,8 @@ async function run(cmd) {
|
|
|
1457
3292
|
return uninstall(cmd);
|
|
1458
3293
|
case "remote":
|
|
1459
3294
|
return remote(cmd);
|
|
3295
|
+
case "pair":
|
|
3296
|
+
return pair();
|
|
1460
3297
|
case "deploy":
|
|
1461
3298
|
return deploy(cmd);
|
|
1462
3299
|
case "open":
|