@mylasertools/kerfscript 0.2.0 → 0.3.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.
Files changed (46) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/CLA.md +8 -5
  3. package/COMMERCIAL-LICENSE.md +23 -28
  4. package/LANGUAGE.md +194 -60
  5. package/README.md +89 -39
  6. package/THIRD-PARTY-NOTICES.md +68 -4
  7. package/TRADEMARKS.md +16 -10
  8. package/dist/cli.js +773 -297
  9. package/dist/evaluator.d.cts +26 -0
  10. package/dist/evaluator.d.ts +26 -0
  11. package/dist/export/dxf.d.cts +1 -1
  12. package/dist/export/dxf.d.ts +1 -1
  13. package/dist/export/svg.d.cts +2 -0
  14. package/dist/export/svg.d.ts +2 -0
  15. package/dist/font.d.cts +3 -0
  16. package/dist/font.d.ts +3 -0
  17. package/dist/functions.d.cts +21 -2
  18. package/dist/functions.d.ts +21 -2
  19. package/dist/index.cjs +14 -14
  20. package/dist/index.d.cts +2 -2
  21. package/dist/index.d.ts +2 -2
  22. package/dist/index.js +14 -14
  23. package/dist/lexer.d.cts +4 -1
  24. package/dist/lexer.d.ts +4 -1
  25. package/dist/parser.d.cts +1 -1
  26. package/dist/parser.d.ts +1 -1
  27. package/dist/render.d.cts +3 -2
  28. package/dist/render.d.ts +3 -2
  29. package/dist/values.d.cts +10 -2
  30. package/dist/values.d.ts +10 -2
  31. package/dist/wasm.d.cts +1 -0
  32. package/dist/wasm.d.ts +1 -0
  33. package/docs/cli.md +69 -28
  34. package/docs/compatibility.md +40 -65
  35. package/docs/customizer.md +40 -28
  36. package/docs/desktop.md +96 -0
  37. package/docs/getting-started.md +48 -31
  38. package/docs/javascript.md +108 -51
  39. package/docs/kerf.md +36 -39
  40. package/docs/layers.md +71 -37
  41. package/docs/openscad.md +52 -48
  42. package/docs/parts-and-sheets.md +45 -31
  43. package/docs/versions.md +20 -30
  44. package/docs/webassembly.md +131 -0
  45. package/fonts/OFL.txt +92 -0
  46. package/package.json +10 -6
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- /*! @mylasertools/kerfscript | (c) MyLaserTools | AGPL-3.0-only or commercial licence, see COMMERCIAL-LICENSE.md. Includes Clipper2 (BSL-1.0) and opentype.js (MIT), see THIRD-PARTY-NOTICES.md. */
2
+ /*! @mylasertools/kerfscript | (c) MyLaserTools | AGPL-3.0-only or commercial licence, see COMMERCIAL-LICENSE.md. Includes Clipper2 (BSL-1.0), opentype.js, tiny-inflate and string.prototype.codepointat (MIT), see THIRD-PARTY-NOTICES.md. */
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -31,6 +31,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
32
  mod
33
33
  ));
34
+ var __toBinaryNode = (base64) => new Uint8Array(Buffer.from(base64, "base64"));
34
35
 
35
36
  // node_modules/opentype.js/dist/opentype.js
