@bitmagic/cli 0.1.53-dev.3 → 0.1.53-dev.5
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 +76 -11
- package/dist/cli.d.ts +14 -0
- package/dist/cli.js +2 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/publish.d.ts +12 -0
- package/dist/commands/publish.js +15 -0
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/reset-account.js +25 -8
- package/dist/commands/reset-account.js.map +1 -1
- package/dist/commands/self-update.d.ts +67 -0
- package/dist/commands/self-update.js +196 -0
- package/dist/commands/self-update.js.map +1 -0
- package/dist/commands/upgrade.js +5 -2
- package/dist/commands/upgrade.js.map +1 -1
- package/dist/editor/cli-update.d.ts +32 -0
- package/dist/editor/cli-update.js +67 -0
- package/dist/editor/cli-update.js.map +1 -0
- package/dist/editor/server.js +7 -0
- package/dist/editor/server.js.map +1 -1
- package/dist/editor/shell-page.js +22 -1
- package/dist/editor/shell-page.js.map +1 -1
- package/dist/render/qr-terminal.d.ts +56 -0
- package/dist/render/qr-terminal.js +135 -0
- package/dist/render/qr-terminal.js.map +1 -0
- package/dist/render/qr.d.ts +51 -0
- package/dist/render/qr.js +516 -0
- package/dist/render/qr.js.map +1 -0
- package/dist/scaffold/project-files.js +31 -27
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/update/notice.d.ts +31 -1
- package/dist/update/notice.js +39 -5
- package/dist/update/notice.js.map +1 -1
- package/dist/update/self-install.d.ts +175 -0
- package/dist/update/self-install.js +335 -0
- package/dist/update/self-install.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A QR encoder, so `bitmagic publish` can hand the creator's phone the URL it just printed.
|
|
3
|
+
*
|
|
4
|
+
* The Creator does this server-side already — `PublishController.generateQRCode` calls the `qrcode`
|
|
5
|
+
* package and the publish dialog shows the PNG. The CLI cannot follow it there: `qrcode` drags in
|
|
6
|
+
* `dijkstrajs`, `pngjs` and `yargs@15`, and `@bitmagic/cli` is a published package with four
|
|
7
|
+
* deliberately-chosen runtime dependencies. So the encoder lives here instead, cut down to exactly
|
|
8
|
+
* what a published-game URL needs:
|
|
9
|
+
*
|
|
10
|
+
* - **Byte mode only.** A URL is bytes. Numeric, alphanumeric and kanji modes would encode it
|
|
11
|
+
* smaller in theory and never in practice, because `https://` alone rules out alphanumeric.
|
|
12
|
+
* - **Error correction level M only**, matching the Creator's `errorCorrectionLevel: 'M'` — a code
|
|
13
|
+
* scanned from this terminal and one scanned from the publish dialog then behave identically.
|
|
14
|
+
* - **Versions 1-9 only.** The character-count indicator is 8 bits up to version 9 and 16 bits
|
|
15
|
+
* from version 10, so stopping here removes a branch and four tables. Version 9 holds 180 bytes;
|
|
16
|
+
* the longest URL this ever sees is the dev portal's, around 60. Anything longer returns null
|
|
17
|
+
* rather than growing the tables — see `encodeQr`.
|
|
18
|
+
*
|
|
19
|
+
* Structure follows ISO/IEC 18004. Every table below is a literal with the spec's own name for it,
|
|
20
|
+
* and `__tests__/qr.test.ts` checks each one against fixtures generated by the `qrcode` package, so
|
|
21
|
+
* a transposed digit fails loudly instead of producing a code that scans as garbage.
|
|
22
|
+
*/
|
|
23
|
+
import { Buffer } from 'buffer';
|
|
24
|
+
/** The largest symbol version this encoder builds. Above it the count indicator widens to 16 bits. */
|
|
25
|
+
const MAX_VERSION = 9;
|
|
26
|
+
/** Byte mode's 4-bit mode indicator (ISO/IEC 18004 table 2). */
|
|
27
|
+
const MODE_BYTE = 0b0100;
|
|
28
|
+
/** The two padding codewords, applied alternately to fill the data capacity (11.2.1). */
|
|
29
|
+
const PAD_CODEWORDS = [0xec, 0x11];
|
|
30
|
+
const BLOCKS_M = [
|
|
31
|
+
{ ecPerBlock: 10, group1Blocks: 1, group1Data: 16, group2Blocks: 0, group2Data: 0 }, // v1 = 26
|
|
32
|
+
{ ecPerBlock: 16, group1Blocks: 1, group1Data: 28, group2Blocks: 0, group2Data: 0 }, // v2 = 44
|
|
33
|
+
{ ecPerBlock: 26, group1Blocks: 1, group1Data: 44, group2Blocks: 0, group2Data: 0 }, // v3 = 70
|
|
34
|
+
{ ecPerBlock: 18, group1Blocks: 2, group1Data: 32, group2Blocks: 0, group2Data: 0 }, // v4 = 100
|
|
35
|
+
{ ecPerBlock: 24, group1Blocks: 2, group1Data: 43, group2Blocks: 0, group2Data: 0 }, // v5 = 134
|
|
36
|
+
{ ecPerBlock: 16, group1Blocks: 4, group1Data: 27, group2Blocks: 0, group2Data: 0 }, // v6 = 172
|
|
37
|
+
{ ecPerBlock: 18, group1Blocks: 4, group1Data: 31, group2Blocks: 0, group2Data: 0 }, // v7 = 196
|
|
38
|
+
{ ecPerBlock: 22, group1Blocks: 2, group1Data: 38, group2Blocks: 2, group2Data: 39 }, // v8 = 242
|
|
39
|
+
{ ecPerBlock: 22, group1Blocks: 3, group1Data: 36, group2Blocks: 2, group2Data: 37 }, // v9 = 292
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Alignment-pattern centre coordinates per version (ISO/IEC 18004 annex E).
|
|
43
|
+
*
|
|
44
|
+
* A pattern is drawn at every pairing of these coordinates except where it would collide with a
|
|
45
|
+
* finder — `drawAlignmentPatterns` skips those by checking whether the module is already set.
|
|
46
|
+
*/
|
|
47
|
+
const ALIGNMENT_POSITIONS = [
|
|
48
|
+
[], // v1 has none
|
|
49
|
+
[6, 18],
|
|
50
|
+
[6, 22],
|
|
51
|
+
[6, 26],
|
|
52
|
+
[6, 30],
|
|
53
|
+
[6, 34],
|
|
54
|
+
[6, 22, 38],
|
|
55
|
+
[6, 24, 42],
|
|
56
|
+
[6, 26, 46],
|
|
57
|
+
];
|
|
58
|
+
/**
|
|
59
|
+
* The 15-bit format-information strings for level M and mask 0-7 (ISO/IEC 18004 table C.1).
|
|
60
|
+
*
|
|
61
|
+
* Already BCH(15,5)-encoded and XORed with the 0b101010000010010 mask the spec applies, so nothing
|
|
62
|
+
* here has to be computed. Level M is the only row we need, which is why this is a flat array.
|
|
63
|
+
*/
|
|
64
|
+
const FORMAT_INFO_M = [0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0];
|
|
65
|
+
/**
|
|
66
|
+
* The 18-bit version-information strings, which only versions 7 and up carry (table D.1).
|
|
67
|
+
*
|
|
68
|
+
* Indexed by version, so entries 1-6 are zero and never read.
|
|
69
|
+
*/
|
|
70
|
+
const VERSION_INFO = { 7: 0x07c94, 8: 0x085bc, 9: 0x09a99 };
|
|
71
|
+
/** Penalty weights for the four mask-evaluation rules (ISO/IEC 18004 table 24). */
|
|
72
|
+
const PENALTY_N1 = 3;
|
|
73
|
+
const PENALTY_N2 = 3;
|
|
74
|
+
const PENALTY_N3 = 40;
|
|
75
|
+
const PENALTY_N4 = 10;
|
|
76
|
+
/**
|
|
77
|
+
* The eight data-mask patterns (table 23). True means "invert this module".
|
|
78
|
+
*
|
|
79
|
+
* `row`/`col` are the spec's i/j. These apply to encoding-region modules only; function patterns
|
|
80
|
+
* are written before masking and are never touched, which `placeData` enforces by only filling
|
|
81
|
+
* modules still left null.
|
|
82
|
+
*/
|
|
83
|
+
const MASK_FUNCTIONS = [
|
|
84
|
+
(row, col) => (row + col) % 2 === 0,
|
|
85
|
+
(row) => row % 2 === 0,
|
|
86
|
+
(_row, col) => col % 3 === 0,
|
|
87
|
+
(row, col) => (row + col) % 3 === 0,
|
|
88
|
+
(row, col) => (Math.floor(row / 2) + Math.floor(col / 3)) % 2 === 0,
|
|
89
|
+
(row, col) => ((row * col) % 2) + ((row * col) % 3) === 0,
|
|
90
|
+
(row, col) => (((row * col) % 2) + ((row * col) % 3)) % 2 === 0,
|
|
91
|
+
(row, col) => (((row + col) % 2) + ((row * col) % 3)) % 2 === 0,
|
|
92
|
+
];
|
|
93
|
+
// ---------------------------------------------------------------------------------------------
|
|
94
|
+
// GF(256) arithmetic, for Reed-Solomon
|
|
95
|
+
// ---------------------------------------------------------------------------------------------
|
|
96
|
+
/**
|
|
97
|
+
* Exponent and log tables over GF(256) with primitive polynomial 0x11d and generator 2 (annex B).
|
|
98
|
+
*
|
|
99
|
+
* The exponent table runs to 512 entries — a doubled copy — so `gfMul` can add two logs (each up to
|
|
100
|
+
* 254) and index straight in without a modulo.
|
|
101
|
+
*/
|
|
102
|
+
function buildGaloisTables() {
|
|
103
|
+
const exp = new Uint8Array(512);
|
|
104
|
+
const log = new Uint8Array(256);
|
|
105
|
+
let value = 1;
|
|
106
|
+
for (let i = 0; i < 255; i += 1) {
|
|
107
|
+
exp[i] = value;
|
|
108
|
+
log[value] = i;
|
|
109
|
+
value <<= 1;
|
|
110
|
+
if ((value & 0x100) !== 0)
|
|
111
|
+
value ^= 0x11d;
|
|
112
|
+
}
|
|
113
|
+
for (let i = 255; i < 512; i += 1)
|
|
114
|
+
exp[i] = exp[i - 255];
|
|
115
|
+
return { exp, log };
|
|
116
|
+
}
|
|
117
|
+
const { exp: GF_EXP, log: GF_LOG } = buildGaloisTables();
|
|
118
|
+
function gfMultiply(a, b) {
|
|
119
|
+
if (a === 0 || b === 0)
|
|
120
|
+
return 0;
|
|
121
|
+
return GF_EXP[GF_LOG[a] + GF_LOG[b]];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The generator polynomial of the given degree, in descending coefficient order.
|
|
125
|
+
*
|
|
126
|
+
* Built as the product of (x - a^0)(x - a^1)...; subtraction is XOR in GF(2), so the sign vanishes.
|
|
127
|
+
*/
|
|
128
|
+
function generatorPolynomial(degree) {
|
|
129
|
+
let poly = Uint8Array.from([1]);
|
|
130
|
+
for (let d = 0; d < degree; d += 1) {
|
|
131
|
+
const next = new Uint8Array(poly.length + 1);
|
|
132
|
+
for (let i = 0; i < poly.length; i += 1) {
|
|
133
|
+
next[i] ^= poly[i];
|
|
134
|
+
next[i + 1] ^= gfMultiply(poly[i], GF_EXP[d]);
|
|
135
|
+
}
|
|
136
|
+
poly = next;
|
|
137
|
+
}
|
|
138
|
+
return poly;
|
|
139
|
+
}
|
|
140
|
+
/** The `ecLength` error-correction codewords for one block of data codewords. */
|
|
141
|
+
function reedSolomon(data, ecLength) {
|
|
142
|
+
const generator = generatorPolynomial(ecLength);
|
|
143
|
+
// Long division of `data` shifted up by ecLength places; the remainder is the ECC.
|
|
144
|
+
const remainder = new Uint8Array(data.length + ecLength);
|
|
145
|
+
remainder.set(data);
|
|
146
|
+
for (let i = 0; i < data.length; i += 1) {
|
|
147
|
+
const factor = remainder[i];
|
|
148
|
+
if (factor === 0)
|
|
149
|
+
continue;
|
|
150
|
+
for (let j = 0; j < generator.length; j += 1) {
|
|
151
|
+
remainder[i + j] ^= gfMultiply(generator[j], factor);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return remainder.slice(data.length);
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------------------------
|
|
157
|
+
// Codewords
|
|
158
|
+
// ---------------------------------------------------------------------------------------------
|
|
159
|
+
function totalDataCodewords(spec) {
|
|
160
|
+
return spec.group1Blocks * spec.group1Data + spec.group2Blocks * spec.group2Data;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* How many bytes fit at this version, in byte mode at level M.
|
|
164
|
+
*
|
|
165
|
+
* The header costs 12 bits — 4 for the mode indicator plus 8 for the count — so the payload gets
|
|
166
|
+
* the data capacity less one and a half codewords, rounded down.
|
|
167
|
+
*/
|
|
168
|
+
function byteCapacity(version) {
|
|
169
|
+
return Math.floor((totalDataCodewords(BLOCKS_M[version - 1]) * 8 - 12) / 8);
|
|
170
|
+
}
|
|
171
|
+
/** The smallest version that holds `byteLength` bytes, or null when even version 9 does not. */
|
|
172
|
+
function smallestVersion(byteLength) {
|
|
173
|
+
for (let version = 1; version <= MAX_VERSION; version += 1) {
|
|
174
|
+
if (byteLength <= byteCapacity(version))
|
|
175
|
+
return version;
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* The final codeword sequence: header, payload, padding, ECC, interleaved as the spec requires.
|
|
181
|
+
*
|
|
182
|
+
* Interleaving (8.6) is what makes a burst of damage survivable — consecutive codewords in the
|
|
183
|
+
* symbol come from different blocks, so a smudge spreads its errors across every block's budget
|
|
184
|
+
* instead of exhausting one.
|
|
185
|
+
*/
|
|
186
|
+
function buildCodewords(payload, version) {
|
|
187
|
+
const spec = BLOCKS_M[version - 1];
|
|
188
|
+
const dataCodewordCount = totalDataCodewords(spec);
|
|
189
|
+
const capacityBits = dataCodewordCount * 8;
|
|
190
|
+
const bits = [];
|
|
191
|
+
const pushBits = (value, length) => {
|
|
192
|
+
for (let i = length - 1; i >= 0; i -= 1)
|
|
193
|
+
bits.push((value >>> i) & 1);
|
|
194
|
+
};
|
|
195
|
+
pushBits(MODE_BYTE, 4);
|
|
196
|
+
pushBits(payload.length, 8);
|
|
197
|
+
for (const byte of payload)
|
|
198
|
+
pushBits(byte, 8);
|
|
199
|
+
// Terminator: up to four zero bits, truncated if the capacity ends first (11.1).
|
|
200
|
+
for (let i = 0; i < 4 && bits.length < capacityBits; i += 1)
|
|
201
|
+
bits.push(0);
|
|
202
|
+
while (bits.length % 8 !== 0)
|
|
203
|
+
bits.push(0);
|
|
204
|
+
const data = new Uint8Array(dataCodewordCount);
|
|
205
|
+
for (let i = 0; i < bits.length; i += 1) {
|
|
206
|
+
if (bits[i] === 1)
|
|
207
|
+
data[i >> 3] |= 0x80 >> (i & 7);
|
|
208
|
+
}
|
|
209
|
+
for (let i = bits.length / 8, pad = 0; i < dataCodewordCount; i += 1, pad += 1) {
|
|
210
|
+
data[i] = PAD_CODEWORDS[pad % 2];
|
|
211
|
+
}
|
|
212
|
+
const blocks = [];
|
|
213
|
+
let offset = 0;
|
|
214
|
+
const groups = [
|
|
215
|
+
[spec.group1Blocks, spec.group1Data],
|
|
216
|
+
[spec.group2Blocks, spec.group2Data],
|
|
217
|
+
];
|
|
218
|
+
for (const [count, size] of groups) {
|
|
219
|
+
for (let b = 0; b < count; b += 1) {
|
|
220
|
+
const chunk = data.slice(offset, offset + size);
|
|
221
|
+
offset += size;
|
|
222
|
+
blocks.push({ data: chunk, ec: reedSolomon(chunk, spec.ecPerBlock) });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const out = [];
|
|
226
|
+
const longestBlock = Math.max(spec.group1Data, spec.group2Data);
|
|
227
|
+
for (let i = 0; i < longestBlock; i += 1) {
|
|
228
|
+
for (const block of blocks) {
|
|
229
|
+
if (i < block.data.length)
|
|
230
|
+
out.push(block.data[i]);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
for (let i = 0; i < spec.ecPerBlock; i += 1) {
|
|
234
|
+
for (const block of blocks)
|
|
235
|
+
out.push(block.ec[i]);
|
|
236
|
+
}
|
|
237
|
+
return Uint8Array.from(out);
|
|
238
|
+
}
|
|
239
|
+
function moduleCount(version) {
|
|
240
|
+
return version * 4 + 17;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* One finder pattern with its separator, anchored at the given top-left module.
|
|
244
|
+
*
|
|
245
|
+
* The loop runs from -1 to 7 rather than 0 to 6 so the one-module separator is written in the same
|
|
246
|
+
* pass, as false. Out-of-range coordinates are skipped, which is what keeps the three call sites
|
|
247
|
+
* identical despite each finder having its separator on different sides.
|
|
248
|
+
*/
|
|
249
|
+
function drawFinderPattern(grid, row, col) {
|
|
250
|
+
const size = grid.length;
|
|
251
|
+
for (let r = -1; r <= 7; r += 1) {
|
|
252
|
+
if (row + r < 0 || row + r >= size)
|
|
253
|
+
continue;
|
|
254
|
+
for (let c = -1; c <= 7; c += 1) {
|
|
255
|
+
if (col + c < 0 || col + c >= size)
|
|
256
|
+
continue;
|
|
257
|
+
const onOuterRing = (r >= 0 && r <= 6 && (c === 0 || c === 6))
|
|
258
|
+
|| (c >= 0 && c <= 6 && (r === 0 || r === 6));
|
|
259
|
+
const inCore = r >= 2 && r <= 4 && c >= 2 && c <= 4;
|
|
260
|
+
grid[row + r][col + c] = onOuterRing || inCore;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function drawTimingPatterns(grid) {
|
|
265
|
+
const size = grid.length;
|
|
266
|
+
for (let i = 8; i < size - 8; i += 1) {
|
|
267
|
+
if (grid[i][6] === null)
|
|
268
|
+
grid[i][6] = i % 2 === 0;
|
|
269
|
+
if (grid[6][i] === null)
|
|
270
|
+
grid[6][i] = i % 2 === 0;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function drawAlignmentPatterns(grid, version) {
|
|
274
|
+
const positions = ALIGNMENT_POSITIONS[version - 1];
|
|
275
|
+
for (const row of positions) {
|
|
276
|
+
for (const col of positions) {
|
|
277
|
+
// Already written means a finder owns this corner; the spec omits the pattern there.
|
|
278
|
+
if (grid[row][col] !== null)
|
|
279
|
+
continue;
|
|
280
|
+
for (let r = -2; r <= 2; r += 1) {
|
|
281
|
+
for (let c = -2; c <= 2; c += 1) {
|
|
282
|
+
grid[row + r][col + c] = r === -2 || r === 2 || c === -2 || c === 2 || (r === 0 && c === 0);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* The two copies of the format information, plus the always-dark module beside the bottom-left
|
|
290
|
+
* finder (8.9). Written before the data so `placeData` treats these positions as occupied.
|
|
291
|
+
*/
|
|
292
|
+
function drawFormatInfo(grid, mask) {
|
|
293
|
+
const size = grid.length;
|
|
294
|
+
const bits = FORMAT_INFO_M[mask];
|
|
295
|
+
for (let i = 0; i < 15; i += 1) {
|
|
296
|
+
const dark = ((bits >> i) & 1) === 1;
|
|
297
|
+
// Copy one, running down the left of the top-left finder and skipping the timing row.
|
|
298
|
+
if (i < 6)
|
|
299
|
+
grid[i][8] = dark;
|
|
300
|
+
else if (i < 8)
|
|
301
|
+
grid[i + 1][8] = dark;
|
|
302
|
+
else
|
|
303
|
+
grid[size - 15 + i][8] = dark;
|
|
304
|
+
// Copy two, running left from the top-right corner and continuing under the top-left finder.
|
|
305
|
+
if (i < 8)
|
|
306
|
+
grid[8][size - i - 1] = dark;
|
|
307
|
+
else if (i < 9)
|
|
308
|
+
grid[8][15 - i] = dark;
|
|
309
|
+
else
|
|
310
|
+
grid[8][14 - i] = dark;
|
|
311
|
+
}
|
|
312
|
+
grid[size - 8][8] = true;
|
|
313
|
+
}
|
|
314
|
+
/** The two copies of the version information, for versions 7 and up only (8.10). */
|
|
315
|
+
function drawVersionInfo(grid, version) {
|
|
316
|
+
if (version < 7)
|
|
317
|
+
return;
|
|
318
|
+
const size = grid.length;
|
|
319
|
+
const bits = VERSION_INFO[version];
|
|
320
|
+
for (let i = 0; i < 18; i += 1) {
|
|
321
|
+
const dark = ((bits >> i) & 1) === 1;
|
|
322
|
+
const major = Math.floor(i / 3);
|
|
323
|
+
const minor = i % 3;
|
|
324
|
+
grid[major][size - 11 + minor] = dark;
|
|
325
|
+
grid[size - 11 + minor][major] = dark;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Fill the encoding region with the codeword bits, masking as we go.
|
|
330
|
+
*
|
|
331
|
+
* The walk is the spec's: two-module-wide columns from the right edge leftwards, alternating
|
|
332
|
+
* upward and downward, right module of the pair before the left. Column 6 is the vertical timing
|
|
333
|
+
* pattern and is stepped over entirely rather than skipped module by module.
|
|
334
|
+
*
|
|
335
|
+
* Running out of codewords is not an error — versions 2 to 6 have leftover remainder bits, which
|
|
336
|
+
* the spec fills with zeros. They still get masked, which is why this cannot just stop early.
|
|
337
|
+
*/
|
|
338
|
+
function placeData(grid, codewords, mask) {
|
|
339
|
+
const size = grid.length;
|
|
340
|
+
const maskFn = MASK_FUNCTIONS[mask];
|
|
341
|
+
let bitIndex = 7;
|
|
342
|
+
let byteIndex = 0;
|
|
343
|
+
let row = size - 1;
|
|
344
|
+
let upward = true;
|
|
345
|
+
for (let col = size - 1; col > 0; col -= 2) {
|
|
346
|
+
if (col === 6)
|
|
347
|
+
col -= 1;
|
|
348
|
+
for (;;) {
|
|
349
|
+
for (let c = 0; c < 2; c += 1) {
|
|
350
|
+
if (grid[row][col - c] !== null)
|
|
351
|
+
continue;
|
|
352
|
+
let dark = false;
|
|
353
|
+
if (byteIndex < codewords.length) {
|
|
354
|
+
dark = ((codewords[byteIndex] >>> bitIndex) & 1) === 1;
|
|
355
|
+
}
|
|
356
|
+
if (maskFn(row, col - c))
|
|
357
|
+
dark = !dark;
|
|
358
|
+
grid[row][col - c] = dark;
|
|
359
|
+
bitIndex -= 1;
|
|
360
|
+
if (bitIndex === -1) {
|
|
361
|
+
byteIndex += 1;
|
|
362
|
+
bitIndex = 7;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
row += upward ? -1 : 1;
|
|
366
|
+
if (row < 0 || row >= size) {
|
|
367
|
+
row -= upward ? -1 : 1;
|
|
368
|
+
upward = !upward;
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function buildSymbol(codewords, version, mask) {
|
|
375
|
+
const size = moduleCount(version);
|
|
376
|
+
const grid = Array.from({ length: size }, () => new Array(size).fill(null));
|
|
377
|
+
drawFinderPattern(grid, 0, 0);
|
|
378
|
+
drawFinderPattern(grid, size - 7, 0);
|
|
379
|
+
drawFinderPattern(grid, 0, size - 7);
|
|
380
|
+
drawAlignmentPatterns(grid, version);
|
|
381
|
+
drawTimingPatterns(grid);
|
|
382
|
+
drawFormatInfo(grid, mask);
|
|
383
|
+
drawVersionInfo(grid, version);
|
|
384
|
+
placeData(grid, codewords, mask);
|
|
385
|
+
// Every module is written by now: the function patterns above cover the whole reserved area, and
|
|
386
|
+
// placeData fills every remaining null. The cast is the only place this file assumes that.
|
|
387
|
+
return grid.map((row) => row.map((module) => module === true));
|
|
388
|
+
}
|
|
389
|
+
// ---------------------------------------------------------------------------------------------
|
|
390
|
+
// Mask selection
|
|
391
|
+
// ---------------------------------------------------------------------------------------------
|
|
392
|
+
/**
|
|
393
|
+
* The spec's four penalty rules (8.8.2), summed. Lower is better.
|
|
394
|
+
*
|
|
395
|
+
* Scored over the entire symbol including function patterns, as the spec requires — the finders'
|
|
396
|
+
* own 1:1:3:1:1 ratio is exactly what rule 3 hunts for elsewhere, and excluding them would let a
|
|
397
|
+
* mask hide a false finder against a real one.
|
|
398
|
+
*/
|
|
399
|
+
export function maskPenalty(matrix) {
|
|
400
|
+
const size = matrix.length;
|
|
401
|
+
let points = 0;
|
|
402
|
+
// Rule 1: runs of five or more same-coloured modules in a row or column.
|
|
403
|
+
for (let a = 0; a < size; a += 1) {
|
|
404
|
+
let runRow = 1;
|
|
405
|
+
let runCol = 1;
|
|
406
|
+
for (let b = 1; b < size; b += 1) {
|
|
407
|
+
if (matrix[a][b] === matrix[a][b - 1])
|
|
408
|
+
runRow += 1;
|
|
409
|
+
else {
|
|
410
|
+
if (runRow >= 5)
|
|
411
|
+
points += PENALTY_N1 + (runRow - 5);
|
|
412
|
+
runRow = 1;
|
|
413
|
+
}
|
|
414
|
+
if (matrix[b][a] === matrix[b - 1][a])
|
|
415
|
+
runCol += 1;
|
|
416
|
+
else {
|
|
417
|
+
if (runCol >= 5)
|
|
418
|
+
points += PENALTY_N1 + (runCol - 5);
|
|
419
|
+
runCol = 1;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (runRow >= 5)
|
|
423
|
+
points += PENALTY_N1 + (runRow - 5);
|
|
424
|
+
if (runCol >= 5)
|
|
425
|
+
points += PENALTY_N1 + (runCol - 5);
|
|
426
|
+
}
|
|
427
|
+
// Rule 2: every 2x2 block of one colour.
|
|
428
|
+
for (let row = 0; row < size - 1; row += 1) {
|
|
429
|
+
for (let col = 0; col < size - 1; col += 1) {
|
|
430
|
+
const dark = matrix[row][col];
|
|
431
|
+
if (matrix[row][col + 1] === dark
|
|
432
|
+
&& matrix[row + 1][col] === dark
|
|
433
|
+
&& matrix[row + 1][col + 1] === dark) {
|
|
434
|
+
points += PENALTY_N2;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
// Rule 3: the 1:1:3:1:1 finder ratio with four light modules on one side, either orientation.
|
|
439
|
+
// Tracked as an 11-bit sliding window per row and per column; 0x5d0 is 10111010000 and 0x05d is
|
|
440
|
+
// 00001011101.
|
|
441
|
+
for (let a = 0; a < size; a += 1) {
|
|
442
|
+
let windowRow = 0;
|
|
443
|
+
let windowCol = 0;
|
|
444
|
+
for (let b = 0; b < size; b += 1) {
|
|
445
|
+
windowRow = ((windowRow << 1) & 0x7ff) | (matrix[a][b] ? 1 : 0);
|
|
446
|
+
windowCol = ((windowCol << 1) & 0x7ff) | (matrix[b][a] ? 1 : 0);
|
|
447
|
+
if (b < 10)
|
|
448
|
+
continue;
|
|
449
|
+
if (windowRow === 0x5d0 || windowRow === 0x05d)
|
|
450
|
+
points += PENALTY_N3;
|
|
451
|
+
if (windowCol === 0x5d0 || windowCol === 0x05d)
|
|
452
|
+
points += PENALTY_N3;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
// Rule 4: how far the proportion of dark modules strays from half, in five-percent steps.
|
|
456
|
+
let dark = 0;
|
|
457
|
+
for (const row of matrix) {
|
|
458
|
+
for (const module of row) {
|
|
459
|
+
if (module)
|
|
460
|
+
dark += 1;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const percent = (dark * 100) / (size * size);
|
|
464
|
+
points += Math.floor(Math.abs(percent - 50) / 5) * PENALTY_N4;
|
|
465
|
+
return points;
|
|
466
|
+
}
|
|
467
|
+
// ---------------------------------------------------------------------------------------------
|
|
468
|
+
// Public surface
|
|
469
|
+
// ---------------------------------------------------------------------------------------------
|
|
470
|
+
/**
|
|
471
|
+
* Encode `text` with an explicitly chosen mask.
|
|
472
|
+
*
|
|
473
|
+
* Exported for the fixture tests, which pin the mask so they compare structure — codewords, ECC,
|
|
474
|
+
* interleaving, function patterns, format bits — rather than a mask heuristic. Callers outside the
|
|
475
|
+
* tests want `encodeQr`.
|
|
476
|
+
*/
|
|
477
|
+
export function encodeQrWithMask(text, mask) {
|
|
478
|
+
if (mask < 0 || mask > 7)
|
|
479
|
+
return null;
|
|
480
|
+
const payload = Buffer.from(text, 'utf8');
|
|
481
|
+
const version = smallestVersion(payload.length);
|
|
482
|
+
if (version === null)
|
|
483
|
+
return null;
|
|
484
|
+
return buildSymbol(buildCodewords(payload, version), version, mask);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Encode `text` as a matrix of modules, row-major, true meaning dark. Null when it does not fit.
|
|
488
|
+
*
|
|
489
|
+
* The mask is chosen by the spec's penalty rules. That choice is a legibility heuristic and not a
|
|
490
|
+
* correctness property — all eight masks produce a valid, scannable symbol, and a decoder reads the
|
|
491
|
+
* chosen one out of the format information either way.
|
|
492
|
+
*
|
|
493
|
+
* There is no quiet zone here: it belongs to whatever draws the symbol, which knows what it is
|
|
494
|
+
* drawing onto. `qr-terminal.ts` paints its own.
|
|
495
|
+
*/
|
|
496
|
+
export function encodeQr(text) {
|
|
497
|
+
const payload = Buffer.from(text, 'utf8');
|
|
498
|
+
const version = smallestVersion(payload.length);
|
|
499
|
+
if (version === null)
|
|
500
|
+
return null;
|
|
501
|
+
const codewords = buildCodewords(payload, version);
|
|
502
|
+
let best = null;
|
|
503
|
+
let bestPenalty = Number.POSITIVE_INFINITY;
|
|
504
|
+
for (let mask = 0; mask < 8; mask += 1) {
|
|
505
|
+
const candidate = buildSymbol(codewords, version, mask);
|
|
506
|
+
const penalty = maskPenalty(candidate);
|
|
507
|
+
if (penalty < bestPenalty) {
|
|
508
|
+
bestPenalty = penalty;
|
|
509
|
+
best = candidate;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
return best;
|
|
513
|
+
}
|
|
514
|
+
/** The longest text this encoder can hold, in bytes. Exported so a caller can explain a refusal. */
|
|
515
|
+
export const MAX_BYTES = byteCapacity(MAX_VERSION);
|
|
516
|
+
//# sourceMappingURL=qr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr.js","sourceRoot":"","sources":["../../src/render/qr.ts"],"names":[],"mappings":"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"}
|
|
@@ -396,45 +396,49 @@ export function renderBitmagicJson(metadata) {
|
|
|
396
396
|
return renderJson(metadata);
|
|
397
397
|
}
|
|
398
398
|
/**
|
|
399
|
-
* The "Updating the bitmagic CLI" section, which
|
|
400
|
-
* still being asked.
|
|
399
|
+
* The "Updating the bitmagic CLI" section, which used to have two jobs and now has one.
|
|
401
400
|
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
401
|
+
* It began as an answer to a question the project already answered: an agent told to update the CLI
|
|
402
|
+
* had two published lines to choose from, nothing in the project naming one, and so asked the
|
|
403
|
+
* creator "dev or prod?". The section baked in the right `npm i -g` for the pin and forbade the
|
|
404
|
+
* question.
|
|
406
405
|
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
406
|
+
* That instruction was right about the line and wrong about the mechanism. A printed `npm i -g` is
|
|
407
|
+
* run by whatever `npm` the agent's shell resolves, and a coding agent's non-interactive shell
|
|
408
|
+
* sources no profile — under nvm it gets a different node's npm, installs into a prefix nothing on
|
|
409
|
+
* PATH points at, and reports success while `bitmagic --version` never moves. `bitmagic
|
|
410
|
+
* self-update` resolves its own install from the running process and reads the pin itself, so the
|
|
411
|
+
* whole two-line explanation collapses into one command that cannot be aimed at the wrong place or
|
|
412
|
+
* the wrong line. What remains of the old paragraph is the *why*, which an agent still needs when
|
|
413
|
+
* something looks wrong — not a choice for it to make.
|
|
410
414
|
*
|
|
411
|
-
* `environment` is undefined for a project scaffolded before the pin existed.
|
|
412
|
-
*
|
|
413
|
-
*
|
|
415
|
+
* `environment` is undefined for a project scaffolded before the pin existed. The command still
|
|
416
|
+
* works there (it falls back to the line the installed build is on), so that case only loses the
|
|
417
|
+
* sentence naming this project's environment.
|
|
414
418
|
*/
|
|
415
419
|
function renderCliUpdateSection(environment) {
|
|
416
|
-
const install = environment === 'prod' ? 'npm i -g @bitmagic/cli' : 'npm i -g @bitmagic/cli@dev';
|
|
417
420
|
const here = environment === undefined
|
|
418
421
|
? `This project predates the \`environment\` field of \`bitmagic.json\` and so has no pin yet.
|
|
419
|
-
Run \`bitmagic upgrade\` once to stamp one
|
|
420
|
-
meantime,
|
|
421
|
-
|
|
422
|
-
\`bitmagic.json\`),
|
|
422
|
+
Run \`bitmagic upgrade\` once to stamp one, and \`bitmagic whoami\` to see what the CLI resolves in
|
|
423
|
+
the meantime; until there is a pin, \`self-update\` keeps you on the line your installed build is
|
|
424
|
+
already on.`
|
|
425
|
+
: `This project is on the **${environment}** environment (\`environment\` in \`bitmagic.json\`), and the command reads that pin itself.`;
|
|
426
|
+
return `## Updating the bitmagic CLI
|
|
423
427
|
|
|
424
428
|
\`\`\`
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
return `## Updating the bitmagic CLI
|
|
429
|
+
bitmagic self-update
|
|
430
|
+
\`\`\`
|
|
428
431
|
|
|
429
432
|
${here}
|
|
430
433
|
|
|
431
|
-
**Never ask which line to install,
|
|
432
|
-
\`
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
with this paragraph, the file is right. The engine is a
|
|
434
|
+
**Never ask which line to install, never offer the choice, and never update with \`npm i -g @bitmagic/cli\`** —
|
|
435
|
+
\`self-update\` reinstalls into the exact place this CLI lives, using the node running it, which the \`npm\` on
|
|
436
|
+
your PATH may not be; under nvm it usually is not, and the install lands in another prefix while
|
|
437
|
+
\`bitmagic --version\` never moves. The lines are not interchangeable (\`dev\` and \`local\` take the prerelease
|
|
438
|
+
built against the dev api-server, \`prod\` the release), and the wrong one fails as opaque command errors
|
|
439
|
+
rather than version warnings — so run \`self-update\` before debugging a command that started failing
|
|
440
|
+
strangely. If \`bitmagic.json\` ever disagrees with this paragraph, the file is right. The engine is a
|
|
441
|
+
separate command: \`bitmagic upgrade\`.`;
|
|
438
442
|
}
|
|
439
443
|
export function renderAgentsMd(environment) {
|
|
440
444
|
return `# Working on this Bitmagic game
|