36
37
  var require_opentype = __commonJS({
@@ -922,14 +923,14 @@ var require_opentype = __commonJS({
922
923
  }
923
924
  return encodingTable;
924
925
  };
925
- encode.MACSTRING = function(str2, encoding) {
926
+ encode.MACSTRING = function(str, encoding) {
926
927
  var table2 = getMacEncodingTable(encoding);
927
928
  if (table2 === void 0) {
928
929
  return void 0;
929
930
  }
930
931
  var result = [];
931
- for (var i = 0; i < str2.length; i++) {
932
- var c = str2.charCodeAt(i);
932
+ for (var i = 0; i < str.length; i++) {
933
+ var c = str.charCodeAt(i);
933
934
  if (c >= 128) {
934
935
  c = table2[c];
935
936
  if (c === void 0) {
@@ -940,8 +941,8 @@ var require_opentype = __commonJS({
940
941
  }
941
942
  return result;
942
943
  };
943
- sizeOf.MACSTRING = function(str2, encoding) {
944
- var b = encode.MACSTRING(str2, encoding);
944
+ sizeOf.MACSTRING = function(str, encoding) {
945
+ var b = encode.MACSTRING(str, encoding);
945
946
  if (b !== void 0) {
946
947
  return b.length;
947
948
  } else {
@@ -5687,18 +5688,18 @@ var require_opentype = __commonJS({
5687
5688
  var language = getLanguageCode(platformID, languageID, ltag2);
5688
5689
  var encoding = getEncoding(platformID, encodingID, languageID);
5689
5690
  if (encoding !== void 0 && language !== void 0) {
5690
- var text = void 0;
5691
+ var text2 = void 0;
5691
5692
  if (encoding === utf16) {
5692
- text = decode.UTF16(data, stringOffset + offset2, byteLength);
5693
+ text2 = decode.UTF16(data, stringOffset + offset2, byteLength);
5693
5694
  } else {
5694
- text = decode.MACSTRING(data, stringOffset + offset2, byteLength, encoding);
5695
+ text2 = decode.MACSTRING(data, stringOffset + offset2, byteLength, encoding);
5695
5696
  }
5696
- if (text) {
5697
+ if (text2) {
5697
5698
  var translations = name[property];
5698
5699
  if (translations === void 0) {
5699
5700
  translations = name[property] = {};
5700
5701
  }
5701
- translations[language] = text;
5702
+ translations[language] = text2;
5702
5703
  }
5703
5704
  }
5704
5705
  }
@@ -5778,12 +5779,12 @@ var require_opentype = __commonJS({
5778
5779
  nameID = nameIDs[i];
5779
5780
  var translations = namesWithNumericKeys[nameID];
5780
5781
  for (var lang in translations) {
5781
- var text = translations[lang];
5782
+ var text2 = translations[lang];
5782
5783
  var macPlatform = 1;
5783
5784
  var macLanguage = macLanguageIds[lang];
5784
5785
  var macScript = macLanguageToScript[macLanguage];
5785
5786
  var macEncoding = getEncoding(macPlatform, macScript, macLanguage);
5786
- var macName = encode.MACSTRING(text, macEncoding);
5787
+ var macName = encode.MACSTRING(text2, macEncoding);
5787
5788
  if (macName === void 0) {
5788
5789
  macPlatform = 0;
5789
5790
  macLanguage = ltag2.indexOf(lang);
@@ -5792,7 +5793,7 @@ var require_opentype = __commonJS({
5792
5793
  ltag2.push(lang);
5793
5794
  }
5794
5795
  macScript = 4;
5795
- macName = encode.UTF16(text);
5796
+ macName = encode.UTF16(text2);
5796
5797
  }
5797
5798
  var macNameOffset = addStringToPool(macName, stringPool);
5798
5799
  nameRecords.push(makeNameRecord(
@@ -5805,7 +5806,7 @@ var require_opentype = __commonJS({
5805
5806
  ));
5806
5807
  var winLanguage = windowsLanguageIds[lang];
5807
5808
  if (winLanguage !== void 0) {
5808
- var winName = encode.UTF16(text);
5809
+ var winName = encode.UTF16(text2);
5809
5810
  var winNameOffset = addStringToPool(winName, stringPool);
5810
5811
  nameRecords.push(makeNameRecord(
5811
5812
  3,
@@ -6537,8 +6538,8 @@ var require_opentype = __commonJS({
6537
6538
  var tag = p.parseTag();
6538
6539
  var dataOffset = p.parseULong();
6539
6540
  var dataLength = p.parseULong();
6540
- var text = decode.UTF8(data, start + dataOffset, dataLength);
6541
- tags[tag] = text;
6541
+ var text2 = decode.UTF8(data, start + dataOffset, dataLength);
6542
+ tags[tag] = text2;
6542
6543
  }
6543
6544
  return tags;
6544
6545
  }
@@ -10474,10 +10475,10 @@ var require_opentype = __commonJS({
10474
10475
  }
10475
10476
  });
10476
10477
  };
10477
- Tokenizer.prototype.tokenize = function(text) {
10478
+ Tokenizer.prototype.tokenize = function(text2) {
10478
10479
  this.tokens = [];
10479
10480
  this.resetContextsRanges();
10480
- var chars = Array.from(text);
10481
+ var chars = Array.from(text2);
10481
10482
  this.dispatch("start");
10482
10483
  for (var i = 0; i < chars.length; i++) {
10483
10484
  var char = chars[i];
@@ -11166,8 +11167,8 @@ var require_opentype = __commonJS({
11166
11167
  this.tokenizer = new Tokenizer();
11167
11168
  this.featuresTags = {};
11168
11169
  }
11169
- Bidi.prototype.setText = function(text) {
11170
- this.text = text;
11170
+ Bidi.prototype.setText = function(text2) {
11171
+ this.text = text2;
11171
11172
  };
11172
11173
  Bidi.prototype.contextChecks = {
11173
11174
  latinWordCheck,
@@ -11299,19 +11300,19 @@ var require_opentype = __commonJS({
11299
11300
  reverseArabicSentences.call(this);
11300
11301
  }
11301
11302
  };
11302
- Bidi.prototype.processText = function(text) {
11303
- if (!this.text || this.text !== text) {
11304
- this.setText(text);
11303
+ Bidi.prototype.processText = function(text2) {
11304
+ if (!this.text || this.text !== text2) {
11305
+ this.setText(text2);
11305
11306
  tokenizeText.call(this);
11306
11307
  this.applyFeaturesToContexts();
11307
11308
  }
11308
11309
  };
11309
- Bidi.prototype.getBidiText = function(text) {
11310
- this.processText(text);
11310
+ Bidi.prototype.getBidiText = function(text2) {
11311
+ this.processText(text2);
11311
11312
  return this.tokenizer.getText();
11312
11313
  };
11313
- Bidi.prototype.getTextGlyphs = function(text) {
11314
- this.processText(text);
11314
+ Bidi.prototype.getTextGlyphs = function(text2) {
11315
+ this.processText(text2);
11315
11316
  var indexes = [];
11316
11317
  for (var i = 0; i < this.tokenizer.tokens.length; i++) {
11317
11318
  var token = this.tokenizer.tokens[i];
@@ -11463,13 +11464,13 @@ var require_opentype = __commonJS({
11463
11464
  { script: "latn", tags: ["liga", "rlig"] }
11464
11465
  ]
11465
11466
  };
11466
- Font.prototype.forEachGlyph = function(text, x, y, fontSize, options, callback) {
11467
+ Font.prototype.forEachGlyph = function(text2, x, y, fontSize, options, callback) {
11467
11468
  x = x !== void 0 ? x : 0;
11468
11469
  y = y !== void 0 ? y : 0;
11469
11470
  fontSize = fontSize !== void 0 ? fontSize : 72;
11470
11471
  options = Object.assign({}, this.defaultRenderOptions, options);
11471
11472
  var fontScale = 1 / this.unitsPerEm * fontSize;
11472
- var glyphs = this.stringToGlyphs(text, options);
11473
+ var glyphs = this.stringToGlyphs(text2, options);
11473
11474
  var kerningLookups;
11474
11475
  if (options.kerning) {
11475
11476
  var script = options.script || this.position.getDefaultScriptName();
@@ -11493,36 +11494,36 @@ var require_opentype = __commonJS({
11493
11494
  }
11494
11495
  return x;
11495
11496
  };
11496
- Font.prototype.getPath = function(text, x, y, fontSize, options) {
11497
+ Font.prototype.getPath = function(text2, x, y, fontSize, options) {
11497
11498
  var fullPath = new Path();
11498
- this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11499
+ this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11499
11500
  var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
11500
11501
  fullPath.extend(glyphPath);
11501
11502
  });
11502
11503
  return fullPath;
11503
11504
  };
11504
- Font.prototype.getPaths = function(text, x, y, fontSize, options) {
11505
+ Font.prototype.getPaths = function(text2, x, y, fontSize, options) {
11505
11506
  var glyphPaths = [];
11506
- this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11507
+ this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11507
11508
  var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
11508
11509
  glyphPaths.push(glyphPath);
11509
11510
  });
11510
11511
  return glyphPaths;
11511
11512
  };
11512
- Font.prototype.getAdvanceWidth = function(text, fontSize, options) {
11513
- return this.forEachGlyph(text, 0, 0, fontSize, options, function() {
11513
+ Font.prototype.getAdvanceWidth = function(text2, fontSize, options) {
11514
+ return this.forEachGlyph(text2, 0, 0, fontSize, options, function() {
11514
11515
  });
11515
11516
  };
11516
- Font.prototype.draw = function(ctx, text, x, y, fontSize, options) {
11517
- this.getPath(text, x, y, fontSize, options).draw(ctx);
11517
+ Font.prototype.draw = function(ctx, text2, x, y, fontSize, options) {
11518
+ this.getPath(text2, x, y, fontSize, options).draw(ctx);
11518
11519
  };
11519
- Font.prototype.drawPoints = function(ctx, text, x, y, fontSize, options) {
11520
- this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11520
+ Font.prototype.drawPoints = function(ctx, text2, x, y, fontSize, options) {
11521
+ this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11521
11522
  glyph.drawPoints(ctx, gX, gY, gFontSize);
11522
11523
  });
11523
11524
  };
11524
- Font.prototype.drawMetrics = function(ctx, text, x, y, fontSize, options) {
11525
- this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11525
+ Font.prototype.drawMetrics = function(ctx, text2, x, y, fontSize, options) {
11526
+ this.forEachGlyph(text2, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
11526
11527
  glyph.drawMetrics(ctx, gX, gY, gFontSize);
11527
11528
  });
11528
11529
  };
@@ -12305,12 +12306,21 @@ import { basename, dirname, extname, join, resolve } from "node:path";
12305
12306
  var isRange = (v) => typeof v === "object" && v !== null && !Array.isArray(v) && v.type === "range";
12306
12307
  var isFn = (v) => typeof v === "object" && v !== null && !Array.isArray(v) && v.type === "function";
12307
12308
  var isNum = (v) => typeof v === "number";
12309
+ var own = (o, key) => o && Object.prototype.hasOwnProperty.call(o, key) ? o[key] : void 0;
12310
+ function checkSetting(name, v, depth = 0) {
12311
+ if (v === null || v === void 0 || ["number", "string", "boolean"].includes(typeof v)) return;
12312
+ if (Array.isArray(v) && depth < 32) {
12313
+ for (const x of v) checkSetting(name, x, depth + 1);
12314
+ return;
12315
+ }
12316
+ throw new Error(`Setting "${name}" must be a number, string, boolean or list`);
12317
+ }
12308
12318
  function rangeValues(r, limit) {
12309
12319
  const out = [];
12310
12320
  if (r.step === 0) return out;
12311
12321
  if (r.step > 0 ? r.start > r.end : r.start < r.end) return out;
12312
12322
  const n2 = Math.floor((r.end - r.start) / r.step + 1e-9) + 1;
12313
- if (n2 > limit) throw new Error(`Range has ${n2} steps, more than the limit of ${limit}`);
12323
+ if (n2 > limit) throw new Error(`a range of ${n2} items is more than the limit of ${limit}`);
12314
12324
  for (let k = 0; k < n2; k++) out.push(r.start + k * r.step);
12315
12325
  return out;
12316
12326
  }
@@ -12320,11 +12330,34 @@ function truthy(v) {
12320
12330
  if (typeof v === "number") return !Number.isNaN(v);
12321
12331
  return true;
12322
12332
  }
12323
- function equals(a, b) {
12324
- if (Array.isArray(a) && Array.isArray(b))
12325
- return a.length === b.length && a.every((x, i) => equals(x, b[i]));
12326
- if (isRange(a) && isRange(b)) return a.start === b.start && a.step === b.step && a.end === b.end;
12327
- return a === b;
12333
+ var same = (a, b) => isRange(a) && isRange(b) ? a.start === b.start && a.step === b.step && a.end === b.end : a === b;
12334
+ function equals(a, b, step) {
12335
+ step?.();
12336
+ if (!Array.isArray(a) || !Array.isArray(b)) return same(a, b);
12337
+ const seen = /* @__PURE__ */ new Map();
12338
+ const open = [];
12339
+ const enter = (x, y) => {
12340
+ let ys = seen.get(x);
12341
+ if (ys?.has(y)) return true;
12342
+ if (x.length !== y.length) return false;
12343
+ if (!ys) seen.set(x, ys = /* @__PURE__ */ new Set());
12344
+ ys.add(y);
12345
+ open.push([x, y, 0]);
12346
+ return true;
12347
+ };
12348
+ if (!enter(a, b)) return false;
12349
+ while (open.length) {
12350
+ const top = open[open.length - 1];
12351
+ if (top[2] === top[0].length) {
12352
+ open.pop();
12353
+ continue;
12354
+ }
12355
+ const x = top[0][top[2]];
12356
+ const y = top[1][top[2]++];
12357
+ step?.();
12358
+ if (Array.isArray(x) && Array.isArray(y) ? !enter(x, y) : !same(x, y)) return false;
12359
+ }
12360
+ return true;
12328
12361
  }
12329
12362
  function typeName(v) {
12330
12363
  if (v === void 0) return "undef";
@@ -12333,17 +12366,73 @@ function typeName(v) {
12333
12366
  if (isFn(v)) return "function";
12334
12367
  return typeof v;
12335
12368
  }
12336
- function show(v) {
12369
+ function scalar(v) {
12337
12370
  if (v === void 0) return "undef";
12338
12371
  if (typeof v === "string") return JSON.stringify(v);
12339
12372
  if (typeof v === "number") return fmt(v);
12340
- if (Array.isArray(v)) return `[${v.map(show).join(", ")}]`;
12341
12373
  if (isRange(v)) return `[${fmt(v.start)}:${fmt(v.step)}:${fmt(v.end)}]`;
12342
12374
  if (isFn(v)) return `function(${v.params.map((p) => p.name).join(", ")})`;
12343
12375
  return String(v);
12344
12376
  }
12345
- function str(v) {
12346
- return typeof v === "string" ? v : show(v);
12377
+ function write(v, max, quote = false) {
12378
+ if (typeof v === "string" && !quote)
12379
+ return { text: v.length > max ? v.slice(0, Math.max(max, 0)) : v, whole: v.length <= max };
12380
+ const out = [];
12381
+ let n2 = 0;
12382
+ const put = (s) => {
12383
+ out.push(s);
12384
+ n2 += s.length;
12385
+ };
12386
+ const open = [];
12387
+ let next = v;
12388
+ for (; ; ) {
12389
+ if (Array.isArray(next)) {
12390
+ put("[");
12391
+ open.push([next, 0]);
12392
+ } else put(scalar(next));
12393
+ let more = false;
12394
+ while (open.length && !more) {
12395
+ const top = open[open.length - 1];
12396
+ if (top[1] < top[0].length) {
12397
+ if (top[1]) put(", ");
12398
+ next = top[0][top[1]++];
12399
+ more = true;
12400
+ } else {
12401
+ open.pop();
12402
+ put("]");
12403
+ }
12404
+ }
12405
+ if (!more || n2 > max) break;
12406
+ }
12407
+ const text2 = out.join("");
12408
+ return n2 > max ? { text: text2.slice(0, Math.max(max, 0)), whole: false } : { text: text2, whole: true };
12409
+ }
12410
+ function joinText(vs, sep, max) {
12411
+ const out = [];
12412
+ let n2 = 0;
12413
+ for (const v of vs) {
12414
+ if (out.length) n2 += sep.length;
12415
+ const r = write(v, max - n2);
12416
+ if (!r.whole) return void 0;
12417
+ n2 += r.text.length;
12418
+ out.push(r.text);
12419
+ }
12420
+ return out.join(sep);
12421
+ }
12422
+ function show(v) {
12423
+ const r = write(v, 200, true);
12424
+ return r.whole ? r.text : r.text + "...";
12425
+ }
12426
+ var toText = (v) => typeof v === "string" ? v : show(v);
12427
+ function toNumber(v) {
12428
+ let inList = false;
12429
+ while (Array.isArray(v) && v.length === 1) {
12430
+ v = v[0];
12431
+ inList = true;
12432
+ }
12433
+ if (Array.isArray(v)) return v.length ? NaN : 0;
12434
+ if (inList && (v === void 0 || typeof v === "boolean")) return v === void 0 ? 0 : NaN;
12435
+ return typeof v === "object" ? NaN : Number(v);
12347
12436
  }
12348
12437
  function fmt(n2) {
12349
12438
  if (Number.isInteger(n2)) return String(n2);
@@ -12352,17 +12441,72 @@ function fmt(n2) {
12352
12441
 
12353
12442
  // src/functions.ts
12354
12443
  var RAD = Math.PI / 180;
12444
+ var def = (sig, run, order) => ({
12445
+ params: sig.replace("...", "").split(",").map((p) => p.trim()).filter(Boolean),
12446
+ rest: sig.endsWith("..."),
12447
+ order,
12448
+ run
12449
+ });
12450
+ function givenTwice(f, pos, named) {
12451
+ if (f.order) return [];
12452
+ return f.params.filter((p, i) => i < pos.length && named.has(p));
12453
+ }
12454
+ function bindArgs(f, pos, named) {
12455
+ if (f.rest) {
12456
+ const out = [...pos];
12457
+ f.params.forEach((p, i) => {
12458
+ if (named.has(p)) out[i] = named.get(p);
12459
+ });
12460
+ return out;
12461
+ }
12462
+ if (!f.order) return f.params.map((p, i) => named.has(p) ? named.get(p) : pos[i]);
12463
+ const given = pos.length + f.params.filter((p) => named.has(p)).length;
12464
+ const free = f.order(given).filter((p) => !named.has(p));
12465
+ return f.params.map((p) => named.has(p) ? named.get(p) : pos[free.indexOf(p)]);
12466
+ }
12467
+ function text(vs, sep, c, fn) {
12468
+ const out = joinText(vs, sep, c.maxLength);
12469
+ if (out === void 0)
12470
+ throw new Error(
12471
+ `${fn}(): the text would be longer than the limit of ${c.maxLength} characters`
12472
+ );
12473
+ c.step(Math.ceil(out.length / 8));
12474
+ return out;
12475
+ }
12355
12476
  function num(v, fn) {
12356
12477
  if (typeof v !== "number") throw new Error(`${fn}() needs a number, got ${typeName(v)}`);
12357
12478
  return v;
12358
12479
  }
12359
- function list(v, fn) {
12480
+ function list(v, fn, c) {
12360
12481
  if (Array.isArray(v)) return v;
12361
- if (isRange(v)) return rangeValues(v, 1e6);
12482
+ if (isRange(v)) return rangeValues(v, c.maxLength);
12362
12483
  if (typeof v === "string") return [...v];
12363
12484
  throw new Error(`${fn}() needs a list, got ${typeName(v)}`);
12364
12485
  }
12365
- var math1 = (name, f) => (a) => typeof a[0] === "number" ? clean(f(a[0])) : void 0;
12486
+ var CONSTANT_TIME = /* @__PURE__ */ new Set([
12487
+ "is_num",
12488
+ "is_string",
12489
+ "is_bool",
12490
+ "is_list",
12491
+ "is_undef",
12492
+ "is_function",
12493
+ "type_of",
12494
+ "ord"
12495
+ ]);
12496
+ function argumentWork(name, args, max) {
12497
+ if (CONSTANT_TIME.has(name)) return 0;
12498
+ let n2 = 0;
12499
+ for (const v of args) {
12500
+ if (typeof v === "string") n2 += v.length;
12501
+ else if (Array.isArray(v)) n2 += name === "len" ? 0 : v.length;
12502
+ else if (isRange(v) && v.step !== 0) {
12503
+ const items = Math.floor((v.end - v.start) / v.step) + 1;
12504
+ if (items > 0) n2 += Math.min(items, max + 1);
12505
+ }
12506
+ }
12507
+ return n2;
12508
+ }
12509
+ var math1 = (f) => def("x", (a) => typeof a[0] === "number" ? clean(f(a[0])) : void 0);
12366
12510
  function clean(x) {
12367
12511
  const r = Math.round(x);
12368
12512
  return Math.abs(x - r) < 1e-12 ? r : x;
@@ -12383,69 +12527,112 @@ function minmax(a, pick, name) {
12383
12527
  return pick(xs.map((x) => num(x, name)));
12384
12528
  }
12385
12529
  var FUNCTIONS = {
12386
- abs: math1("abs", Math.abs),
12387
- sign: math1("sign", Math.sign),
12388
- floor: math1("floor", Math.floor),
12389
- ceil: math1("ceil", Math.ceil),
12390
- round: math1("round", (x) => x < 0 ? -Math.round(-x) : Math.round(x)),
12391
- sqrt: math1("sqrt", Math.sqrt),
12392
- exp: math1("exp", Math.exp),
12393
- ln: math1("ln", Math.log),
12394
- log: (a) => a.length === 2 ? Math.log(num(a[1], "log")) / Math.log(num(a[0], "log")) : clean(Math.log10(num(a[0], "log"))),
12395
- sin: math1("sin", (x) => Math.sin(x * RAD)),
12396
- cos: math1("cos", (x) => Math.cos(x * RAD)),
12397
- tan: math1("tan", (x) => Math.tan(x * RAD)),
12398
- asin: math1("asin", (x) => Math.asin(x) / RAD),
12399
- acos: math1("acos", (x) => Math.acos(x) / RAD),
12400
- atan: math1("atan", (x) => Math.atan(x) / RAD),
12401
- atan2: (a) => clean(Math.atan2(num(a[0], "atan2"), num(a[1], "atan2")) / RAD),
12402
- pow: (a) => Math.pow(num(a[0], "pow"), num(a[1], "pow")),
12403
- min: (a) => minmax(a, (xs) => Math.min(...xs), "min"),
12404
- max: (a) => minmax(a, (xs) => Math.max(...xs), "max"),
12405
- clamp: (a) => Math.min(Math.max(num(a[0], "clamp"), num(a[1], "clamp")), num(a[2], "clamp")),
12406
- lerp: (a) => {
12530
+ abs: math1(Math.abs),
12531
+ sign: math1(Math.sign),
12532
+ floor: math1(Math.floor),
12533
+ ceil: math1(Math.ceil),
12534
+ round: math1((x) => x < 0 ? -Math.round(-x) : Math.round(x)),
12535
+ sqrt: math1(Math.sqrt),
12536
+ exp: math1(Math.exp),
12537
+ ln: math1(Math.log),
12538
+ // log(x) is base 10; log(base, x) takes the base first
12539
+ log: def(
12540
+ "x, base",
12541
+ (a, c) => c.given < 2 ? clean(Math.log10(num(a[0], "log"))) : Math.log(num(a[0], "log")) / Math.log(num(a[1], "log")),
12542
+ (n2) => n2 >= 2 ? ["base", "x"] : ["x", "base"]
12543
+ ),
12544
+ sin: math1((x) => Math.sin(x * RAD)),
12545
+ cos: math1((x) => Math.cos(x * RAD)),
12546
+ tan: math1((x) => Math.tan(x * RAD)),
12547
+ asin: math1((x) => Math.asin(x) / RAD),
12548
+ acos: math1((x) => Math.acos(x) / RAD),
12549
+ atan: math1((x) => Math.atan(x) / RAD),
12550
+ atan2: def("y, x", (a) => clean(Math.atan2(num(a[0], "atan2"), num(a[1], "atan2")) / RAD)),
12551
+ pow: def("x, y", (a) => Math.pow(num(a[0], "pow"), num(a[1], "pow"))),
12552
+ min: def(
12553
+ "values...",
12554
+ (a) => minmax(a, (xs) => xs.reduce((m, x) => x < m ? x : m, Infinity), "min")
12555
+ ),
12556
+ max: def(
12557
+ "values...",
12558
+ (a) => minmax(a, (xs) => xs.reduce((m, x) => x > m ? x : m, -Infinity), "max")
12559
+ ),
12560
+ clamp: def(
12561
+ "x, low, high",
12562
+ (a) => Math.min(Math.max(num(a[0], "clamp"), num(a[1], "clamp")), num(a[2], "clamp"))
12563
+ ),
12564
+ lerp: def("a, b, t", (a) => {
12407
12565
  const t = num(a[2], "lerp");
12408
12566
  if (Array.isArray(a[0]) && Array.isArray(a[1])) {
12409
12567
  const b = a[1];
12410
12568
  return a[0].map((x, i) => num(x, "lerp") + (num(b[i], "lerp") - num(x, "lerp")) * t);
12411
12569
  }
12412
12570
  return num(a[0], "lerp") + (num(a[1], "lerp") - num(a[0], "lerp")) * t;
12413
- },
12414
- norm: (a) => Math.hypot(...list(a[0], "norm").map((x) => num(x, "norm"))),
12415
- cross: (a) => {
12416
- const u = list(a[0], "cross").map((x) => num(x, "cross"));
12417
- const v = list(a[1], "cross").map((x) => num(x, "cross"));
12571
+ }),
12572
+ norm: def(
12573
+ "v",
12574
+ (a, c) => Math.sqrt(list(a[0], "norm", c).reduce((s, x) => s + num(x, "norm") ** 2, 0))
12575
+ ),
12576
+ cross: def("a, b", (a, c) => {
12577
+ const u = list(a[0], "cross", c).map((x) => num(x, "cross"));
12578
+ const v = list(a[1], "cross", c).map((x) => num(x, "cross"));
12418
12579
  if (u.length === 2) return u[0] * v[1] - u[1] * v[0];
12419
12580
  return [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];
12420
- },
12421
- len: (a) => typeof a[0] === "string" ? [...a[0]].length : Array.isArray(a[0]) ? a[0].length : void 0,
12422
- concat: (a) => a.flatMap((x) => Array.isArray(x) ? x : [x]),
12423
- reverse: (a) => typeof a[0] === "string" ? [...a[0]].reverse().join("") : [...list(a[0], "reverse")].reverse(),
12424
- sum: (a) => list(a[0], "sum").reduce((s, x) => s + num(x, "sum"), 0),
12425
- slice: (a) => {
12426
- const xs = typeof a[0] === "string" ? [...a[0]] : list(a[0], "slice");
12581
+ }),
12582
+ len: def(
12583
+ "value",
12584
+ (a) => typeof a[0] === "string" ? [...a[0]].length : Array.isArray(a[0]) ? a[0].length : void 0
12585
+ ),
12586
+ concat: def("...", (a, c) => {
12587
+ const n2 = a.reduce((s, x) => s + (Array.isArray(x) ? x.length : 1), 0);
12588
+ if (n2 > c.maxLength)
12589
+ throw new Error(`concat(): a list of ${n2} items is more than the limit of ${c.maxLength}`);
12590
+ return a.flatMap((x) => Array.isArray(x) ? x : [x]);
12591
+ }),
12592
+ reverse: def(
12593
+ "value",
12594
+ (a, c) => typeof a[0] === "string" ? [...a[0]].reverse().join("") : [...list(a[0], "reverse", c)].reverse()
12595
+ ),
12596
+ sum: def("values", (a, c) => list(a[0], "sum", c).reduce((s, x) => s + num(x, "sum"), 0)),
12597
+ slice: def("value, start, end", (a, c) => {
12598
+ const xs = typeof a[0] === "string" ? [...a[0]] : list(a[0], "slice", c);
12427
12599
  const out = xs.slice(
12428
12600
  num(a[1] ?? 0, "slice"),
12429
12601
  a[2] === void 0 ? void 0 : num(a[2], "slice")
12430
12602
  );
12431
12603
  return typeof a[0] === "string" ? out.join("") : out;
12432
- },
12433
- str: (a) => a.map(str).join(""),
12434
- chr: (a) => a.flatMap((x) => Array.isArray(x) ? x : [x]).map((x) => String.fromCodePoint(num(x, "chr"))).join(""),
12435
- ord: (a) => typeof a[0] === "string" && a[0].length ? a[0].codePointAt(0) : void 0,
12436
- upper: (a) => typeof a[0] === "string" ? a[0].toUpperCase() : void 0,
12437
- lower: (a) => typeof a[0] === "string" ? a[0].toLowerCase() : void 0,
12438
- split: (a) => typeof a[0] === "string" ? a[0].split(typeof a[1] === "string" ? a[1] : " ") : void 0,
12439
- join: (a) => list(a[0], "join").map(str).join(typeof a[1] === "string" ? a[1] : ""),
12440
- search: (a) => {
12441
- const xs = typeof a[1] === "string" ? [...a[1]] : list(a[1], "search");
12442
- const i = xs.findIndex((x) => equals(x, a[0]));
12604
+ }),
12605
+ str: def("...", (a, c) => text(a, "", c, "str")),
12606
+ chr: def(
12607
+ "...",
12608
+ (a) => a.flatMap((x) => Array.isArray(x) ? x : [x]).map((x) => String.fromCodePoint(num(x, "chr"))).join("")
12609
+ ),
12610
+ ord: def(
12611
+ "text",
12612
+ (a) => typeof a[0] === "string" && a[0].length ? a[0].codePointAt(0) : void 0
12613
+ ),
12614
+ upper: def("text", (a) => typeof a[0] === "string" ? a[0].toUpperCase() : void 0),
12615
+ lower: def("text", (a) => typeof a[0] === "string" ? a[0].toLowerCase() : void 0),
12616
+ split: def(
12617
+ "text, separator",
12618
+ (a) => typeof a[0] === "string" ? a[0].split(typeof a[1] === "string" ? a[1] : " ") : void 0
12619
+ ),
12620
+ join: def(
12621
+ "values, separator",
12622
+ (a, c) => text(list(a[0], "join", c), typeof a[1] === "string" ? a[1] : "", c, "join")
12623
+ ),
12624
+ search: def("value, list", (a, c) => {
12625
+ const xs = typeof a[1] === "string" ? [...a[1]] : list(a[1], "search", c);
12626
+ const i = xs.findIndex((x) => equals(x, a[0], c.step));
12443
12627
  return i < 0 ? void 0 : i;
12444
- },
12445
- contains: (a) => typeof a[0] === "string" ? a[0].includes(str(a[1])) : list(a[0], "contains").some((x) => equals(x, a[1])),
12446
- lookup: (a) => {
12628
+ }),
12629
+ contains: def(
12630
+ "value, item",
12631
+ (a, c) => typeof a[0] === "string" ? a[0].includes(text([a[1]], "", c, "contains")) : list(a[0], "contains", c).some((x) => equals(x, a[1], c.step))
12632
+ ),
12633
+ lookup: def("x, table", (a, c) => {
12447
12634
  const key = num(a[0], "lookup");
12448
- const table = list(a[1], "lookup");
12635
+ const table = list(a[1], "lookup", c);
12449
12636
  if (!table.length) return void 0;
12450
12637
  const rows = table.map((r) => [num(r[0], "lookup"), num(r[1], "lookup")]).sort((p, q) => p[0] - q[0]);
12451
12638
  if (key <= rows[0][0]) return rows[0][1];
@@ -12456,22 +12643,22 @@ var FUNCTIONS = {
12456
12643
  return y0 + (key - x0) / (x1 - x0) * (y1 - y0);
12457
12644
  }
12458
12645
  return rows[rows.length - 1][1];
12459
- },
12460
- rands: (a) => {
12646
+ }),
12647
+ rands: def("min, max, count, seed", (a) => {
12461
12648
  const lo = num(a[0], "rands"), hi = num(a[1], "rands"), n2 = num(a[2], "rands");
12462
12649
  const rnd = seeded(a[3] === void 0 ? 1 : num(a[3], "rands"));
12463
12650
  return Array.from(
12464
12651
  { length: Math.min(Math.max(0, Math.floor(n2)), 1e6) },
12465
12652
  () => lo + (hi - lo) * rnd()
12466
12653
  );
12467
- },
12468
- is_num: (a) => isNum(a[0]) && !Number.isNaN(a[0]),
12469
- is_string: (a) => typeof a[0] === "string",
12470
- is_bool: (a) => typeof a[0] === "boolean",
12471
- is_list: (a) => Array.isArray(a[0]),
12472
- is_undef: (a) => a[0] === void 0,
12473
- is_function: (a) => isFn(a[0]),
12474
- type_of: (a) => typeName(a[0])
12654
+ }),
12655
+ is_num: def("value", (a) => isNum(a[0]) && !Number.isNaN(a[0])),
12656
+ is_string: def("value", (a) => typeof a[0] === "string"),
12657
+ is_bool: def("value", (a) => typeof a[0] === "boolean"),
12658
+ is_list: def("value", (a) => Array.isArray(a[0])),
12659
+ is_undef: def("value", (a) => a[0] === void 0),
12660
+ is_function: def("value", (a) => isFn(a[0])),
12661
+ type_of: def("value", (a) => typeName(a[0]))
12475
12662
  };
12476
12663
 
12477
12664
  // node_modules/clipper2-ts/dist/Core.js
@@ -16672,21 +16859,31 @@ function merge(shapes) {
16672
16859
  for (const s of shapes) {
16673
16860
  for (const [k, l] of s.layers) {
16674
16861
  const t = out.layers.get(k) ?? { regions: [], lines: [] };
16675
- t.regions.push(...l.regions);
16676
- t.lines.push(...l.lines);
16862
+ for (const p of l.regions) t.regions.push(p);
16863
+ for (const p of l.lines) t.lines.push(p);
16677
16864
  out.layers.set(k, t);
16678
16865
  }
16679
- out.parts.push(...s.parts);
16866
+ for (const p of s.parts) out.parts.push(p);
16680
16867
  }
16681
16868
  return out;
16682
16869
  }
16683
- function retag(s, layer) {
16870
+ function allOn(layers, layer) {
16684
16871
  const all = { regions: [], lines: [] };
16685
- for (const l of s.layers.values()) {
16686
- all.regions.push(...l.regions);
16687
- all.lines.push(...l.lines);
16872
+ for (const l of layers.values()) {
16873
+ for (const p of l.regions) all.regions.push(p);
16874
+ for (const p of l.lines) all.lines.push(p);
16688
16875
  }
16689
- return { layers: /* @__PURE__ */ new Map([[layer, all]]), parts: s.parts };
16876
+ return /* @__PURE__ */ new Map([[layer, all]]);
16877
+ }
16878
+ function retag(s, layer) {
16879
+ if (s.parts.length && layer !== "guide")
16880
+ throw new Error(
16881
+ `a part cannot go on the ${layer} layer as a whole. Put ${layer}() inside part() instead.`
16882
+ );
16883
+ return {
16884
+ layers: allOn(s.layers, layer),
16885
+ parts: s.parts.map((p) => ({ ...p, layers: allOn(p.layers, layer) }))
16886
+ };
16690
16887
  }
16691
16888
  function bounds(polys) {
16692
16889
  let x0 = Infinity, y0 = Infinity, x1 = -Infinity, y1 = -Infinity;
@@ -16703,7 +16900,7 @@ function layerBounds(layers, skip) {
16703
16900
  const all = [];
16704
16901
  for (const [k, l] of layers) {
16705
16902
  if (skip?.(k)) continue;
16706
- all.push(...l.regions, ...l.lines);
16903
+ for (const p of [...l.regions, ...l.lines]) all.push(p);
16707
16904
  }
16708
16905
  return bounds(all);
16709
16906
  }
@@ -16840,14 +17037,16 @@ function livingHinge(w, h, spacing, bridge, cut) {
16840
17037
  }
16841
17038
 
16842
17039
  // src/lexer.ts
17040
+ var where = (pos, col = true) => `line ${pos.line}${col ? `, column ${pos.col}` : ""}${pos.file ? ` in <${pos.file}>` : ""}`;
16843
17041
  var KerfError = class extends Error {
16844
17042
  constructor(message, pos) {
16845
- super(pos ? `${message} (line ${pos.line}, column ${pos.col})` : message);
17043
+ super(pos ? `${message} (${where(pos)})` : message);
16846
17044
  this.echoes = [];
16847
17045
  this.name = "KerfError";
16848
17046
  if (pos) {
16849
17047
  this.line = pos.line;
16850
17048
  this.col = pos.col;
17049
+ this.file = pos.file;
16851
17050
  }
16852
17051
  }
16853
17052
  };
@@ -16881,13 +17080,13 @@ var PUNCT = [
16881
17080
  "}",
16882
17081
  "#"
16883
17082
  ];
16884
- function tokenize(src) {
17083
+ function tokenize(src, file) {
16885
17084
  const tokens = [];
16886
17085
  const comments = [];
16887
17086
  let i = 0;
16888
17087
  let line = 1;
16889
17088
  let lineStart = 0;
16890
- const pos = () => ({ line, col: i - lineStart + 1, offset: i });
17089
+ const pos = () => ({ line, col: i - lineStart + 1, offset: i, ...file && { file } });
16891
17090
  const advance = (n2) => {
16892
17091
  for (let k = 0; k < n2; k++) {
16893
17092
  if (src[i] === "\n") {
@@ -16906,8 +17105,8 @@ function tokenize(src) {
16906
17105
  if (c === "/" && src[i + 1] === "/") {
16907
17106
  const end = src.indexOf("\n", i);
16908
17107
  const stop = end < 0 ? src.length : end;
16909
- const own = /^[ \t]*$/.test(src.slice(src.lastIndexOf("\n", i - 1) + 1, i));
16910
- comments.push({ text: src.slice(i + 2, stop).trim(), line, block: false, own });
17108
+ const own2 = /^[ \t]*$/.test(src.slice(src.lastIndexOf("\n", i - 1) + 1, i));
17109
+ comments.push({ text: src.slice(i + 2, stop).trim(), line, block: false, own: own2 });
16911
17110
  i = stop;
16912
17111
  continue;
16913
17112
  }
@@ -16996,8 +17195,8 @@ var KEYWORDS = /* @__PURE__ */ new Set([
16996
17195
  "false",
16997
17196
  "undef"
16998
17197
  ]);
16999
- function parse(src) {
17000
- const { tokens, comments } = tokenize(src);
17198
+ function parse(src, file) {
17199
+ const { tokens, comments } = tokenize(src, file);
17001
17200
  const p = new Parser(tokens);
17002
17201
  const body = [];
17003
17202
  while (!p.at("eof")) body.push(...p.statement());
@@ -17139,12 +17338,12 @@ var Parser = class _Parser {
17139
17338
  const out = [];
17140
17339
  while (!this.isP(")")) {
17141
17340
  const name = this.ident().value;
17142
- let def = null;
17341
+ let def2 = null;
17143
17342
  if (this.isP("=")) {
17144
17343
  this.next();
17145
- def = this.expr();
17344
+ def2 = this.expr();
17146
17345
  }
17147
- out.push({ name, default: def });
17346
+ out.push({ name, default: def2 });
17148
17347
  if (!this.isP(")")) this.expectP(",");
17149
17348
  }
17150
17349
  this.next();
@@ -17413,13 +17612,14 @@ function flatten(cmds, tolerance = 0.02) {
17413
17612
  } else {
17414
17613
  finish(true);
17415
17614
  last = start;
17416
- cur = [];
17615
+ cur = [start];
17417
17616
  }
17418
17617
  }
17419
17618
  finish(false);
17420
17619
  return { closed, open };
17421
17620
  }
17422
17621
  function parseSvgPath(d2) {
17622
+ const isCommand = (t) => /^[a-zA-Z]$/.test(t);
17423
17623
  const tokens = d2.match(/[a-zA-Z]|[-+]?(?:\d+\.?\d*|\.\d+)(?:[eE][-+]?\d+)?/g) ?? [];
17424
17624
  const out = [];
17425
17625
  let i = 0;
@@ -17429,8 +17629,7 @@ function parseSvgPath(d2) {
17429
17629
  let prev = "";
17430
17630
  const num2 = () => {
17431
17631
  const t = tokens[i++];
17432
- if (t === void 0 || /[a-zA-Z]/.test(t))
17433
- throw new Error(`Bad path data near "${t ?? "end"}"`);
17632
+ if (t === void 0 || isCommand(t)) throw new Error(`Bad path data near "${t ?? "end"}"`);
17434
17633
  return Number(t);
17435
17634
  };
17436
17635
  const flag = () => {
@@ -17444,8 +17643,10 @@ function parseSvgPath(d2) {
17444
17643
  return Number(t);
17445
17644
  };
17446
17645
  while (i < tokens.length) {
17447
- if (/[a-zA-Z]/.test(tokens[i])) cmd = tokens[i++];
17646
+ if (isCommand(tokens[i])) cmd = tokens[i++];
17448
17647
  else if (!cmd) throw new Error("Path data must start with a command");
17648
+ else if (cmd === "Z" || cmd === "z")
17649
+ throw new Error(`Bad path data near "${tokens[i]}": Z takes no numbers`);
17449
17650
  const rel = cmd === cmd.toLowerCase();
17450
17651
  const C = cmd.toUpperCase();
17451
17652
  const ox = rel ? x : 0, oy = rel ? y : 0;
@@ -17588,7 +17789,7 @@ var FontBook = class {
17588
17789
  }
17589
17790
  const hit = this.parsed.get(key);
17590
17791
  if (hit) return hit;
17591
- const src = this.sources[key];
17792
+ const src = own(this.sources, key);
17592
17793
  if (!src) {
17593
17794
  this.missing.add(key);
17594
17795
  throw new Error(
@@ -17601,25 +17802,23 @@ var FontBook = class {
17601
17802
  return font;
17602
17803
  }
17603
17804
  };
17604
- function layoutCommands(font, text, o) {
17805
+ function layoutCommands(font, text2, o) {
17605
17806
  const opts = { kerning: true };
17606
17807
  if (o.spacing === 1) {
17607
- const path = font.getPath(text, 0, 0, o.size, opts);
17608
- return { cmds: path.commands, advance: font.getAdvanceWidth(text, o.size, opts) };
17808
+ const path = font.getPath(text2, 0, 0, o.size, opts);
17809
+ return { cmds: path.commands, advance: font.getAdvanceWidth(text2, o.size, opts) };
17609
17810
  }
17610
17811
  const cmds = [];
17611
17812
  let x = 0;
17612
- const chars = [...text];
17813
+ const chars = [...text2];
17613
17814
  chars.forEach((ch, i) => {
17614
17815
  cmds.push(...font.getPath(ch, x, 0, o.size, opts).commands);
17615
17816
  x += font.getAdvanceWidth(ch, o.size, opts) * (i < chars.length - 1 ? o.spacing : 1);
17616
17817
  });
17617
17818
  return { cmds, advance: x };
17618
17819
  }
17619
- function textRegions(book, text, o) {
17620
- if (!text) return [];
17621
- const font = book.get(o.font);
17622
- const { cmds, advance } = layoutCommands(font, text, o);
17820
+ function outlines(font, text2, o) {
17821
+ const { cmds, advance } = layoutCommands(font, text2, o);
17623
17822
  const flipped = cmds.map((c) => {
17624
17823
  if (c.type === "Z") return c;
17625
17824
  if (c.type === "C") return { ...c, y1: -c.y1, y2: -c.y2, y: -c.y };
@@ -17627,17 +17826,22 @@ function textRegions(book, text, o) {
17627
17826
  return { ...c, y: -c.y };
17628
17827
  });
17629
17828
  const flat = flatten(flipped, Math.max(5e-3, o.size / 2e3));
17630
- const polys = union2([...flat.closed, ...flat.open.filter((p) => p.length >= 3)]);
17829
+ return { polys: [...flat.closed, ...flat.open.filter((p) => p.length >= 3)], advance };
17830
+ }
17831
+ function textRegions(book, text2, o) {
17832
+ if (!text2) return [];
17833
+ const font = book.get(o.font);
17834
+ const { polys: raw, advance } = outlines(font, text2, o);
17835
+ const polys = union2(raw);
17631
17836
  const b = bounds(polys);
17632
17837
  if (!b) return [];
17633
17838
  const dx = o.halign === "center" ? -advance / 2 : o.halign === "right" ? -advance : 0;
17634
17839
  const dy = o.valign === "top" ? -b[3] : o.valign === "center" ? -(b[1] + b[3]) / 2 : o.valign === "bottom" ? -b[1] : 0;
17635
17840
  return polys.map((p) => p.map(([x, y]) => [x + dx, y + dy]));
17636
17841
  }
17637
- function textMetrics(book, text, o) {
17842
+ function textMetrics(book, text2, o) {
17638
17843
  const font = book.get(o.font);
17639
- const { advance } = layoutCommands(font, text, o);
17640
- const polys = textRegions(book, text, { ...o, halign: "left", valign: "baseline" });
17844
+ const { polys, advance } = outlines(font, text2, o);
17641
17845
  const b = bounds(polys) ?? [0, 0, 0, 0];
17642
17846
  return {
17643
17847
  advance,
@@ -17657,6 +17861,31 @@ var DEFAULT_LAYERS = [
17657
17861
  { name: "cut", mode: "cut", color: "#ff0000" },
17658
17862
  { name: "guide", mode: "guide", color: "#00a0ff" }
17659
17863
  ];
17864
+ var DEFAULT_LIMITS = {
17865
+ maxParts: 1e4,
17866
+ maxSegments: 1e4,
17867
+ maxListLength: 1e6,
17868
+ maxListItems: 3e6,
17869
+ maxTextLength: 2e3,
17870
+ maxPoints: 2e6,
17871
+ maxOutputPoints: 1e6,
17872
+ maxSheets: 200
17873
+ };
17874
+ var SHAPE_COST = 100;
17875
+ var LIST_COST = 4;
17876
+ var CHARS_PER_ITEM = 8;
17877
+ var shapePoints = (s) => {
17878
+ let n2 = SHAPE_COST;
17879
+ const add = (layers) => {
17880
+ for (const l of layers.values()) {
17881
+ for (const p of l.regions) n2 += p.length;
17882
+ for (const p of l.lines) n2 += p.length;
17883
+ }
17884
+ };
17885
+ add(s.layers);
17886
+ for (const p of s.parts) add(p.layers);
17887
+ return n2;
17888
+ };
17660
17889
  var Env = class {
17661
17890
  constructor(parent, caller) {
17662
17891
  this.parent = parent;
@@ -17696,11 +17925,15 @@ var Evaluator = class {
17696
17925
  this.opts = opts;
17697
17926
  this.steps = 0;
17698
17927
  this.depth = 0;
17928
+ this.pointCount = 0;
17929
+ this.itemCount = 0;
17930
+ this.copies = 0;
17699
17931
  this.echoes = [];
17700
17932
  this.warnings = [];
17701
17933
  this.layers = new Map(DEFAULT_LAYERS.map((l) => [l.name, l]));
17702
17934
  this.loaded = /* @__PURE__ */ new Map();
17703
17935
  this.maxSteps = opts.maxSteps ?? 5e6;
17936
+ this.limits = { ...DEFAULT_LIMITS, ...opts.limits };
17704
17937
  this.builtins = this.makeBuiltins();
17705
17938
  }
17706
17939
  run(program) {
@@ -17728,17 +17961,17 @@ var Evaluator = class {
17728
17961
  warnings: this.warnings
17729
17962
  };
17730
17963
  }
17731
- tick(pos) {
17732
- if (++this.steps > this.maxSteps)
17964
+ tick(pos, n2 = 1) {
17965
+ if (!((this.steps += n2) <= this.maxSteps))
17733
17966
  throw new KerfError(`Stopped after ${this.maxSteps} steps. Is there an endless loop?`, pos);
17734
17967
  }
17735
17968
  load(path, at) {
17736
17969
  const hit = this.loaded.get(path);
17737
17970
  if (hit) return hit;
17738
- const src = STDLIB[path] ?? this.opts.resolve?.(path);
17739
- if (src === void 0) throw new KerfError(`Library <${path}> not found`, at);
17971
+ const src = own(STDLIB, path) ?? this.opts.resolve?.(path);
17972
+ if (typeof src !== "string") throw new KerfError(`Library <${path}> not found`, at);
17740
17973
  this.loaded.set(path, { body: [] });
17741
- const { program } = parse(src);
17974
+ const { program } = parse(src, path);
17742
17975
  this.loaded.set(path, program);
17743
17976
  return program;
17744
17977
  }
@@ -17747,16 +17980,28 @@ var Evaluator = class {
17747
17980
  if (s.kind === "module") env.mods.set(s.name, { params: s.params, body: s.body, env });
17748
17981
  else if (s.kind === "function") env.fns.set(s.name, { params: s.params, body: s.body, env });
17749
17982
  else if (s.kind === "use" && !s.include) {
17750
- const lib = this.load(s.path, s.pos);
17983
+ const body = this.included(this.load(s.path, s.pos).body, /* @__PURE__ */ new Set([s.path]));
17751
17984
  const libEnv = new Env(env);
17752
- this.hoist(lib.body, libEnv);
17753
- for (const ls of lib.body)
17985
+ this.hoist(body, libEnv);
17986
+ for (const ls of body)
17754
17987
  if (ls.kind === "assign") this.assign(ls.name, this.expr(ls.value, libEnv), libEnv);
17755
17988
  for (const [k, v] of libEnv.mods) env.mods.set(k, v);
17756
17989
  for (const [k, v] of libEnv.fns) env.fns.set(k, v);
17757
17990
  }
17758
17991
  }
17759
17992
  }
17993
+ // A library's statements with the files it includes written out in place
17994
+ included(stmts, seen) {
17995
+ const out = [];
17996
+ for (const s of stmts) {
17997
+ if (s.kind !== "use" || !s.include) out.push(s);
17998
+ else if (!seen.has(s.path)) {
17999
+ seen.add(s.path);
18000
+ for (const t of this.included(this.load(s.path, s.pos).body, seen)) out.push(t);
18001
+ }
18002
+ }
18003
+ return out;
18004
+ }
17760
18005
  assign(name, value, env) {
17761
18006
  env.vars.set(name, value);
17762
18007
  }
@@ -17814,7 +18059,7 @@ var Evaluator = class {
17814
18059
  iterable(v, at) {
17815
18060
  if (isRange(v)) {
17816
18061
  try {
17817
- return rangeValues(v, 1e6);
18062
+ return rangeValues(v, this.limits.maxListLength);
17818
18063
  } catch (e) {
17819
18064
  throw new KerfError(e.message, at);
17820
18065
  }
@@ -17855,11 +18100,17 @@ var Evaluator = class {
17855
18100
  });
17856
18101
  for (const k of args.named.keys()) {
17857
18102
  if (k.startsWith("$")) env.vars.set(k, args.named.get(k));
17858
- else if (!names.has(k))
17859
- this.warnings.push(`${what}: unknown argument "${k}" (line ${args.at.line})`);
18103
+ else if (!names.has(k)) this.unknownArg(what, k, args.at);
17860
18104
  }
17861
18105
  void defEnv;
17862
18106
  }
18107
+ unknownArg(what, name, at) {
18108
+ this.warn(`${what}: unknown argument "${name}" (${where(at, false)})`);
18109
+ }
18110
+ // A warning, once however often it comes up
18111
+ warn(warning) {
18112
+ if (!this.warnings.includes(warning)) this.warnings.push(warning);
18113
+ }
17863
18114
  callModule(s, env) {
17864
18115
  const args = this.evalArgs(s.args, env, s.pos);
17865
18116
  const user = env.mod(s.name);
@@ -17876,7 +18127,7 @@ var Evaluator = class {
17876
18127
  this.depth--;
17877
18128
  }
17878
18129
  }
17879
- const b = this.builtins[s.name];
18130
+ const b = own(this.builtins, s.name);
17880
18131
  if (!b) {
17881
18132
  const hint = s.name === "color" ? " Use layer(), cut(), score() or engrave() instead." : s.name === "square" ? " Use rect()." : "";
17882
18133
  throw new KerfError(`Unknown module ${s.name}().${hint}`, s.pos);
@@ -17892,20 +18143,28 @@ var Evaluator = class {
17892
18143
  childList: () => {
17893
18144
  const e = childEnv();
17894
18145
  this.hoist(s.children, e);
17895
- const out = [];
18146
+ const out2 = [];
17896
18147
  for (const st of s.children) {
17897
18148
  const r = this.stmt(st, e);
17898
- if (kids.includes(st)) out.push(r ?? emptyShape());
18149
+ if (kids.includes(st)) out2.push(r ?? emptyShape());
17899
18150
  }
17900
- return out;
18151
+ return out2;
17901
18152
  }
17902
18153
  };
18154
+ let out;
17903
18155
  try {
17904
- return b(ctx);
18156
+ out = b(ctx);
17905
18157
  } catch (e) {
17906
18158
  if (e instanceof KerfError) throw e;
17907
18159
  throw new KerfError(`${s.name}(): ${e.message}`, s.pos);
17908
18160
  }
18161
+ this.pointCount += shapePoints(out);
18162
+ if (this.pointCount > this.limits.maxPoints)
18163
+ throw new KerfError(
18164
+ `The shapes have more than ${this.limits.maxPoints} points, the limit. Use fewer or simpler shapes, or a lower $fn.`,
18165
+ s.pos
18166
+ );
18167
+ return out;
17909
18168
  }
17910
18169
  childStmts(stmts) {
17911
18170
  return stmts.filter(
@@ -17943,7 +18202,8 @@ var Evaluator = class {
17943
18202
  }
17944
18203
  case "list": {
17945
18204
  const out = [];
17946
- for (const it of x.items) this.listItem(it, env, out);
18205
+ for (const it of x.items) this.listItem(it, env, out, x.pos);
18206
+ this.charge(LIST_COST, x.pos);
17947
18207
  return out;
17948
18208
  }
17949
18209
  case "range": {
@@ -17965,8 +18225,8 @@ var Evaluator = class {
17965
18225
  if (x.op === "||") return truthy(this.expr(x.left, env)) || truthy(this.expr(x.right, env));
17966
18226
  const a = this.expr(x.left, env);
17967
18227
  const b = this.expr(x.right, env);
17968
- if (x.op === "==") return equals(a, b);
17969
- if (x.op === "!=") return !equals(a, b);
18228
+ if (x.op === "==" || x.op === "!=")
18229
+ return equals(a, b, () => this.tick(x.pos)) === (x.op === "==");
17970
18230
  if (x.op === "<" || x.op === "<=" || x.op === ">" || x.op === ">=") {
17971
18231
  if (!(typeof a === "number" && typeof b === "number" || typeof a === "string" && typeof b === "string"))
17972
18232
  throw new KerfError(`Can't compare ${typeName(a)} ${x.op} ${typeName(b)}`, x.pos);
@@ -18005,30 +18265,50 @@ var Evaluator = class {
18005
18265
  }
18006
18266
  }
18007
18267
  }
18008
- listItem(it, env, out) {
18268
+ listItem(it, env, out, at) {
18009
18269
  switch (it.kind) {
18010
- case "item":
18011
- out.push(this.expr(it.expr, env));
18270
+ case "item": {
18271
+ const v = this.expr(it.expr, env);
18272
+ this.grow(out, 1, at);
18273
+ out.push(v);
18012
18274
  return;
18275
+ }
18013
18276
  case "each": {
18014
- const v = this.expr(it.expr, env);
18015
- out.push(...this.iterable(v, { line: 0, col: 0, offset: 0 }));
18277
+ const xs = this.iterable(this.expr(it.expr, env), at);
18278
+ this.grow(out, xs.length, at);
18279
+ for (const x of xs) out.push(x);
18016
18280
  return;
18017
18281
  }
18018
18282
  case "for":
18019
- this.loop(it.assigns, env, (e) => this.listItem(it.body, e, out));
18283
+ this.loop(it.assigns, env, (e) => this.listItem(it.body, e, out, at));
18020
18284
  return;
18021
18285
  case "if":
18022
- if (truthy(this.expr(it.cond, env))) this.listItem(it.then, env, out);
18023
- else if (it.else) this.listItem(it.else, env, out);
18286
+ if (truthy(this.expr(it.cond, env))) this.listItem(it.then, env, out, at);
18287
+ else if (it.else) this.listItem(it.else, env, out, at);
18024
18288
  return;
18025
18289
  case "let": {
18026
18290
  const e = new Env(env);
18027
18291
  this.bindSeq(it.assigns, e);
18028
- this.listItem(it.body, e, out);
18292
+ this.listItem(it.body, e, out, at);
18029
18293
  }
18030
18294
  }
18031
18295
  }
18296
+ grow(out, n2, at) {
18297
+ if (out.length + n2 > this.limits.maxListLength)
18298
+ throw new KerfError(
18299
+ `a list of ${out.length + n2} items is more than the limit of ${this.limits.maxListLength}`,
18300
+ at
18301
+ );
18302
+ this.charge(n2, at);
18303
+ }
18304
+ charge(items, at) {
18305
+ this.itemCount += items;
18306
+ if (!(this.itemCount <= this.limits.maxListItems))
18307
+ throw new KerfError(
18308
+ `The lists and strings hold more than ${this.limits.maxListItems} items in all, the limit. Is a loop building more than it needs?`,
18309
+ at
18310
+ );
18311
+ }
18032
18312
  call(x, env) {
18033
18313
  if (x.callee.kind === "var") {
18034
18314
  const name = x.callee.name;
@@ -18038,14 +18318,34 @@ var Evaluator = class {
18038
18318
  if (f2) return this.callFunction(f2, this.evalArgs(x.args, env, x.pos), env, name);
18039
18319
  const special = this.specialFunction(name, x, env);
18040
18320
  if (special.handled) return special.value;
18041
- const b = FUNCTIONS[name];
18321
+ const b = own(FUNCTIONS, name);
18042
18322
  if (b) {
18043
18323
  const args = this.evalArgs(x.args, env, x.pos);
18324
+ for (const k of args.named.keys())
18325
+ if (!k.startsWith("$") && !b.params.includes(k)) this.unknownArg(`${name}()`, k, x.pos);
18326
+ for (const k of givenTwice(b, args.pos, args.named))
18327
+ this.warn(
18328
+ `${name}(): "${k}" is given by position and by name; the named value is used (${where(x.pos, false)})`
18329
+ );
18330
+ const ctx = {
18331
+ maxLength: this.limits.maxListLength,
18332
+ step: (n2) => this.tick(x.pos, n2),
18333
+ given: args.pos.length + b.params.filter((p) => args.named.has(p)).length
18334
+ };
18335
+ const bound = bindArgs(b, args.pos, args.named);
18336
+ this.tick(x.pos, argumentWork(name, bound, this.limits.maxListLength));
18337
+ let out;
18044
18338
  try {
18045
- return b(args.pos, args.named);
18339
+ out = b.run(bound, ctx);
18046
18340
  } catch (e) {
18047
- throw new KerfError(e.message, x.pos);
18341
+ if (e instanceof KerfError) throw e;
18342
+ throw new KerfError(
18343
+ e instanceof RangeError ? `${name}(): the result is too large` : e.message,
18344
+ x.pos
18345
+ );
18048
18346
  }
18347
+ this.checkValue(out, x.pos, name);
18348
+ return out;
18049
18349
  }
18050
18350
  throw new KerfError(`Unknown function ${name}()`, x.pos);
18051
18351
  }
@@ -18060,16 +18360,11 @@ var Evaluator = class {
18060
18360
  specialFunction(name, x, env) {
18061
18361
  if (name === "echo") {
18062
18362
  const a = this.evalArgs(x.args, env, x.pos);
18063
- this.echoes.push(this.echoText(a));
18363
+ this.echo(this.echoText(a), x.pos);
18064
18364
  return { handled: true, value: void 0 };
18065
18365
  }
18066
18366
  if (name === "assert") {
18067
- const a = this.evalArgs(x.args, env, x.pos);
18068
- if (!truthy(a.pos[0]))
18069
- throw new KerfError(
18070
- `Assertion failed${a.pos[1] !== void 0 ? ": " + (typeof a.pos[1] === "string" ? a.pos[1] : show(a.pos[1])) : ""}`,
18071
- x.pos
18072
- );
18367
+ this.assert(this.evalArgs(x.args, env, x.pos));
18073
18368
  return { handled: true, value: true };
18074
18369
  }
18075
18370
  if (name === "text_width" || name === "text_metrics") {
@@ -18088,9 +18383,33 @@ var Evaluator = class {
18088
18383
  }
18089
18384
  return { handled: false };
18090
18385
  }
18386
+ assert(a) {
18387
+ if (truthy(this.arg(a, "condition", 0))) return;
18388
+ const m = this.arg(a, "message", 1);
18389
+ throw new KerfError(`Assertion failed${m === void 0 ? "" : ": " + toText(m)}`, a.at);
18390
+ }
18391
+ echo(text2, at) {
18392
+ this.charge(Math.ceil(text2.length / CHARS_PER_ITEM), at);
18393
+ this.echoes.push(text2);
18394
+ }
18395
+ // Echo text stops at maxListLength characters, before it is all written out
18091
18396
  echoText(a) {
18092
- const parts = a.pos.map((v) => typeof v === "string" ? v : show(v));
18093
- for (const [k, v] of a.named) parts.push(`${k} = ${show(v)}`);
18397
+ const max = this.limits.maxListLength;
18398
+ const parts = [];
18399
+ let n2 = 0;
18400
+ const add = (label, v, quote) => {
18401
+ if (parts.length) n2 += 2;
18402
+ const r = write(v, max - n2 - label.length, quote);
18403
+ n2 += label.length + r.text.length;
18404
+ if (!r.whole)
18405
+ throw new KerfError(
18406
+ `echo(): the text would be longer than the limit of ${max} characters`,
18407
+ a.at
18408
+ );
18409
+ parts.push(label + r.text);
18410
+ };
18411
+ for (const v of a.pos) add("", v, false);
18412
+ for (const [k, v] of a.named) add(`${k} = `, v, true);
18094
18413
  return parts.join(", ");
18095
18414
  }
18096
18415
  arith(op, a, b, at) {
@@ -18110,7 +18429,10 @@ var Evaluator = class {
18110
18429
  return Math.pow(a, b);
18111
18430
  }
18112
18431
  }
18113
- if (op === "+" && typeof a === "string" && typeof b === "string") return a + b;
18432
+ if (op === "+" && typeof a === "string" && typeof b === "string") {
18433
+ this.checkSize(a.length + b.length, true, at);
18434
+ return a + b;
18435
+ }
18114
18436
  if (Array.isArray(a) && Array.isArray(b)) {
18115
18437
  if (op === "+" || op === "-") {
18116
18438
  if (a.length !== b.length)
@@ -18118,29 +18440,51 @@ var Evaluator = class {
18118
18440
  `Can't ${op === "+" ? "add" : "subtract"} lists of length ${a.length} and ${b.length}`,
18119
18441
  at
18120
18442
  );
18443
+ this.charge(a.length + LIST_COST, at);
18121
18444
  return a.map((x, i) => this.arith(op, x, b[i], at));
18122
18445
  }
18123
18446
  if (op === "*") {
18124
- if (Array.isArray(a[0])) return a.map((row) => this.arith("*", row, b, at));
18447
+ if (Array.isArray(a[0])) {
18448
+ this.charge(a.length + LIST_COST, at);
18449
+ return a.map((row) => this.arith("*", row, b, at));
18450
+ }
18451
+ const term = (x, y) => {
18452
+ const t = this.arith("*", x, y, at);
18453
+ if (typeof t !== "number")
18454
+ throw new KerfError(
18455
+ "Can't multiply these lists: an item times an item is not a number",
18456
+ at
18457
+ );
18458
+ return t;
18459
+ };
18125
18460
  if (Array.isArray(b[0])) {
18126
18461
  const cols = b[0].length;
18462
+ if (a.length !== b.length || b.some((r) => !Array.isArray(r) || r.length !== cols))
18463
+ throw new KerfError(
18464
+ `Can't multiply a list of length ${a.length} by a matrix: it needs ${a.length} rows of the same length`,
18465
+ at
18466
+ );
18467
+ this.checkSize(cols, false, at);
18468
+ this.tick(at, cols * a.length);
18127
18469
  return Array.from(
18128
18470
  { length: cols },
18129
- (_, j) => a.reduce(
18130
- (s, x, i) => s + this.arith("*", x, b[i][j], at),
18131
- 0
18132
- )
18471
+ (_, j) => a.reduce((s, x, i) => s + term(x, b[i][j]), 0)
18133
18472
  );
18134
18473
  }
18135
18474
  if (a.length !== b.length)
18136
18475
  throw new KerfError(`Can't multiply lists of length ${a.length} and ${b.length}`, at);
18137
- return a.reduce((s, x, i) => s + this.arith("*", x, b[i], at), 0);
18476
+ this.tick(at, a.length);
18477
+ return a.reduce((s, x, i) => s + term(x, b[i]), 0);
18138
18478
  }
18139
18479
  }
18140
- if (Array.isArray(a) && typeof b === "number" && (op === "*" || op === "/"))
18480
+ if (Array.isArray(a) && typeof b === "number" && (op === "*" || op === "/")) {
18481
+ this.charge(a.length + LIST_COST, at);
18141
18482
  return a.map((x) => this.arith(op, x, b, at));
18142
- if (typeof a === "number" && Array.isArray(b) && op === "*")
18483
+ }
18484
+ if (typeof a === "number" && Array.isArray(b) && op === "*") {
18485
+ this.charge(b.length + LIST_COST, at);
18143
18486
  return b.map((x) => this.arith(op, a, x, at));
18487
+ }
18144
18488
  const verb = {
18145
18489
  "+": "add",
18146
18490
  "-": "subtract",
@@ -18151,26 +18495,27 @@ var Evaluator = class {
18151
18495
  };
18152
18496
  throw new KerfError(`Can't ${verb[op] ?? op} ${typeName(a)} and ${typeName(b)}`, at);
18153
18497
  }
18154
- arg(a, name, index, def) {
18498
+ arg(a, name, index, def2) {
18155
18499
  if (a.named.has(name)) return a.named.get(name);
18156
18500
  if (index >= 0 && index < a.pos.length) return a.pos[index];
18157
- return def;
18501
+ return def2;
18158
18502
  }
18159
18503
  num(v, fn, name) {
18160
- if (typeof v !== "number" || Number.isNaN(v))
18161
- throw new Error(`${name} must be a number, got ${show(v)}`);
18504
+ if (typeof v !== "number" || !Number.isFinite(v))
18505
+ throw new Error(`${name} must be a finite number, got ${show(v)}`);
18162
18506
  return v;
18163
18507
  }
18164
18508
  vec2(v, name, scalarBoth = true) {
18165
- if (typeof v === "number" && scalarBoth) return [v, v];
18166
- if (Array.isArray(v) && typeof v[0] === "number")
18167
- return [v[0], typeof v[1] === "number" ? v[1] : 0];
18509
+ const ok = (x) => typeof x === "number" && Number.isFinite(x);
18510
+ if (ok(v) && scalarBoth) return [v, v];
18511
+ if (Array.isArray(v) && ok(v[0]) && (v[1] === void 0 || ok(v[1])))
18512
+ return [v[0], v[1] ?? 0];
18168
18513
  throw new Error(`${name} must be a number or [x, y], got ${show(v)}`);
18169
18514
  }
18170
18515
  points(v, name) {
18171
18516
  if (!Array.isArray(v)) throw new Error(`${name} must be a list of [x, y] points`);
18172
18517
  return v.map((p, i) => {
18173
- if (!Array.isArray(p) || typeof p[0] !== "number" || typeof p[1] !== "number")
18518
+ if (!Array.isArray(p) || !Number.isFinite(p[0]) || !Number.isFinite(p[1]))
18174
18519
  throw new Error(`${name}[${i}] must be an [x, y] point, got ${show(p)}`);
18175
18520
  return [p[0], p[1]];
18176
18521
  });
@@ -18178,11 +18523,38 @@ var Evaluator = class {
18178
18523
  dyn(env, name) {
18179
18524
  return env.get(name).value;
18180
18525
  }
18526
+ spend(points) {
18527
+ this.pointCount += points;
18528
+ if (!(this.pointCount <= this.limits.maxPoints))
18529
+ throw new Error(
18530
+ `the shapes need more than ${this.limits.maxPoints} points, the limit. Use fewer or simpler shapes.`
18531
+ );
18532
+ }
18533
+ checkValue(v, pos, fn) {
18534
+ if (Array.isArray(v) || typeof v === "string")
18535
+ this.checkSize(v.length, typeof v === "string", pos, fn);
18536
+ }
18537
+ checkSize(n2, isString, pos, fn) {
18538
+ if (n2 > this.limits.maxListLength)
18539
+ throw new KerfError(
18540
+ `${fn ? `${fn}(): ` : ""}${isString ? `a string of ${n2} characters` : `a list of ${n2} items`} is more than the limit of ${this.limits.maxListLength}`,
18541
+ pos
18542
+ );
18543
+ this.charge(isString ? Math.ceil(n2 / CHARS_PER_ITEM) : n2 + LIST_COST, pos);
18544
+ }
18181
18545
  segs(env) {
18182
- const fn = Number(this.dyn(env, "$fn")) || 0;
18183
- const fa = Number(this.dyn(env, "$fa")) || 2;
18184
- const fs = Number(this.dyn(env, "$fs")) || 0.2;
18185
- return (r) => fragments(r, fn, fa, fs);
18546
+ const fn = toNumber(this.dyn(env, "$fn")) || 0;
18547
+ const fa = toNumber(this.dyn(env, "$fa")) || 2;
18548
+ const fs = toNumber(this.dyn(env, "$fs")) || 0.2;
18549
+ const max = this.limits.maxSegments;
18550
+ return (r) => {
18551
+ const n2 = fragments(r, fn, fa, fs);
18552
+ if (!(n2 <= max))
18553
+ throw new Error(
18554
+ `a circle with ${n2} segments is more than the limit of ${max}. Lower $fn, or raise $fa or $fs.`
18555
+ );
18556
+ return n2;
18557
+ };
18186
18558
  }
18187
18559
  thickness(env) {
18188
18560
  const t = this.dyn(env, "$thickness");
@@ -18200,9 +18572,15 @@ var Evaluator = class {
18200
18572
  "text needs a font. Pass fonts to render(), or --font on the command line.",
18201
18573
  a.at
18202
18574
  );
18203
- const text = String(this.arg(a, "text", 0, ""));
18575
+ const shown = write(this.arg(a, "text", 0, ""), this.limits.maxTextLength);
18576
+ if (!shown.whole)
18577
+ throw new KerfError(
18578
+ `the text is more than ${this.limits.maxTextLength} characters, the limit for one text()`,
18579
+ a.at
18580
+ );
18581
+ this.tick(a.at, shown.text.length);
18204
18582
  try {
18205
- return textMetrics(this.opts.fonts, text, this.textOpts(a, env));
18583
+ return textMetrics(this.opts.fonts, shown.text, this.textOpts(a, env));
18206
18584
  } catch (e) {
18207
18585
  if (e instanceof KerfError) throw e;
18208
18586
  throw new KerfError(e.message, a.at);
@@ -18211,10 +18589,10 @@ var Evaluator = class {
18211
18589
  textOpts(a, env) {
18212
18590
  return {
18213
18591
  size: this.num(this.arg(a, "size", 1, 10), "text", "size"),
18214
- font: String(this.arg(a, "font", 2, this.dyn(env, "$font") ?? "")),
18215
- halign: String(this.arg(a, "halign", -1, "left")),
18216
- valign: String(this.arg(a, "valign", -1, "baseline")),
18217
- spacing: Number(this.arg(a, "spacing", -1, 1))
18592
+ font: toText(this.arg(a, "font", 2, this.dyn(env, "$font") ?? "")),
18593
+ halign: toText(this.arg(a, "halign", -1, "left")),
18594
+ valign: toText(this.arg(a, "valign", -1, "baseline")),
18595
+ spacing: toNumber(this.arg(a, "spacing", -1, 1))
18218
18596
  };
18219
18597
  }
18220
18598
  edges(v) {
@@ -18232,7 +18610,7 @@ var Evaluator = class {
18232
18610
  return {
18233
18611
  rect: (c) => {
18234
18612
  const [w, h] = this.vec2(this.arg(c.args, "size", 0, 1), "size");
18235
- const r = Number(this.arg(c.args, "r", -1, 0)) || 0;
18613
+ const r = toNumber(this.arg(c.args, "r", -1, 0)) || 0;
18236
18614
  const center = truthy(this.arg(c.args, "center", 1, false));
18237
18615
  const p = roundedRect(w, h, r, this.segs(c.env));
18238
18616
  return regionShape(union2([center ? p.map(([x, y]) => [x - w / 2, y - h / 2]) : p]));
@@ -18253,12 +18631,16 @@ var Evaluator = class {
18253
18631
  Math.floor(this.num(this.arg(c.args, "n", 0, 6), "regular_polygon", "n"))
18254
18632
  );
18255
18633
  const r = this.num(this.arg(c.args, "r", 1, 10), "regular_polygon", "r");
18634
+ if (!(n2 <= this.limits.maxSegments))
18635
+ throw new Error(`${n2} corners is more than the limit of ${this.limits.maxSegments}`);
18256
18636
  return regionShape([ellipsePoly(r, r, n2)]);
18257
18637
  },
18258
18638
  star: (c) => {
18259
18639
  const n2 = Math.max(2, Math.floor(this.num(this.arg(c.args, "n", 0, 5), "star", "n")));
18260
18640
  const r = this.num(this.arg(c.args, "r", 1, 10), "star", "r");
18261
18641
  const ri = this.num(this.arg(c.args, "inner", 2, r * 0.45), "star", "inner");
18642
+ if (!(n2 * 2 <= this.limits.maxSegments))
18643
+ throw new Error(`${n2} points is more than the limit of ${this.limits.maxSegments / 2}`);
18262
18644
  const p = [];
18263
18645
  for (let i = 0; i < n2 * 2; i++) {
18264
18646
  const a = Math.PI / 2 + Math.PI * i / n2;
@@ -18271,7 +18653,7 @@ var Evaluator = class {
18271
18653
  const pts = this.points(this.arg(c.args, "points", 0), "points");
18272
18654
  const paths = this.arg(c.args, "paths", 1);
18273
18655
  const polys = Array.isArray(paths) ? paths.map(
18274
- (ix) => (Array.isArray(ix) ? ix : []).map((i) => pts[Number(i)]).filter(Boolean)
18656
+ (ix) => (Array.isArray(ix) ? ix : []).map((i) => pts[toNumber(i)]).filter(Boolean)
18275
18657
  ) : [pts];
18276
18658
  return regionShape(union2(polys, "evenodd"));
18277
18659
  },
@@ -18280,7 +18662,7 @@ var Evaluator = class {
18280
18662
  if (typeof d2 !== "string")
18281
18663
  throw new Error('path() needs SVG path data, like path("M0 0 L10 0 L5 8 Z")');
18282
18664
  const flat2 = flatten(parseSvgPath(d2), 0.01);
18283
- const fill = String(this.arg(c.args, "fill", -1, "evenodd")) === "nonzero" ? "nonzero" : "evenodd";
18665
+ const fill = this.arg(c.args, "fill", -1, "evenodd") === "nonzero" ? "nonzero" : "evenodd";
18284
18666
  return merge([regionShape(union2(flat2.closed, fill)), lineShape(flat2.open)]);
18285
18667
  },
18286
18668
  line: (c) => {
@@ -18298,6 +18680,10 @@ var Evaluator = class {
18298
18680
  const a0 = this.num(this.arg(c.args, "start", 1, 0), "arc", "start");
18299
18681
  const a1 = this.num(this.arg(c.args, "end", 2, 90), "arc", "end");
18300
18682
  const n2 = Math.max(2, Math.ceil(this.segs(c.env)(r) * Math.abs(a1 - a0) / 360));
18683
+ if (!(n2 <= this.limits.maxSegments))
18684
+ throw new Error(
18685
+ `an arc with ${n2} segments is more than the limit of ${this.limits.maxSegments}`
18686
+ );
18301
18687
  const p = [];
18302
18688
  for (let i = 0; i <= n2; i++) {
18303
18689
  const a = (a0 + (a1 - a0) * i / n2) * Math.PI / 180;
@@ -18310,14 +18696,14 @@ var Evaluator = class {
18310
18696
  throw new Error(
18311
18697
  "text() needs a font. Pass fonts to render(), or --font on the command line."
18312
18698
  );
18313
- const text = this.arg(c.args, "text", 0, "");
18314
- return regionShape(
18315
- textRegions(
18316
- this.opts.fonts,
18317
- typeof text === "string" ? text : show(text),
18318
- this.textOpts(c.args, c.env)
18319
- )
18320
- );
18699
+ const text2 = this.arg(c.args, "text", 0, "");
18700
+ const shown = write(text2, this.limits.maxTextLength);
18701
+ if (!shown.whole)
18702
+ throw new Error(
18703
+ `the text is more than ${this.limits.maxTextLength} characters, the limit for one text()`
18704
+ );
18705
+ this.tick(c.args.at, shown.text.length);
18706
+ return regionShape(textRegions(this.opts.fonts, shown.text, this.textOpts(c.args, c.env)));
18321
18707
  },
18322
18708
  translate: (c) => {
18323
18709
  const [x, y] = this.vec2(this.arg(c.args, "v", 0, [0, 0]), "v", false);
@@ -18325,7 +18711,7 @@ var Evaluator = class {
18325
18711
  },
18326
18712
  rotate: (c) => {
18327
18713
  const a = this.arg(c.args, "a", 0, 0);
18328
- const deg = Array.isArray(a) ? Number(a[2] ?? 0) : this.num(a, "rotate", "a");
18714
+ const deg = Array.isArray(a) ? toNumber(a[2] ?? 0) : this.num(a, "rotate", "a");
18329
18715
  const r = deg * Math.PI / 180;
18330
18716
  const cs = Math.cos(r), sn = Math.sin(r);
18331
18717
  const ctr = this.arg(c.args, "center", -1);
@@ -18376,22 +18762,26 @@ var Evaluator = class {
18376
18762
  }
18377
18763
  return out;
18378
18764
  },
18765
+ // One hull for the shapes outside parts, and one inside each part
18379
18766
  hull: (c) => {
18380
18767
  const s = c.children();
18381
- const pts = [];
18382
- let key = "cut";
18383
- let first = true;
18384
- for (const [k, l] of s.layers) {
18385
- if (first && (l.regions.length || l.lines.length)) {
18386
- key = k;
18387
- first = false;
18768
+ const each = (layers) => {
18769
+ const pts = [];
18770
+ let key = "cut";
18771
+ let first = true;
18772
+ for (const [k, l] of layers) {
18773
+ if (first && (l.regions.length || l.lines.length)) {
18774
+ key = k;
18775
+ first = false;
18776
+ }
18777
+ for (const p of [...l.regions, ...l.lines]) for (const q of p) pts.push(q);
18388
18778
  }
18389
- for (const p of [...l.regions, ...l.lines]) pts.push(...p);
18390
- }
18391
- const h = hull(pts);
18779
+ const h = hull(pts);
18780
+ return /* @__PURE__ */ new Map([[key, { regions: h.length >= 3 ? [h] : [], lines: [] }]]);
18781
+ };
18392
18782
  return {
18393
- layers: /* @__PURE__ */ new Map([[key, { regions: h.length >= 3 ? [h] : [], lines: [] }]]),
18394
- parts: s.parts
18783
+ layers: each(s.layers),
18784
+ parts: s.parts.map((p) => ({ ...p, layers: each(p.layers) }))
18395
18785
  };
18396
18786
  },
18397
18787
  offset: (c) => {
@@ -18430,15 +18820,18 @@ var Evaluator = class {
18430
18820
  const m = mode ?? known?.mode ?? "line";
18431
18821
  if (!["cut", "line", "fill", "guide"].includes(m))
18432
18822
  throw new Error('mode must be "cut", "line", "fill" or "guide"');
18433
- const col = String(color ?? known?.color ?? "#00aa00");
18823
+ const col = toText(color ?? known?.color ?? "#00aa00");
18434
18824
  if (!/^#[0-9a-fA-F]{6}$/.test(col)) throw new Error('color must look like "#00aa00"');
18435
18825
  this.layers.set(name, { name, mode: m, color: col });
18436
18826
  }
18437
18827
  return retag(c.children(), name);
18438
18828
  },
18439
18829
  part: (c) => {
18440
- const name = String(this.arg(c.args, "name", 0, "part"));
18441
- const qty = Math.max(1, Math.floor(Number(this.arg(c.args, "qty", 1, 1)) || 1));
18830
+ const name = toText(this.arg(c.args, "name", 0, "part"));
18831
+ const qty = Math.max(1, Math.floor(toNumber(this.arg(c.args, "qty", 1, 1)) || 1));
18832
+ this.copies += qty;
18833
+ if (!(this.copies <= this.limits.maxParts))
18834
+ throw new Error(`more than ${this.limits.maxParts} part copies in total, the limit`);
18442
18835
  const s = c.children();
18443
18836
  return {
18444
18837
  layers: /* @__PURE__ */ new Map(),
@@ -18449,8 +18842,8 @@ var Evaluator = class {
18449
18842
  qty,
18450
18843
  layers: s.layers,
18451
18844
  thickness: this.thickness(c.env),
18452
- kerf: Number(this.dyn(c.env, "$kerf")) || 0,
18453
- material: String(this.dyn(c.env, "$material") ?? "material")
18845
+ kerf: toNumber(this.dyn(c.env, "$kerf")) || 0,
18846
+ material: toText(this.dyn(c.env, "$material") ?? "material")
18454
18847
  }
18455
18848
  ]
18456
18849
  };
@@ -18461,7 +18854,7 @@ var Evaluator = class {
18461
18854
  const n2 = this.arg(c.args, "name", 2);
18462
18855
  if (t !== void 0) c.env.vars.set("$thickness", this.num(t, "material", "thickness"));
18463
18856
  if (k !== void 0) c.env.vars.set("$kerf", this.num(k, "material", "kerf"));
18464
- if (n2 !== void 0) c.env.vars.set("$material", String(n2));
18857
+ if (n2 !== void 0) c.env.vars.set("$material", toText(n2));
18465
18858
  return c.children();
18466
18859
  },
18467
18860
  children: (c) => {
@@ -18475,7 +18868,7 @@ var Evaluator = class {
18475
18868
  if (idx === void 0) kids.forEach((k) => want.add(k));
18476
18869
  else
18477
18870
  for (const i of this.iterable(idx, c.args.at))
18478
- if (kids[Number(i)]) want.add(kids[Number(i)]);
18871
+ if (kids[toNumber(i)]) want.add(kids[toNumber(i)]);
18479
18872
  const out = [];
18480
18873
  for (const st of ctx.stmts) {
18481
18874
  if (st.kind === "assign") this.stmt(st, e);
@@ -18487,31 +18880,28 @@ var Evaluator = class {
18487
18880
  return merge(out);
18488
18881
  },
18489
18882
  echo: (c) => {
18490
- this.echoes.push(this.echoText(c.args));
18883
+ this.echo(this.echoText(c.args), c.args.at);
18491
18884
  return c.children();
18492
18885
  },
18493
18886
  assert: (c) => {
18494
- const a = c.args;
18495
- if (!truthy(a.pos[0] ?? a.named.get("condition")))
18496
- throw new KerfError(
18497
- `Assertion failed${a.pos[1] !== void 0 ? ": " + (typeof a.pos[1] === "string" ? a.pos[1] : show(a.pos[1])) : ""}`,
18498
- a.at
18499
- );
18887
+ this.assert(c.args);
18500
18888
  return c.children();
18501
18889
  },
18502
18890
  finger_rect: (c) => {
18503
18891
  const [w, h] = this.vec2(this.arg(c.args, "size", 0), "size");
18504
18892
  const edges = this.edges(this.arg(c.args, "edges", 1, "out"));
18505
18893
  const t = this.thickness(c.env);
18506
- return regionShape(fingerRect(w, h, edges, t, this.fingerWidth(c.args, c.env, 2)));
18894
+ const finger = this.fingerWidth(c.args, c.env, 2);
18895
+ this.spend(2 * (Math.abs(w) + Math.abs(h)) / finger * 4);
18896
+ return regionShape(fingerRect(w, h, edges, t, finger));
18507
18897
  },
18508
18898
  finger_holes: (c) => {
18509
18899
  const L = this.num(this.arg(c.args, "length", 0), "finger_holes", "length");
18510
18900
  const e = this.edges(this.arg(c.args, "edge", 1, "out"))[0];
18511
18901
  if (e === "flat") throw new Error('edge must be "out" or "in"');
18512
- return regionShape(
18513
- fingerHoles(L, e, this.thickness(c.env), this.fingerWidth(c.args, c.env, 2))
18514
- );
18902
+ const finger = this.fingerWidth(c.args, c.env, 2);
18903
+ this.spend(Math.abs(L) / finger * 4);
18904
+ return regionShape(fingerHoles(L, e, this.thickness(c.env), finger));
18515
18905
  },
18516
18906
  tslot: (c) => {
18517
18907
  const d2 = this.num(this.arg(c.args, "d", 0, 3), "tslot", "d");
@@ -18531,6 +18921,7 @@ var Evaluator = class {
18531
18921
  );
18532
18922
  if (spacing <= 0 || bridge <= 0 || cut <= 0)
18533
18923
  throw new Error("spacing, bridge and cut must be positive");
18924
+ this.spend((Math.abs(w) / spacing + 1) * (Math.abs(h) / (cut + bridge) + 2) * 2);
18534
18925
  return lineShape(livingHinge(w, h, spacing, bridge, cut));
18535
18926
  }
18536
18927
  };
@@ -18538,14 +18929,20 @@ var Evaluator = class {
18538
18929
  const out = { regions: [], lines: [] };
18539
18930
  for (const s of shapes) {
18540
18931
  if (s.parts.length) throw new Error(`part() can only be the first child of ${fn}()`);
18541
- for (const l of s.layers.values()) out.regions.push(...l.regions);
18932
+ for (const l of s.layers.values()) for (const p of l.regions) out.regions.push(p);
18542
18933
  }
18543
18934
  return out;
18544
18935
  }
18545
18936
  function mapLayers(s, f) {
18546
- const layers = /* @__PURE__ */ new Map();
18547
- for (const [k, l] of s.layers) layers.set(k, f(l));
18548
- return { layers, parts: s.parts };
18937
+ const each = (from) => {
18938
+ const layers = /* @__PURE__ */ new Map();
18939
+ for (const [k, l] of from) layers.set(k, f(l));
18940
+ return layers;
18941
+ };
18942
+ return {
18943
+ layers: each(s.layers),
18944
+ parts: s.parts.map((p) => ({ ...p, layers: each(p.layers) }))
18945
+ };
18549
18946
  }
18550
18947
  }
18551
18948
  };
@@ -18556,24 +18953,35 @@ var n = (v) => {
18556
18953
  return Object.is(r, -0) ? "0" : String(r);
18557
18954
  };
18558
18955
  var esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
18559
- var d = (p, closed) => `M${p.map(([x, y]) => `${n(x)} ${n(y)}`).join("L")}${closed ? "Z" : ""}`;
18956
+ function tidy(p, closed) {
18957
+ const out = [];
18958
+ for (const [x, y] of p) {
18959
+ const q = [n(x), n(y)];
18960
+ const prev = out[out.length - 1];
18961
+ if (!prev || prev[0] !== q[0] || prev[1] !== q[1]) out.push(q);
18962
+ }
18963
+ while (closed && out.length > 1 && out[0][0] === out[out.length - 1][0] && out[0][1] === out[out.length - 1][1])
18964
+ out.pop();
18965
+ return out;
18966
+ }
18967
+ var d = (p, closed) => `M${tidy(p, closed).map(([x, y]) => `${x} ${y}`).join("L")}${closed ? "Z" : ""}`;
18560
18968
  function layerPaths(items, layers) {
18561
18969
  const out = [];
18562
- for (const def of layers) {
18970
+ for (const def2 of layers) {
18563
18971
  const lines = [];
18564
18972
  const holes = [];
18565
18973
  const shapes = [];
18566
18974
  for (const it of items) {
18567
- const l = it.layers.get(def.name);
18975
+ const l = it.layers.get(def2.name);
18568
18976
  if (!l) continue;
18569
18977
  for (const p of l.lines) lines.push(d(p, false));
18570
18978
  for (const p of l.regions) (area2(p) < 0 ? holes : shapes).push(d(p, true));
18571
18979
  }
18572
18980
  if (lines.length || holes.length || shapes.length)
18573
18981
  out.push({
18574
- name: def.name,
18575
- mode: def.mode,
18576
- color: def.color,
18982
+ name: def2.name,
18983
+ mode: def2.mode,
18984
+ color: def2.color,
18577
18985
  d: [...lines, ...holes, ...shapes].join(""),
18578
18986
  regions: [...holes, ...shapes].join(""),
18579
18987
  lines: lines.join("")
@@ -18586,19 +18994,19 @@ function toSvg(items, width, height, layers) {
18586
18994
  '<?xml version="1.0" encoding="UTF-8"?>',
18587
18995
  `<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="${n(width)}mm" height="${n(height)}mm" viewBox="0 0 ${n(width)} ${n(height)}">`
18588
18996
  ];
18589
- for (const def of layers) {
18997
+ for (const def2 of layers) {
18590
18998
  const inner = [];
18591
18999
  const outer = [];
18592
19000
  for (const it of items) {
18593
- const l = it.layers.get(def.name);
19001
+ const l = it.layers.get(def2.name);
18594
19002
  if (!l) continue;
18595
19003
  const tag = ` data-part="${esc(it.part)}"`;
18596
- if (def.mode === "fill") {
19004
+ if (def2.mode === "fill") {
18597
19005
  if (l.regions.length)
18598
19006
  outer.push(`<path${tag} d="${l.regions.map((p) => d(p, true)).join("")}"/>`);
18599
19007
  for (const p of l.lines)
18600
19008
  outer.push(
18601
- `<path${tag} fill="none" stroke="${def.color}" stroke-width="0.1" d="${d(p, false)}"/>`
19009
+ `<path${tag} fill="none" stroke="${def2.color}" stroke-width="0.1" d="${d(p, false)}"/>`
18602
19010
  );
18603
19011
  continue;
18604
19012
  }
@@ -18607,9 +19015,9 @@ function toSvg(items, width, height, layers) {
18607
19015
  (area2(p) < 0 ? inner : outer).push(`<path${tag} d="${d(p, true)}"/>`);
18608
19016
  }
18609
19017
  if (!inner.length && !outer.length) continue;
18610
- const paint = def.mode === "fill" ? `fill="${def.color}" fill-rule="evenodd" stroke="none"` : `fill="none" stroke="${def.color}" stroke-width="0.1"${def.mode === "guide" ? ' stroke-dasharray="1 1"' : ""}`;
19018
+ const paint = def2.mode === "fill" ? `fill="${def2.color}" fill-rule="evenodd" stroke="none"` : `fill="none" stroke="${def2.color}" stroke-width="0.1"${def2.mode === "guide" ? ' stroke-dasharray="1 1"' : ""}`;
18611
19019
  out.push(
18612
- `<g id="${esc(def.name)}" inkscape:groupmode="layer" inkscape:label="${esc(def.name)}" data-mode="${def.mode}" ${paint}>`,
19020
+ `<g id="${esc(def2.name)}" inkscape:groupmode="layer" inkscape:label="${esc(def2.name)}" data-mode="${def2.mode}" ${paint}>`,
18613
19021
  ...inner,
18614
19022
  ...outer,
18615
19023
  "</g>"
@@ -18638,10 +19046,32 @@ var aci = (color) => {
18638
19046
  if (b > r && b > g) return 5;
18639
19047
  return 7;
18640
19048
  };
19049
+ function dxfNames(layers) {
19050
+ const base = (s) => s.toUpperCase().replace(/[^A-Z0-9_-]/g, "_");
19051
+ const builtIn = new Set(DEFAULT_LAYERS.map((l) => l.name));
19052
+ const taken = new Set(layers.map((l) => base(l.name)));
19053
+ const used = /* @__PURE__ */ new Set();
19054
+ const out = /* @__PURE__ */ new Map();
19055
+ const ordered = [
19056
+ ...layers.filter((l) => builtIn.has(l.name)),
19057
+ ...layers.filter((l) => !builtIn.has(l.name))
19058
+ ];
19059
+ for (const l of ordered) {
19060
+ let n2 = base(l.name);
19061
+ if (used.has(n2)) {
19062
+ let i = 2;
19063
+ while (taken.has(`${n2}_${i}`) || used.has(`${n2}_${i}`)) i++;
19064
+ n2 = `${n2}_${i}`;
19065
+ }
19066
+ used.add(n2);
19067
+ out.set(l.name, n2);
19068
+ }
19069
+ return out;
19070
+ }
18641
19071
  function toDxf(items, _width, height, layers) {
18642
19072
  const out = [];
18643
19073
  const g = (code, value) => out.push(String(code), String(value));
18644
- const name = (s) => s.toUpperCase().replace(/[^A-Z0-9_-]/g, "_");
19074
+ const names = dxfNames(layers);
18645
19075
  g(0, "SECTION");
18646
19076
  g(2, "HEADER");
18647
19077
  g(9, "$ACADVER");
@@ -18656,7 +19086,7 @@ function toDxf(items, _width, height, layers) {
18656
19086
  g(70, layers.length);
18657
19087
  for (const l of layers) {
18658
19088
  g(0, "LAYER");
18659
- g(2, name(l.name));
19089
+ g(2, names.get(l.name));
18660
19090
  g(70, 0);
18661
19091
  g(62, aci(l.color));
18662
19092
  g(6, "CONTINUOUS");
@@ -18673,21 +19103,24 @@ function toDxf(items, _width, height, layers) {
18673
19103
  g(20, 0);
18674
19104
  g(30, 0);
18675
19105
  g(70, closed ? 1 : 0);
18676
- for (const [x, y] of p) {
19106
+ for (const [x, y] of tidy(
19107
+ p.map(([x2, y2]) => [x2, height - y2]),
19108
+ closed
19109
+ )) {
18677
19110
  g(0, "VERTEX");
18678
19111
  g(8, layer);
18679
- g(10, n(x));
18680
- g(20, n(height - y));
19112
+ g(10, x);
19113
+ g(20, y);
18681
19114
  g(30, 0);
18682
19115
  }
18683
19116
  g(0, "SEQEND");
18684
19117
  g(8, layer);
18685
19118
  };
18686
- for (const def of layers) {
18687
- const ln = name(def.name);
19119
+ for (const def2 of layers) {
19120
+ const ln = names.get(def2.name);
18688
19121
  const outer = [];
18689
19122
  for (const it of items) {
18690
- const l = it.layers.get(def.name);
19123
+ const l = it.layers.get(def2.name);
18691
19124
  if (!l) continue;
18692
19125
  for (const p of l.lines) poly(ln, p, false);
18693
19126
  for (const p of l.regions) area2(p) < 0 ? poly(ln, p, true) : outer.push(p);
@@ -18709,19 +19142,30 @@ var perimeter = (p, closed) => {
18709
19142
  };
18710
19143
  var round2 = (n2) => Math.round(n2 * 100) / 100;
18711
19144
  function render(source, options = {}) {
19145
+ for (const [name, v] of Object.entries(options.params ?? {})) {
19146
+ try {
19147
+ checkSetting(name, v);
19148
+ } catch (e) {
19149
+ throw new KerfError(e.message);
19150
+ }
19151
+ }
18712
19152
  const { program } = parse(source);
18713
19153
  const fonts = options.fonts ? new FontBook(options.fonts, options.defaultFont) : void 0;
18714
19154
  const ev = new Evaluator({
18715
19155
  overrides: options.params,
18716
19156
  resolve: options.resolve,
18717
19157
  fonts,
18718
- maxSteps: options.maxSteps
19158
+ maxSteps: options.maxSteps,
19159
+ limits: options.limits
18719
19160
  });
19161
+ const limits = ev.limits;
18720
19162
  let res;
18721
19163
  try {
18722
19164
  res = ev.run(program);
18723
19165
  } catch (e) {
18724
- const err = e instanceof RangeError && /call stack/i.test(e.message) ? new KerfError("Recursion too deep: the program calls itself without stopping") : e;
19166
+ const err = e instanceof RangeError ? new KerfError(
19167
+ /call stack/i.test(e.message) ? "Recursion too deep: the program calls itself without stopping" : "A value grew too large. Is a list or string doubling without end?"
19168
+ ) : e;
18725
19169
  if (err instanceof KerfError) {
18726
19170
  err.echoes = ev.echoes;
18727
19171
  if (fonts?.missing.size) err.missingFonts = [...fonts.missing];
@@ -18739,9 +19183,9 @@ function render(source, options = {}) {
18739
19183
  name: "part",
18740
19184
  qty: 1,
18741
19185
  layers: res.shape.layers,
18742
- thickness: Number(g("$thickness")) || 3,
18743
- kerf: Number(g("$kerf")) || 0,
18744
- material: String(g("$material") ?? "material")
19186
+ thickness: toNumber(g("$thickness")) || 3,
19187
+ kerf: toNumber(g("$kerf")) || 0,
19188
+ material: toText(g("$material") ?? "material")
18745
19189
  });
18746
19190
  if (!parts.length) warnings.push("Nothing to cut: the program made no shapes.");
18747
19191
  const infos = [];
@@ -18778,6 +19222,8 @@ function render(source, options = {}) {
18778
19222
  }
18779
19223
  const b = layerBounds(layers) ?? [0, 0, 0, 0];
18780
19224
  const kerf = options.kerf ?? p.kerf;
19225
+ if (!(Number.isFinite(kerf) && kerf >= 0))
19226
+ throw new KerfError("$kerf must be a number, 0 or more");
18781
19227
  const info = {
18782
19228
  name: p.name,
18783
19229
  qty: p.qty,
@@ -18804,11 +19250,27 @@ function render(source, options = {}) {
18804
19250
  infos.push(info);
18805
19251
  ready.push({ info, layers });
18806
19252
  }
19253
+ let outputPoints = 0;
19254
+ for (const r of ready) {
19255
+ let n2 = 0;
19256
+ for (const l of r.layers.values()) {
19257
+ for (const p of l.regions) n2 += p.length;
19258
+ for (const p of l.lines) n2 += p.length;
19259
+ }
19260
+ outputPoints += n2 * r.info.qty;
19261
+ }
19262
+ if (outputPoints > limits.maxOutputPoints)
19263
+ throw new KerfError(
19264
+ `The files would have ${outputPoints} points, more than the limit of ${limits.maxOutputPoints}. Use fewer copies or simpler shapes.`
19265
+ );
18807
19266
  const sheetSize = options.sheet ?? g("$sheet");
18808
- if (!Array.isArray(sheetSize) || typeof sheetSize[0] !== "number" || typeof sheetSize[1] !== "number")
18809
- throw new KerfError("$sheet must be [width, height]");
18810
- const gap = options.gap ?? Number(g("$gap") ?? 3);
19267
+ if (!Array.isArray(sheetSize) || !(Number.isFinite(sheetSize[0]) && sheetSize[0] > 0) || !(Number.isFinite(sheetSize[1]) && sheetSize[1] > 0))
19268
+ throw new KerfError("$sheet must be [width, height], both more than 0");
19269
+ const gap = options.gap ?? toNumber(g("$gap") ?? 3);
18811
19270
  const margin = options.margin ?? gap;
19271
+ if (!(Number.isFinite(gap) && gap >= 0)) throw new KerfError("$gap must be a number, 0 or more");
19272
+ if (!(Number.isFinite(margin) && margin >= 0))
19273
+ throw new KerfError("margin must be a number, 0 or more");
18812
19274
  const layoutMode = options.layout ?? (g("$layout") === "none" ? "none" : "pack");
18813
19275
  const order = [
18814
19276
  "engrave",
@@ -18836,8 +19298,8 @@ function render(source, options = {}) {
18836
19298
  for (const it of items)
18837
19299
  for (const [k, l] of it.layers) {
18838
19300
  const t = all.get(k) ?? { regions: [], lines: [] };
18839
- t.regions.push(...l.regions);
18840
- t.lines.push(...l.lines);
19301
+ for (const p of l.regions) t.regions.push(p);
19302
+ for (const p of l.lines) t.lines.push(p);
18841
19303
  all.set(k, t);
18842
19304
  }
18843
19305
  const b = exportBounds(all);
@@ -18879,6 +19341,10 @@ function render(source, options = {}) {
18879
19341
  let items = [];
18880
19342
  let x = margin, y = margin, shelf = 0, usedW = 0, usedH = 0;
18881
19343
  const flush = () => {
19344
+ if (items.length && sheets.length >= limits.maxSheets)
19345
+ throw new KerfError(
19346
+ `The parts need more than ${limits.maxSheets} sheets, the limit. Use fewer copies or a bigger $sheet.`
19347
+ );
18882
19348
  if (items.length)
18883
19349
  sheets.push(
18884
19350
  finishSheet(
@@ -19037,9 +19503,18 @@ function parameters(source) {
19037
19503
  }
19038
19504
 
19039
19505
  // src/index.ts
19040
- var VERSION = "0.2.0";
19506
+ var VERSION = "0.3.0";
19041
19507
  var LANGUAGE_VERSION = "0.1";
19042
19508
 
19509
+ // fonts/AtkinsonHyperlegible-Regular.ttf
19510
+ var AtkinsonHyperlegible_Regular_default = __toBinaryNode("AAEAAAASAQAABAAgRFNJRwAAAAEAANREAAAACEdERUYmIiVoAACtoAAAAPhHUE9TBhS8lAAArpgAACDKR1NVQs2+72cAAM9kAAAE3k9TLzKBnCDAAAABqAAAAGBjbWFwMF4gUgAAB8wAAAOOY3Z0IBXBCrQAABooAAAAbGZwZ21iLv99AAALXAAADgxnYXNwAAAAEAAArZgAAAAIZ2x5ZhpHbHEAAB14AACEOGhlYWQdEfmxAAABLAAAADZoaGVhCIkENgAAAWQAAAAkaG10eMbdPbEAAAIIAAAFwmxvY2GjLsNGAAAalAAAAuRtYXhwAssPEgAAAYgAAAAgbmFtZXEwlLkAAKGwAAAEpnBvc3S6e2pLAACmWAAAB0BwcmVwWrHfOwAAGWgAAAC9AAEAAAABAYk7pItRXw889QAPA+gAAAAA3G3PNQAAAADcsOWS/8b/BgUKA3gAAAAGAAIAAAAAAAAAAQAAA7b+3gAABTD/xv63BQoAAQAAAAAAAAAAAAAAAAAAAXAAAQAAAXEAWAAHAFQABAACACoAVwCNAAAAlQ4MAAIAAQAEAhYBkAAFAAACigK7AAAAjAKKArsAAAHfADEBAgAAAAAAAAAAAAAAAIAAAO8AACBLAAAAAAAAAABOT05FAMAADSXKA7b+3gAAA7YBIiAAAAMAAAAAAfACnAAAACAAAwIPADICWAAAAAAAAAEYAAABGAAAAogAPAGSACoCJQAiAj4AKgJmACYCRwA2AlYAPAH+AA8CZwA8AlYAPAJyAAoCawBMApAAMgKhAEwCNwBMAiQATALGADICsgBMAZ4AQgH+AA8CcwBMAhsATAM0AEwCsQBMAtcAMgJZAEwC8QAyAmoATAJUACgCLgAKArIATAJNAAoDSAAKAm8ACgJTAAoCXwAsAg4AJgI2AEYB9AAmAjQAJgIbACYBNwAPAjAAJgIiAEYBFgAtAP7/xgHqAEYA7wBGA0kARgIiAEYCKAAmAjYARgJAACYBVABGAdcAHwFEABQCGABEAbkAAAKOAAABzQAAAa0AAAHMACgBrQA1Aa0ANQGPADUA1gA1AP0ADwEHADUA6wA1AOsANQDrADUBjgA1AY4ANQGOADUCHQAoAh0AKAG2ADUCuAA1BTAAJgFhADUBYQA1AkoADwFzADUCMgA1AloANQMeADUBfgA1AWAAKAJDADUBfgA1AX8ANQEMADUCGgBGAfwAJgDrADUBIwBJAQAANQF9ADkCMgA1AzoANQMsADUDZAA1AikAKAJaADUCKQAoAggAKAMMADIAzQAmAM0AJgE7AEwBeQAPATsAIQIoADUBjAAKAQwANQEZAEwBLQAoAo8AJgJSACgDnwAmAsEAJgCgACgBLAAyASwAIwGxAEQCWgA1AM0AJgFwACYAzQAmAXkADwE/ACYA6QBMAT8AIgIrACgBGQBMAfQAJgJKAEYCRAA1AlMACgDpAEwCEgAfAakANQMeADUCCAAxAlUATAPmAAoBQQAZAcoANQJFADUCWgA1AkMANQJDADUCMQA1AksANQJaADUCVgAPAOsANQJGADUDBQA1Aq8AMgJuADUCRgA1AvcANQJJADUCTwAUAZ4ANQGzADUB4AApAyAAKQNQADUBwgA1Aj0AFADtAA8CKAAmAtcAMgJAAEwDagAmAjcAJgI2AEYCEAA1AloANQQcADIDnwAmAnIACgJyAAoCcgAKAnIACgJyAAoCcgAKAnIACgIOACYCDgAmAg4AJgIOACYCDgAmAg4AJgIOACYCkAAyAfQAJgI3AEwCNwBMAjcATAI3AEwCGwAmAhsAJgIbACYCGwAmAZ4AQgGeAEIBngAtAZ4ALwEWABoBFgAtARb/5AEW/+YCsQBMAtcAMgLXADIC1wAyAtcAMgLXADICsgBMArIATAKyAEwCsgBMAlMACgIiAEYCKAAmAigAJgIoACYCKAAmAigAJgIYAEQCGABEAhgARAIYAEQBrQAAAa0AAAJUACgB1wAfAlMACgJfACwBzAAoAsgAFAJ/ADgCfwBtAn8ATwJ/AFQCfwAzAn8AVgJ/AFECfwBZAn8ASAJ/AFECcgAKAg4AJgJyAAoCDgAmAjcATAIbACYCNwBMAhsAJgI3AEwCGwAmAjcATAIbACYC1wAyAigAJgGeAEIBFv/8AZ4AQgEWACICkAAyAfQAJgKQADIB9AAmAlQAKAHXAB8CsgBMAhgARAKyAEwCGABEArIATAIYAEQCsgBMAhgARAKxAEwCIgBGArEATAIiAEYCXwAsAcwAKAJfACwBzAAoAsYACgJFABQCxgAyAjAAJgLGADICMAAmAjAAJgIbAEwA7wA3Ai4ACgDvAEYCGwBMAUQAFAKxAEwCIgBGAmoATAFUAEYCagBMAVQAJQLIABQCWwAm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JUawF0NYUBtSWVggPFkusTABFCstsEQssDsriiAgPLAGI0KKOCMgLkawAiVGsBdDWFAbUllYIDxZLrEwARQrsAZDLrAwKy2wRSywABawBCWwBCYgICBGI0dhsAwjQi5HI0cjYbALQysjIDwgLiM4sTABFCstsEYssQoEJUKwABawBCWwBCUgLkcjRyNhILAGI0KxDABCsAtDKyCwYFBYILBAUVizBCAFIBuzBCYFGllCQiMgR7AGQ7ACYiCwAFBYsEBgWWawAWNgILABKyCKimEgsARDYGQjsAVDYWRQWLAEQ2EbsAVDYFmwAyWwAmIgsABQWLBAYFlmsAFjYbACJUZhOCMgPCM4GyEgIEYjR7ABKyNhOCFZsTABFCstsEcssQA6Ky6xMAEUKy2wSCyxADsrISMgIDywBiNCIzixMAEUK7AGQy6wMCstsEkssAAVIEewACNCsgABARUUEy6wNiotsEossAAVIEewACNCsgABARUUEy6wNiotsEsssQABFBOwNyotsEwssDkqLbBNLLAAFkUjIC4gRoojYTixMAEUKy2wTiywCiNCsE0rLbBPLLIAAEYrLbBQLLIAAUYrLbBRLLIBAEYrLbBSLLIBAUYrLbBTLLIAAEcrLbBULLIAAUcrLbBVLLIBAEcrLbBWLLIBAUcrLbBXLLMAAABDKy2wWCyzAAEAQystsFksswEAAEMrLbBaLLMBAQBDKy2wWyyzAAABQystsFwsswABAUMrLbBdLLMBAAFDKy2wXiyzAQEBQystsF8ssgAARSstsGAssgABRSstsGEssgEARSstsGIssgEBRSstsGMssgAASCstsGQssgABSCstsGUssgEASCstsGYssgEBSCstsGcsswAAAEQrLbBoLLMAAQBEKy2waSyzAQAARCstsGosswEBAEQrLbBrLLMAAAFEKy2wbCyzAAEBRCstsG0sswEAAUQrLbBuLLMBAQFEKy2wbyyxADwrLrEwARQrLbBwLLEAPCuwQCstsHEssQA8K7BBKy2wciywABaxADwrsEIrLbBzLLEBPCuwQCstsHQssQE8K7BBKy2wdSywABaxATwrsEIrLbB2LLEAPSsusTABFCstsHcssQA9K7BAKy2weCyxAD0rsEErLbB5LLEAPSuwQistsHossQE9K7BAKy2weyyxAT0rsEErLbB8LLEBPSuwQist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AF8ArAAIsQIBsKywNSsAAP//AAoAAAJoA08CJgAPAAABBwCSAGQAlgAIsQICsJawNSsAAP//AAoAAAJoA0YCJgAPAAABBwBHAL0APQAIsQICsD2wNSsAAP//AAoAAAJoA2ACJgAPAAAABwFfAL8AAP//AAoAAAJoA2ACJgAPAAAABwFNAP8AAP//AAoAAAJoAz0CJgAPAAABBwBbAHoAoQAIsQIBsKGwNSsAAP//ACb/9AHbApwCJgApAAAABgFjfQAAAP//ACb/9AHbAsMCJgApAAAABwFeAJsAAP//ACb/9AHbArcCJgApAAAABgFVZQAAAP//ACb/9AHbAqkCJgApAAAABgFvYgAAAP//ACb/9AHbArkCJgApAAAABgFYZwAAAP//ACb/9AHbAwkCJgApAAAABwFoAJoAAP//ACb/9AHbAsMCJgApAAAABwFMANgAAP//ADL/SwJqAqgCJgARAAAABwFUAQMAAP//ACb/SwHTAfgCJgArAAAABwFUALUAAP//AEwAAAIRA2ACJgATAAAABwFfALYAAP//AEwAAAIRA2ACJgATAAAABwFNAPYAAP//AEwAAAIRA2MCJgATAAAABwFWAI4AAP//AEwAAAIRA08CJgATAAABBwCSAFsAlgAIsQECsJawNSsAAP//ACb/9AICAsMCJgAtAAAABwFeAK0AAP//ACb/9AICAsMCJgAtAAAABwFMAOoAAP//ACb/9AICArcCJgAtAAAABgFVdwAAAP//ACb/9AICArkCJgAtAAAABgFYeQAAAP//AEIAAAFcA2ACJgAXAAAABgFfVQAAAP//AEIAAAFcA2ACJgAXAAAABwFNAJUAAP//AC0AAAFwA2MCJgAXAAAABgFWLQAAAP//AC8AAAFuA08CJgAXAAABBwCS//oAlgAIsQECsJawNSsAAP//ABoAAADGAsMCJgFiAAAABgFeGgAAAP//AC0AAAD5AsMCJgFiAAAABgFMVwAAAP///+QAAAEnArcCJgFiAAAABgFV5AAAAP///+YAAAElArkCJgFiAAAABgFY5gAAAP//AEwAAAJlA1UCJgAcAAABBwCrAJAArAAIsQEBsKywNSsAAP//ADL/9AKlA2ACJgAdAAAABwFfAPIAAP//ADL/9AKlA2ACJgAdAAAABwFNATIAAP//ADL/9AKlA2MCJgAdAAAABwFW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AAEECQAAAGIAAAADAAEECQABACoAYgADAAEECQACAA4AjAADAAEECQADAE4AmgADAAEECQAEADoA6AADAAEECQAFAEYBIgADAAEECQAGADgBaAADAAEECQAIACIBoAADAAEECQAJAHoBwgADAAEECQALAEICPAADAAEECQAMAC4CfgADAAEECQANASICrAADAAEECQAOADYDzgBDAG8AcAB5AHIAaQBnAGgAdAAgADIAMAAyADAAIABCAHIAYQBpAGwAbABlACAASQBuAHMAdABpAHQAdQB0AGUAIABvAGYAIABBAG0AZQByAGkAYwBhACwAIABJAG4AYwAuAEEAdABrAGkAbgBzAG8AbgAgAEgAeQBwAGUAcgBsAGUAZwBpAGIAbABlAFIAZQBnAHUAbABhAHIAMQAuADAAMAA2ADsATgBPAE4ARQA7AEEAdABrAGkAbgBzAG8AbgBIAHkAcABlAHIAbABlAGcAaQBiAGwAZQAtAFIAZQBnAHUAbABhAHIAQQB0AGsAaQBuAHMAbwBuACAASAB5AHAAZQByAGwAZQBnAGkAYgBsAGUAIABSAGUAZwB1AGwAYQByAFYAZQByAHMAaQBvAG4AIAAxAC4AMAAwADYAOwAgAHQAdABmAGEAdQB0AG8AaABpAG4AdAAgACgAdgAxAC4AOAAuADMAKQBBAHQAawBpAG4AcwBvAG4ASAB5AHAAZQByAGwAZQBnAGkAYgBsAGUALQBSAGUAZwB1AGwAYQByAEIAcgBhAGkAbABsAGUAIABJAG4AcwB0AGkAdAB1AHQAZQBFAGwAbABpAG8AdAB0ACAAUwBjAG8AdAB0ACwAIABNAGUAZwBhAG4AIABFAGkAcwB3AGUAcgB0AGgALAAgAEwAaQBuAHUAcwAgAEIAbwBtAGEAbgAsACAAVABoAGUAbwBkAG8AcgBlACAAUABlAHQAcgBvAHMAawB5AGgAdAB0AHAAcwA6AC8ALwB3AHcAdwAuAEIAcgBhAGkAbABsAGUASQBuAHMAdABpAHQAdQB0AGUALgBvAHIAZwAvAGgAdAB0AHAAOgAvAC8AaABlAGwAbABvAGEAcABwAGwAaQBlAGQALgBjAG8AbQBUAGgAaQBzACAARgBvAG4AdAAgAFMAbwBmAHQAdwBhAHIAZQAgAGkAcwAgAGwAaQBjAGUAbgBzAGUAZAAgAHUAbgBkAGUAcgAgAHQAaABlACAAUwBJAEwAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUALAAgAFYAZQByAHMAaQBvAG4AIAAxAC4AMQAuACAAVABoAGkAcwAgAGwAaQBjAGUAbgBzAGUAIABpAHMAIABhAHYAYQBpAGwAYQBiAGwAZQAgAHcAaQB0AGgAIABhACAARgBBAFEAIABhAHQAOgAgAGgAdAB0AHAAcwA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAGgAdAB0AHAAcwA6AC8ALwBzAGMAcgBpAHAAdABzAC4AcwBpAGwALgBvAHIAZwAvAE8ARgBMAAAAAgAAAAAAAP+yADkAAAAAAAAAAAAAAAAAAAAAAAAAAAFxAAABAgEDAAMBBAATABQAFQAWABcAGAAZABoAGwAcACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0A2ADhANsA3ADdAOAAtgC3AMQAtAC1AMUAggDCAIcAqwDGAL4AvwC8AJ0AqQCkAIoA2gCDAJMBBQEGAI0BBwCIAMMA3gEIAJ4AqgD1APQA9gAfACAAIQAiACMAHQAeAD4APwBAAEEAQgBDAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASAF4AXwBgAGEAowCEAIUAvQCWAOgAhgCOAIsAogCJAJAApgCcAKcAjwCUAJUAuQCZAO8BCQEKAKUAkgELAQwAmAENAJoAmwDfANkAsgCzAIwBDgDiAOMAoQCRAO0AoADqAO4A8AC4ALAAsQDHAK4AYgBjAK0AyQEPARAAagBrAG0AbABuAGkAZABvAMsAZQDIAMoAcQBwAHIAcwDPAMwAzQDOAHUAdAB2AHcAZgDTANAA0QCvAGcA1gDUANUAaADrAHgAegB5AHsAfQB8AH8AfgCAAIEA7AC6AOQA5QC7AOYA5wDpAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwA/QD+AS0BLgEvATABMQEyATMBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8BQAFBAUIA+AD5AUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBAQFTAVQBVQFWAVcA/wEAAPsA/AFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwANcBcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+BE5VTEwCQ1IHdW5pMDBBMAd1bmkwMEIyB3VuaTAwQjMHdW5pMDNCQwd1bmkwMEI5B3VuaTIyMTUHdW5pMjIxOQd1bmkwM0E5CWVzdGltYXRlZAd1bmkwMzk0B3VuaTIxMTMHQW1hY3JvbgdhbWFjcm9uB3plcm8udGYGb25lLnRmBnR3by50Zgh0aHJlZS50Zgdmb3VyLnRmB2ZpdmUudGYGc2l4LnRmCHNldmVuLnRmCGVpZ2h0LnRmB25pbmUudGYGQWJyZXZlBmFicmV2ZQdBb2dvbmVrB2FvZ29uZWsHRW1hY3JvbgdlbWFjcm9uCkVkb3RhY2NlbnQKZWRvdGFjY2VudAdFb2dvbmVrB2VvZ29uZWsGRWNhcm9uBmVjYXJvbg1PaHVuZ2FydW1sYXV0DW9odW5nYXJ1bWxhdXQHSW1hY3JvbgdpbWFjcm9uB0lvZ29uZWsHaW9nb25lawpDZG90YWNjZW50CmNkb3RhY2NlbnQGU2FjdXRlBnNhY3V0ZQdVbWFjcm9uB3VtYWNyb24FVXJpbmcFdXJpbmcNVWh1bmdhcnVtbGF1dA11aHVuZ2FydW1sYXV0B1VvZ29uZWsHdW9nb25lawZOYWN1dGUGbmFjdXRlBk5jYXJvbgZuY2Fyb24GWmFjdXRlBnphY3V0ZQpaZG90YWNjZW50Cnpkb3RhY2NlbnQESGJhcgRoYmFyCkdkb3RhY2NlbnQKZ2RvdGFjY2VudAd1bmkwMTIzB3VuaTAxM0IHdW5pMDEzQwZUY2Fyb24GbGNhcm9uBkxjYXJvbgZ0Y2Fyb24HdW5pMDE0NQd1bmkwMTQ2BlJhY3V0ZQZyYWN1dGUGUmNhcm9uBnJjYXJvbgZEY3JvYXQGRGNhcm9uBmRjYXJvbgd1bmkwMTM2B3VuaTAxMzcHdW5pMDEyMgd1bmkwMjE4B3VuaTAxNjIHdW5pMDIxQQlhY3V0ZWNvbWIOYWN1dGVjb21iLmNh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/64Aw//kAMT/5ADF/+QAxv/kAMf/5ADI/+QAyf/kAOb/7QD0/+0A9f/tAPb/7QED/64BBP/kAQX/rgEG/+QBGv/tAUj/7QFq/+0AEgAPABwAJgATACf/2gBCABMAvAAcAL0AHAC+ABwAvwAcAMAAHADBABwAwgAcAOb/2gD1/9oA9wATAQMAHAEFABwBKAATASoAEwBbAA//vQAR/+QAFf/kABj/2gAd/+QAH//kACIAJgAkABMAJQATACcAEwAp/9oAK//RACz/0QAt/9EAL//RADX/7QA2/+0AN//RADn/0QA7/+0Alv+iALL/0QC1/9oAtv/RALr/5AC7/9EAvP+9AL3/vQC+/70Av/+9AMD/vQDB/70Awv+9AMP/2gDE/9oAxf/aAMb/2gDH/9oAyP/aAMn/2gDK/+QAy//RAND/0QDR/9EA0v/RANP/0QDd/+QA3v/kAN//5ADg/+QA4f/kAOYAEwDn/+0A6P/RAOn/0QDq/9EA6//RAOz/0QD0/+0A9QATAQP/vQEE/9oBBf+9AQb/2gEI/9EBCv/RAQz/0QEO/9EBFf/kARb/0QEX/+QBGP/RARr/7QEk/+0BJv/tAS3/5AEu/9EBL//kATD/0QEx/9EBNAAmATn/7QE//9EBQf/RAUT/5AFF/+QBRv/RAUj/7QFKACYBSwAmAWr/7QBLAA//0QAR/+0AFf/tABj/5AAd/+0AH//tACIAHAAkABMAKf/kACv/6QAs/+kALf/pAC//5AA3/+kAOf/pALL/6QC1/+QAtv/pALr/7QC7/+kAvP/RAL3/0QC+/9EAv//RAMD/0QDB/9EAwv/RAMP/5ADE/+QAxf/kAMb/5ADH/+QAyP/kAMn/5ADK/+0Ay//pAND/6QDR/+kA0v/pANP/6QDd/+0A3v/tAN//7QDg/+0A4f/tAOj/6QDp/+kA6v/pAOv/6QDs/+kBA//RAQT/5AEF/9EBBv/kAQj/6QEK/+kBDP/pAQ7/6QEV/+0BFv/pARf/7QEY/+kBLf/tAS7/5AEv/+0BMP/kATH/5AE0ABwBP//pAUH/6QFE/+0BRf/tAUb/6QFKABwBSwAcAC0AEf/kABX/5AAd/+QAH//kACn/7QAv/+0APf/kAD7/7QBB/+0Atf/tALr/5ADD/+0AxP/tAMX/7QDG/+0Ax//tAMj/7QDJ/+0Ayv/kAN3/5ADe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AQYBBwEIAQkBCgELAQwBDQEOAREBEwEVARYBFwEYARoBHgEgASIBJAEmAScBKAEpASoBNAE1ATcBOQE6ATwBPgE/AUABQQFFAUYBSAFKAUsBagFsAW4AAgBbAA8ADwAEABEAEQALABIAEgADABMAEwACABcAFwAGABoAGgAWAB0AHQADACAAIAASACIAIgAQACMAIwAKACcAJwARACgAKAAPACsAKwAJAC0ALQABAC4ALgAVADkAOQAXADsAOwAHADwAPAAOAD0APQAFAD4APgANAEEAQQANAEIAQgAMAEoASgATAEsASwAIAE0ATQATAE4ATgAIAFIAUgAIAIMAgwAIAIUAhQAIAJYAlgACALAAsAAWALUAtQABALYAtgADALoAugACALsAuwABALwAwgAEAMoAygALAMsAywAJAMwAzwACANAA0wABANQA1wAGAN0A4QADAOIA5QAKAOYA5gARAO0A8AAFAPEA8gANAPQA9AAHAPUA9QARAPYA9gAPAPcA9wAMAPgA+AADAQMBAwAEAQUBBQAEAQcBBwACAQgBCAABAQkBCQACAQoBCgABAQsBCwACAQwBDAABAQ0BDQACAQ4BDgABAREBEQAGARMBEwAGARUBFQALARYBFgAJARcBFwALARgBGAAJARoBGgAHAR4BHgAFASABIAAFASIBIgAFAScBJwAPASgBKAAMASkBKQAPASoBKgAMATQBNAAQATUBNQAUATcBNwAOAToBOgASATwBPAASAT4BPgADAT8BPwAVAUABQAADAUEBQQAUAUUBRQALAUYBRgAJAUgBSAAHAUoBSwAQAWoBagAHAWwBbAAOAW4BbgAOAAIAUgAPAA8ABAARABEAAgAVABUAAgAdAB0AAgAfAB8AAgAiACIADQAnACcADgAoACgADwApACkAAwArAC0AAQAvAC8ADAAxADEABgA2ADYACAA3ADcAAQA5ADkAAQA7ADsABwA8ADwACwA9AD0ABQA+AD4ACgBBAEEACgBCAEIACQCyALIAAQC1ALUAAwC2ALYAAQC6ALoAAgC7ALsAAQC8AMIABADDAMkAAwDKAMoAAgDLAMsAAQDQANMAAQDYANsABgDdAOEAAgDmAOYADgDnAOcACADoAOwAAQDtAPAABQDxAPIACgD0APQABwD1APUADgD2APYADwD3APcACQEDAQMABAEEAQQAAwEFAQUABAEGAQYAAwEIAQgAAQEKAQoAAQEMAQwAAQEOAQ4AAQESARIABgEUARQABgEVARUAAgEWARYAAQEXARcAAgEYARgAAQEaARoABwEcARwABQEeAR4ABQEgASAABQEiASIABQEkASQACAEmASYACAEoASgACQEqASoACQEtAS0AAgEuAS4ADAEvAS8AAgEwATEADAE0ATQADQE3ATcACwE5ATkACAE/AT8AAQFBAUEAAQFEAUUAAgFGAUYAAQFIAUgABwFKAUsADQFiAWIABgFqAWoABwFsAWwACwFuAW4ACwAEAAAAAQAIAAEADAA0AAQAtgEwAAIABgFMAU8AAAFRAVsABAFeAWEADwFjAWQAEwFmAWkAFQFvAXAAGQACABUADwAPAAAAEQATAAEAFQAXAAQAGQAaAAcAHAAdAAkAIAAjAAsAJwApAA8AKwAtABIALwAwABUAMwA3ABcAOgA9ABwAQQBCACAAvAD4ACIBAwETAF8BFQEhAHABIwErAH0BLQE+AIYBQAFLAJgBYgFiAKQBagFqAKUBbAFuAKYAGwAAC0IAAAtIAAALTgAAC1QAAAtaAAEAbgAAC2AAAgqEAAALWgAAC2AAAgqKAAALZgAAC2wAAAtyAAALeAAAC34AAAuEAAALigAAC5AAAAuWAAAMPAADAHQAAwB0AAALnAAAC6IAAAuoAAALrgABAAACmwABAJ0AAACpBwYAAAcMBxIF7AAACXwAAAVKAAAJOgAABzwAAAdOB1QJagAACIwAAAgUAAAIIAAAB6IAAAeoB64JUgAABVAAAAjUCNoI4AAACOwAAAg+AAAFVgdsB3IHeAVcAAAJFgAACZoAAAfSAAAJpgAACLwAAAgUCBoIIAgmCZoAAAfSAAAHPAAACGIAAAcYAAAHHgckBfgAAAmIAAAJQAlGCUwAAAdCAAAJiAdgCJ4AAAiYAAAFYgAAB64AAAleAAAFaAAACMIIyAjOAAAFbgAABXQAAAj4AAAISgAABXoHhAeKB5AFgAAACSIAAAnEAAAIbgAACuAJ1gjmAAAFhggCCAgIDgWMAAAG3AAABZIAAAhuAAAFmAAABwwHEgWeAAAHDAcSBaQAAAcMBxIFqgAABwwHEgWwAAAHDAcSBbYAAAcMBxIFvAAABwwHEgXCAAAHHgckBcgAAAceByQFzgAABx4HJAXUAAAHHgckBdoAAAceByQF4AAABx4HJAXmAAAHHgckBewAAAXyAAAF+AAABf4AAAYEAAAHTgdUCFAAAAdOB1QGCgAAB04HVAYQAAAHTgdUBtAAAAmIB2AGFgAACYgHYAYcAAAJiAdgBiIAAAmIB2AGKAAAB6gHrgYuAAAHqAeuBjQAAAeoB64GOgAAB6gHrgZAAAAJuAm+BkYAAAm4Cb4GTAAACbgJvgZSAAAJuAm+BlgAAAg+AAAGXgdsB3IHeAZkB2wHcgd4BmoHbAdyB3gGcAdsB3IHeAZ2B2wHcgd4BnwIGgggCCYGgggaCCAIJgaICBoIIAgmBo4IGgggCCYHzAAAB9IAAAaUAAAISgAABpoHhAeKB5AGoAeEB4oHkAamB4QHigeQBqwHhAeKB5AGsgeEB4oHkAa4CAIICAgOBr4IAggICA4GxAgCCAgIDgbKCAIICAgOBtAAAAbcAAAG1gAABtwAAAbiAAAH0gAABugAAAhuAAAG7gAAB9IAAAdIAAAIYgAABvQAAAhuAAAJKAAACS4AAAb6AAAHDAcSBwAAAAceByQHBgAABwwHEgcYAAAHHgckByoAAAdOB1QHMAAACYgHYAhcAAAHTgdUBzYAAAmIB2AHPAAAB04HVAdCAAAJiAdgB0gAAAdOB1QHWgAACYgHYAdmB2wHcgd4B34HhAeKB5AHlgAAB6gHrgecAAAJuAm+B6IAAAeoB64HtAAACXwAAAe6AAAJiAAAB8AAAAl8AAAHxgAACYgAAAfMAAAH0gAAB9gAAAhuAAAH3ggaCCAIJgfkCAIICAgOB+oIGgggCCYH8AgCCAgIDgf2CBoIIAgmB/wIAggICA4IFAgaCCAIJggsAAAIPgAACDIAAAhKAAAIOAAACD4AAAhEAAAISgAACFAAAAhiAAAIVgAACG4AAAhcAAAIYgAACGgAAAhuAAAIdAAACIwAAAh6AAAIjAAACIAAAAiYAAAIhgAACIwAAAiSAAAImAAACJ4AAAikAAAI1AjaCKoAAAjCCMgIsAAACLYAAAi8AAAIwgjICM4AAAjUCNoI4AAACuAJ1gjmAAAI7AAACPIAAAj4AAAI/gAACQQAAAkWAAAJCgAACSIAAAkQAAAJFgAACRwAAAkiAAAJKAAACS4AAAk0AAAJOgAACUAJRglMAAAJUgAACVgAAAleAAAJZAAACWoAAAlw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");
19511
+
19512
+ // src/font.ts
19513
+ var BUILTIN_FONT = "Atkinson";
19514
+ function withBuiltinFont(fonts) {
19515
+ return BUILTIN_FONT in fonts ? fonts : { ...fonts, [BUILTIN_FONT]: AtkinsonHyperlegible_Regular_default };
19516
+ }
19517
+
19043
19518
  // src/cli.ts
19044
19519
  var HELP = `kerf ${VERSION}: the KerfScript laser cutting language
19045
19520
 
@@ -19052,7 +19527,8 @@ Options:
19052
19527
  -o, --out <file> output file (.svg, .dxf or .json); default <file>.svg
19053
19528
  -D name=value set a parameter (value is KerfScript: 40, "Oak", true, [1,2])
19054
19529
  -p, --params <file> JSON file of parameter values
19055
- --font <file.ttf> font for text(); repeat for more fonts (name = file name)
19530
+ --font <file.ttf> font for text(); repeat for more fonts (name = file name).
19531
+ Built in: ${BUILTIN_FONT}
19056
19532
  --kerf <mm> override kerf compensation for all parts
19057
19533
  --sheet <W>x<H> sheet size for packing, in mm
19058
19534
  --gap <mm> space between packed parts
@@ -19067,8 +19543,8 @@ function fail(msg) {
19067
19543
  process.stderr.write(msg + "\n");
19068
19544
  process.exit(1);
19069
19545
  }
19070
- function parseValue(text) {
19071
- const { program } = parse(`__v = ${text};`);
19546
+ function parseValue(text2) {
19547
+ const { program } = parse(`__v = ${text2};`);
19072
19548
  const ev = new Evaluator();
19073
19549
  const res = ev.run(program);
19074
19550
  return res.globals.get("__v").value;
@@ -19142,7 +19618,7 @@ function main(argv) {
19142
19618
  const result = render(source, {
19143
19619
  ...opts,
19144
19620
  params,
19145
- fonts: Object.keys(fonts).length ? fonts : void 0,
19621
+ fonts: withBuiltinFont(fonts),
19146
19622
  resolve: resolveLib
19147
19623
  });
19148
19624
  for (const e of result.echoes) process.stderr.write(`ECHO: ${e}