@patterkit/cli 0.3.0 → 0.3.2

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 (2) hide show
  1. package/dist/cli.js +1502 -1404
  2. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -3609,7 +3609,7 @@ var require_worksheet = __commonJS({
3609
3609
  // =========================================================================
3610
3610
  // Worksheet Protection
3611
3611
  protect(password, options) {
3612
- return new Promise((resolve6) => {
3612
+ return new Promise((resolve7) => {
3613
3613
  this.sheetProtection = {
3614
3614
  sheet: true
3615
3615
  };
@@ -3633,7 +3633,7 @@ var require_worksheet = __commonJS({
3633
3633
  delete this.sheetProtection.spinCount;
3634
3634
  }
3635
3635
  }
3636
- resolve6();
3636
+ resolve7();
3637
3637
  });
3638
3638
  }
3639
3639
  unprotect() {
@@ -4353,7 +4353,7 @@ var require_BufferList = __commonJS({
4353
4353
  this.head = this.tail = null;
4354
4354
  this.length = 0;
4355
4355
  };
4356
- BufferList.prototype.join = function join7(s) {
4356
+ BufferList.prototype.join = function join8(s) {
4357
4357
  if (this.length === 0) return "";
4358
4358
  var p = this.head;
4359
4359
  var ret2 = "" + p.data;
@@ -6330,8 +6330,8 @@ var require_lib2 = __commonJS({
6330
6330
  return this;
6331
6331
  }
6332
6332
  var p = this.constructor;
6333
- return this.then(resolve7, reject3);
6334
- function resolve7(value) {
6333
+ return this.then(resolve8, reject3);
6334
+ function resolve8(value) {
6335
6335
  function yes() {
6336
6336
  return value;
6337
6337
  }
@@ -6484,8 +6484,8 @@ var require_lib2 = __commonJS({
6484
6484
  }
6485
6485
  return out;
6486
6486
  }
6487
- Promise2.resolve = resolve6;
6488
- function resolve6(value) {
6487
+ Promise2.resolve = resolve7;
6488
+ function resolve7(value) {
6489
6489
  if (value instanceof this) {
6490
6490
  return value;
6491
6491
  }
@@ -7017,10 +7017,10 @@ var require_utils = __commonJS({
7017
7017
  var promise = external.Promise.resolve(inputData).then(function(data) {
7018
7018
  var isBlob = support.blob && (data instanceof Blob || ["[object File]", "[object Blob]"].indexOf(Object.prototype.toString.call(data)) !== -1);
7019
7019
  if (isBlob && typeof FileReader !== "undefined") {
7020
- return new external.Promise(function(resolve6, reject2) {
7020
+ return new external.Promise(function(resolve7, reject2) {
7021
7021
  var reader = new FileReader();
7022
7022
  reader.onload = function(e) {
7023
- resolve6(e.target.result);
7023
+ resolve7(e.target.result);
7024
7024
  };
7025
7025
  reader.onerror = function(e) {
7026
7026
  reject2(e.target.error);
@@ -7575,7 +7575,7 @@ var require_StreamHelper = __commonJS({
7575
7575
  }
7576
7576
  }
7577
7577
  function accumulate(helper, updateCallback) {
7578
- return new external.Promise(function(resolve6, reject2) {
7578
+ return new external.Promise(function(resolve7, reject2) {
7579
7579
  var dataArray = [];
7580
7580
  var chunkType = helper._internalType, resultType = helper._outputType, mimeType = helper._mimeType;
7581
7581
  helper.on("data", function(data, meta) {
@@ -7589,7 +7589,7 @@ var require_StreamHelper = __commonJS({
7589
7589
  }).on("end", function() {
7590
7590
  try {
7591
7591
  var result = transformZipOutput(resultType, concat2(chunkType, dataArray), mimeType);
7592
- resolve6(result);
7592
+ resolve7(result);
7593
7593
  } catch (e) {
7594
7594
  reject2(e);
7595
7595
  }
@@ -13702,7 +13702,7 @@ var require_load = __commonJS({
13702
13702
  var Crc32Probe = require_Crc32Probe();
13703
13703
  var nodejsUtils = require_nodejsUtils();
13704
13704
  function checkEntryCRC32(zipEntry) {
13705
- return new external.Promise(function(resolve6, reject2) {
13705
+ return new external.Promise(function(resolve7, reject2) {
13706
13706
  var worker = zipEntry.decompressed.getContentWorker().pipe(new Crc32Probe());
13707
13707
  worker.on("error", function(e) {
13708
13708
  reject2(e);
@@ -13710,7 +13710,7 @@ var require_load = __commonJS({
13710
13710
  if (worker.streamInfo.crc32 !== zipEntry.decompressed.crc32) {
13711
13711
  reject2(new Error("Corrupted zip : CRC32 mismatch"));
13712
13712
  } else {
13713
- resolve6();
13713
+ resolve7();
13714
13714
  }
13715
13715
  }).resume();
13716
13716
  });
@@ -13939,7 +13939,7 @@ var require_buffer_list = __commonJS({
13939
13939
  }
13940
13940
  }, {
13941
13941
  key: "join",
13942
- value: function join7(s) {
13942
+ value: function join8(s) {
13943
13943
  if (this.length === 0) return "";
13944
13944
  var p = this.head;
13945
13945
  var ret2 = "" + p.data;
@@ -14967,14 +14967,14 @@ var require_async_iterator = __commonJS({
14967
14967
  };
14968
14968
  }
14969
14969
  function readAndResolve(iter) {
14970
- var resolve6 = iter[kLastResolve];
14971
- if (resolve6 !== null) {
14970
+ var resolve7 = iter[kLastResolve];
14971
+ if (resolve7 !== null) {
14972
14972
  var data = iter[kStream].read();
14973
14973
  if (data !== null) {
14974
14974
  iter[kLastPromise] = null;
14975
14975
  iter[kLastResolve] = null;
14976
14976
  iter[kLastReject] = null;
14977
- resolve6(createIterResult(data, false));
14977
+ resolve7(createIterResult(data, false));
14978
14978
  }
14979
14979
  }
14980
14980
  }
@@ -14982,13 +14982,13 @@ var require_async_iterator = __commonJS({
14982
14982
  process.nextTick(readAndResolve, iter);
14983
14983
  }
14984
14984
  function wrapForNext(lastPromise, iter) {
14985
- return function(resolve6, reject2) {
14985
+ return function(resolve7, reject2) {
14986
14986
  lastPromise.then(function() {
14987
14987
  if (iter[kEnded]) {
14988
- resolve6(createIterResult(void 0, true));
14988
+ resolve7(createIterResult(void 0, true));
14989
14989
  return;
14990
14990
  }
14991
- iter[kHandlePromise](resolve6, reject2);
14991
+ iter[kHandlePromise](resolve7, reject2);
14992
14992
  }, reject2);
14993
14993
  };
14994
14994
  }
@@ -15008,12 +15008,12 @@ var require_async_iterator = __commonJS({
15008
15008
  return Promise.resolve(createIterResult(void 0, true));
15009
15009
  }
15010
15010
  if (this[kStream].destroyed) {
15011
- return new Promise(function(resolve6, reject2) {
15011
+ return new Promise(function(resolve7, reject2) {
15012
15012
  process.nextTick(function() {
15013
15013
  if (_this[kError]) {
15014
15014
  reject2(_this[kError]);
15015
15015
  } else {
15016
- resolve6(createIterResult(void 0, true));
15016
+ resolve7(createIterResult(void 0, true));
15017
15017
  }
15018
15018
  });
15019
15019
  });
@@ -15036,13 +15036,13 @@ var require_async_iterator = __commonJS({
15036
15036
  return this;
15037
15037
  }), _defineProperty2(_Object$setPrototypeO, "return", function _return() {
15038
15038
  var _this2 = this;
15039
- return new Promise(function(resolve6, reject2) {
15039
+ return new Promise(function(resolve7, reject2) {
15040
15040
  _this2[kStream].destroy(null, function(err) {
15041
15041
  if (err) {
15042
15042
  reject2(err);
15043
15043
  return;
15044
15044
  }
15045
- resolve6(createIterResult(void 0, true));
15045
+ resolve7(createIterResult(void 0, true));
15046
15046
  });
15047
15047
  });
15048
15048
  }), _Object$setPrototypeO), AsyncIteratorPrototype);
@@ -15064,15 +15064,15 @@ var require_async_iterator = __commonJS({
15064
15064
  value: stream2._readableState.endEmitted,
15065
15065
  writable: true
15066
15066
  }), _defineProperty2(_Object$create, kHandlePromise, {
15067
- value: function value(resolve6, reject2) {
15067
+ value: function value(resolve7, reject2) {
15068
15068
  var data = iterator[kStream].read();
15069
15069
  if (data) {
15070
15070
  iterator[kLastPromise] = null;
15071
15071
  iterator[kLastResolve] = null;
15072
15072
  iterator[kLastReject] = null;
15073
- resolve6(createIterResult(data, false));
15073
+ resolve7(createIterResult(data, false));
15074
15074
  } else {
15075
- iterator[kLastResolve] = resolve6;
15075
+ iterator[kLastResolve] = resolve7;
15076
15076
  iterator[kLastReject] = reject2;
15077
15077
  }
15078
15078
  },
@@ -15091,12 +15091,12 @@ var require_async_iterator = __commonJS({
15091
15091
  iterator[kError] = err;
15092
15092
  return;
15093
15093
  }
15094
- var resolve6 = iterator[kLastResolve];
15095
- if (resolve6 !== null) {
15094
+ var resolve7 = iterator[kLastResolve];
15095
+ if (resolve7 !== null) {
15096
15096
  iterator[kLastPromise] = null;
15097
15097
  iterator[kLastResolve] = null;
15098
15098
  iterator[kLastReject] = null;
15099
- resolve6(createIterResult(void 0, true));
15099
+ resolve7(createIterResult(void 0, true));
15100
15100
  }
15101
15101
  iterator[kEnded] = true;
15102
15102
  });
@@ -15111,7 +15111,7 @@ var require_async_iterator = __commonJS({
15111
15111
  var require_from = __commonJS({
15112
15112
  "../../node_modules/readable-stream/lib/internal/streams/from.js"(exports2, module2) {
15113
15113
  "use strict";
15114
- function asyncGeneratorStep2(gen, resolve6, reject2, _next, _throw, key2, arg) {
15114
+ function asyncGeneratorStep2(gen, resolve7, reject2, _next, _throw, key2, arg) {
15115
15115
  try {
15116
15116
  var info = gen[key2](arg);
15117
15117
  var value = info.value;
@@ -15120,7 +15120,7 @@ var require_from = __commonJS({
15120
15120
  return;
15121
15121
  }
15122
15122
  if (info.done) {
15123
- resolve6(value);
15123
+ resolve7(value);
15124
15124
  } else {
15125
15125
  Promise.resolve(value).then(_next, _throw);
15126
15126
  }
@@ -15128,13 +15128,13 @@ var require_from = __commonJS({
15128
15128
  function _asyncToGenerator2(fn) {
15129
15129
  return function() {
15130
15130
  var self2 = this, args = arguments;
15131
- return new Promise(function(resolve6, reject2) {
15131
+ return new Promise(function(resolve7, reject2) {
15132
15132
  var gen = fn.apply(self2, args);
15133
15133
  function _next(value) {
15134
- asyncGeneratorStep2(gen, resolve6, reject2, _next, _throw, "next", value);
15134
+ asyncGeneratorStep2(gen, resolve7, reject2, _next, _throw, "next", value);
15135
15135
  }
15136
15136
  function _throw(err) {
15137
- asyncGeneratorStep2(gen, resolve6, reject2, _next, _throw, "throw", err);
15137
+ asyncGeneratorStep2(gen, resolve7, reject2, _next, _throw, "throw", err);
15138
15138
  }
15139
15139
  _next(void 0);
15140
15140
  });
@@ -16223,14 +16223,14 @@ var require_utils2 = __commonJS({
16223
16223
  nop() {
16224
16224
  },
16225
16225
  promiseImmediate(value) {
16226
- return new Promise((resolve6) => {
16226
+ return new Promise((resolve7) => {
16227
16227
  if (global.setImmediate) {
16228
16228
  setImmediate(() => {
16229
- resolve6(value);
16229
+ resolve7(value);
16230
16230
  });
16231
16231
  } else {
16232
16232
  setTimeout(() => {
16233
- resolve6(value);
16233
+ resolve7(value);
16234
16234
  }, 1);
16235
16235
  }
16236
16236
  });
@@ -16330,9 +16330,9 @@ var require_utils2 = __commonJS({
16330
16330
  },
16331
16331
  fs: {
16332
16332
  exists(path) {
16333
- return new Promise((resolve6) => {
16333
+ return new Promise((resolve7) => {
16334
16334
  fs4.access(path, fs4.constants.F_OK, (err) => {
16335
- resolve6(!err);
16335
+ resolve7(!err);
16336
16336
  });
16337
16337
  });
16338
16338
  }
@@ -16557,9 +16557,9 @@ var require_stream_buf = __commonJS({
16557
16557
  },
16558
16558
  async _pipe(chunk) {
16559
16559
  const write2 = function(pipe) {
16560
- return new Promise((resolve6) => {
16560
+ return new Promise((resolve7) => {
16561
16561
  pipe.write(chunk.toBuffer(), () => {
16562
- resolve6();
16562
+ resolve7();
16563
16563
  });
16564
16564
  });
16565
16565
  };
@@ -28569,12 +28569,12 @@ var require_xlsx = __commonJS({
28569
28569
  var VmlNotesXform = require_vml_notes_xform();
28570
28570
  var theme1Xml = require_theme1();
28571
28571
  function fsReadFileAsync(filename, options) {
28572
- return new Promise((resolve6, reject2) => {
28572
+ return new Promise((resolve7, reject2) => {
28573
28573
  fs4.readFile(filename, options, (error, data) => {
28574
28574
  if (error) {
28575
28575
  reject2(error);
28576
28576
  } else {
28577
- resolve6(data);
28577
+ resolve7(data);
28578
28578
  }
28579
28579
  });
28580
28580
  });
@@ -28701,7 +28701,7 @@ var require_xlsx = __commonJS({
28701
28701
  if (lastDot >= 1) {
28702
28702
  const extension = filename.substr(lastDot + 1);
28703
28703
  const name = filename.substr(0, lastDot);
28704
- await new Promise((resolve6, reject2) => {
28704
+ await new Promise((resolve7, reject2) => {
28705
28705
  const streamBuf = new StreamBuf();
28706
28706
  streamBuf.on("finish", () => {
28707
28707
  model.mediaIndex[filename] = model.media.length;
@@ -28713,7 +28713,7 @@ var require_xlsx = __commonJS({
28713
28713
  buffer: streamBuf.toBuffer()
28714
28714
  };
28715
28715
  model.media.push(medium);
28716
- resolve6();
28716
+ resolve7();
28717
28717
  });
28718
28718
  entry.on("error", (error) => {
28719
28719
  reject2(error);
@@ -28738,13 +28738,13 @@ var require_xlsx = __commonJS({
28738
28738
  model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
28739
28739
  }
28740
28740
  async _processThemeEntry(entry, model, name) {
28741
- await new Promise((resolve6, reject2) => {
28741
+ await new Promise((resolve7, reject2) => {
28742
28742
  const stream2 = new StreamBuf();
28743
28743
  entry.on("error", reject2);
28744
28744
  stream2.on("error", reject2);
28745
28745
  stream2.on("finish", () => {
28746
28746
  model.themes[name] = stream2.read().toString();
28747
- resolve6();
28747
+ resolve7();
28748
28748
  });
28749
28749
  entry.pipe(stream2);
28750
28750
  });
@@ -29052,9 +29052,9 @@ var require_xlsx = __commonJS({
29052
29052
  });
29053
29053
  }
29054
29054
  _finalize(zip) {
29055
- return new Promise((resolve6, reject2) => {
29055
+ return new Promise((resolve7, reject2) => {
29056
29056
  zip.on("finish", () => {
29057
- resolve6(this);
29057
+ resolve7(this);
29058
29058
  });
29059
29059
  zip.on("error", reject2);
29060
29060
  zip.finalize();
@@ -29114,9 +29114,9 @@ var require_xlsx = __commonJS({
29114
29114
  }
29115
29115
  writeFile(filename, options) {
29116
29116
  const stream2 = fs4.createWriteStream(filename);
29117
- return new Promise((resolve6, reject2) => {
29117
+ return new Promise((resolve7, reject2) => {
29118
29118
  stream2.on("finish", () => {
29119
- resolve6();
29119
+ resolve7();
29120
29120
  });
29121
29121
  stream2.on("error", (error) => {
29122
29122
  reject2(error);
@@ -33253,7 +33253,7 @@ var require_csv = __commonJS({
33253
33253
  }
33254
33254
  read(stream2, options) {
33255
33255
  options = options || {};
33256
- return new Promise((resolve6, reject2) => {
33256
+ return new Promise((resolve7, reject2) => {
33257
33257
  const worksheet = this.workbook.addWorksheet(options.sheetName);
33258
33258
  const dateFormats = options.dateFormats || [
33259
33259
  "YYYY-MM-DD[T]HH:mm:ssZ",
@@ -33293,7 +33293,7 @@ var require_csv = __commonJS({
33293
33293
  }).on("end", () => {
33294
33294
  csvStream.emit("worksheet", worksheet);
33295
33295
  });
33296
- csvStream.on("worksheet", resolve6).on("error", reject2);
33296
+ csvStream.on("worksheet", resolve7).on("error", reject2);
33297
33297
  stream2.pipe(csvStream);
33298
33298
  });
33299
33299
  }
@@ -33306,12 +33306,12 @@ var require_csv = __commonJS({
33306
33306
  );
33307
33307
  }
33308
33308
  write(stream2, options) {
33309
- return new Promise((resolve6, reject2) => {
33309
+ return new Promise((resolve7, reject2) => {
33310
33310
  options = options || {};
33311
33311
  const worksheet = this.workbook.getWorksheet(options.sheetName || options.sheetId);
33312
33312
  const csvStream = fastCsv.format(options.formatterOptions);
33313
33313
  stream2.on("finish", () => {
33314
- resolve6();
33314
+ resolve7();
33315
33315
  });
33316
33316
  csvStream.on("error", reject2);
33317
33317
  csvStream.pipe(stream2);
@@ -34534,9 +34534,9 @@ var require_readdir_glob = __commonJS({
34534
34534
  var fs4 = __require("fs");
34535
34535
  var { EventEmitter } = __require("events");
34536
34536
  var { Minimatch } = require_minimatch();
34537
- var { resolve: resolve6 } = __require("path");
34537
+ var { resolve: resolve7 } = __require("path");
34538
34538
  function readdir(dir2, strict) {
34539
- return new Promise((resolve7, reject2) => {
34539
+ return new Promise((resolve8, reject2) => {
34540
34540
  fs4.readdir(dir2, { withFileTypes: true }, (err, files) => {
34541
34541
  if (err) {
34542
34542
  switch (err.code) {
@@ -34544,7 +34544,7 @@ var require_readdir_glob = __commonJS({
34544
34544
  if (strict) {
34545
34545
  reject2(err);
34546
34546
  } else {
34547
- resolve7([]);
34547
+ resolve8([]);
34548
34548
  }
34549
34549
  break;
34550
34550
  case "ENOTSUP":
@@ -34554,7 +34554,7 @@ var require_readdir_glob = __commonJS({
34554
34554
  case "ENAMETOOLONG":
34555
34555
  // Filename too long
34556
34556
  case "UNKNOWN":
34557
- resolve7([]);
34557
+ resolve8([]);
34558
34558
  break;
34559
34559
  case "ELOOP":
34560
34560
  // Too many levels of symbolic links
@@ -34563,30 +34563,30 @@ var require_readdir_glob = __commonJS({
34563
34563
  break;
34564
34564
  }
34565
34565
  } else {
34566
- resolve7(files);
34566
+ resolve8(files);
34567
34567
  }
34568
34568
  });
34569
34569
  });
34570
34570
  }
34571
34571
  function stat(file, followSymlinks) {
34572
- return new Promise((resolve7, reject2) => {
34572
+ return new Promise((resolve8, reject2) => {
34573
34573
  const statFunc = followSymlinks ? fs4.stat : fs4.lstat;
34574
34574
  statFunc(file, (err, stats) => {
34575
34575
  if (err) {
34576
34576
  switch (err.code) {
34577
34577
  case "ENOENT":
34578
34578
  if (followSymlinks) {
34579
- resolve7(stat(file, false));
34579
+ resolve8(stat(file, false));
34580
34580
  } else {
34581
- resolve7(null);
34581
+ resolve8(null);
34582
34582
  }
34583
34583
  break;
34584
34584
  default:
34585
- resolve7(null);
34585
+ resolve8(null);
34586
34586
  break;
34587
34587
  }
34588
34588
  } else {
34589
- resolve7(stats);
34589
+ resolve8(stats);
34590
34590
  }
34591
34591
  });
34592
34592
  });
@@ -34600,8 +34600,8 @@ var require_readdir_glob = __commonJS({
34600
34600
  useStat = true;
34601
34601
  }
34602
34602
  const filename = dir2 + "/" + name;
34603
- const relative2 = filename.slice(1);
34604
- const absolute = path + "/" + relative2;
34603
+ const relative3 = filename.slice(1);
34604
+ const absolute = path + "/" + relative3;
34605
34605
  let stats = null;
34606
34606
  if (useStat || followSymlinks) {
34607
34607
  stats = await stat(absolute, followSymlinks);
@@ -34613,12 +34613,12 @@ var require_readdir_glob = __commonJS({
34613
34613
  stats = { isDirectory: () => false };
34614
34614
  }
34615
34615
  if (stats.isDirectory()) {
34616
- if (!shouldSkip(relative2)) {
34617
- yield { relative: relative2, absolute, stats };
34616
+ if (!shouldSkip(relative3)) {
34617
+ yield { relative: relative3, absolute, stats };
34618
34618
  yield* exploreWalkAsync(filename, path, followSymlinks, useStat, shouldSkip, false);
34619
34619
  }
34620
34620
  } else {
34621
- yield { relative: relative2, absolute, stats };
34621
+ yield { relative: relative3, absolute, stats };
34622
34622
  }
34623
34623
  }
34624
34624
  }
@@ -34676,7 +34676,7 @@ var require_readdir_glob = __commonJS({
34676
34676
  (skip) => new Minimatch(skip, { dot: true })
34677
34677
  );
34678
34678
  }
34679
- this.iterator = explore(resolve6(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
34679
+ this.iterator = explore(resolve7(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
34680
34680
  this.paused = false;
34681
34681
  this.inactive = false;
34682
34682
  this.aborted = false;
@@ -34688,11 +34688,11 @@ var require_readdir_glob = __commonJS({
34688
34688
  }
34689
34689
  setTimeout(() => this._next(), 0);
34690
34690
  }
34691
- _shouldSkipDirectory(relative2) {
34692
- return this.skipMatchers.some((m) => m.match(relative2));
34691
+ _shouldSkipDirectory(relative3) {
34692
+ return this.skipMatchers.some((m) => m.match(relative3));
34693
34693
  }
34694
- _fileMatches(relative2, isDirectory) {
34695
- const file = relative2 + (isDirectory ? "/" : "");
34694
+ _fileMatches(relative3, isDirectory) {
34695
+ const file = relative3 + (isDirectory ? "/" : "");
34696
34696
  return (this.matchers.length === 0 || this.matchers.some((m) => m.match(file))) && !this.ignoreMatchers.some((m) => m.match(file)) && (!this.options.nodir || !isDirectory);
34697
34697
  }
34698
34698
  _next() {
@@ -34701,16 +34701,16 @@ var require_readdir_glob = __commonJS({
34701
34701
  if (!obj2.done) {
34702
34702
  const isDirectory = obj2.value.stats.isDirectory();
34703
34703
  if (this._fileMatches(obj2.value.relative, isDirectory)) {
34704
- let relative2 = obj2.value.relative;
34704
+ let relative3 = obj2.value.relative;
34705
34705
  let absolute = obj2.value.absolute;
34706
34706
  if (this.options.mark && isDirectory) {
34707
- relative2 += "/";
34707
+ relative3 += "/";
34708
34708
  absolute += "/";
34709
34709
  }
34710
34710
  if (this.options.stat) {
34711
- this.emit("match", { relative: relative2, absolute, stat: obj2.value.stats });
34711
+ this.emit("match", { relative: relative3, absolute, stat: obj2.value.stats });
34712
34712
  } else {
34713
- this.emit("match", { relative: relative2, absolute });
34713
+ this.emit("match", { relative: relative3, absolute });
34714
34714
  }
34715
34715
  }
34716
34716
  this._next(this.iterator);
@@ -34930,10 +34930,10 @@ function awaitify(asyncFn, arity) {
34930
34930
  if (typeof args[arity - 1] === "function") {
34931
34931
  return asyncFn.apply(this, args);
34932
34932
  }
34933
- return new Promise((resolve6, reject2) => {
34933
+ return new Promise((resolve7, reject2) => {
34934
34934
  args[arity - 1] = (err, ...cbArgs) => {
34935
34935
  if (err) return reject2(err);
34936
- resolve6(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
34936
+ resolve7(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
34937
34937
  };
34938
34938
  asyncFn.apply(this, args);
34939
34939
  });
@@ -35115,13 +35115,13 @@ function mapSeries(coll, iteratee, callback) {
35115
35115
  return _asyncMap(eachOfSeries$1, coll, iteratee, callback);
35116
35116
  }
35117
35117
  function promiseCallback() {
35118
- let resolve6, reject2;
35118
+ let resolve7, reject2;
35119
35119
  function callback(err, ...args) {
35120
35120
  if (err) return reject2(err);
35121
- resolve6(args.length > 1 ? args : args[0]);
35121
+ resolve7(args.length > 1 ? args : args[0]);
35122
35122
  }
35123
35123
  callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
35124
- resolve6 = res, reject2 = rej;
35124
+ resolve7 = res, reject2 = rej;
35125
35125
  });
35126
35126
  return callback;
35127
35127
  }
@@ -35394,8 +35394,8 @@ function queue$1(worker, concurrency, payload) {
35394
35394
  });
35395
35395
  }
35396
35396
  if (rejectOnError || !callback) {
35397
- return new Promise((resolve6, reject2) => {
35398
- res = resolve6;
35397
+ return new Promise((resolve7, reject2) => {
35398
+ res = resolve7;
35399
35399
  rej = reject2;
35400
35400
  });
35401
35401
  }
@@ -35434,10 +35434,10 @@ function queue$1(worker, concurrency, payload) {
35434
35434
  }
35435
35435
  const eventMethod = (name) => (handler) => {
35436
35436
  if (!handler) {
35437
- return new Promise((resolve6, reject2) => {
35437
+ return new Promise((resolve7, reject2) => {
35438
35438
  once2(name, (err, data) => {
35439
35439
  if (err) return reject2(err);
35440
- resolve6(data);
35440
+ resolve7(data);
35441
35441
  });
35442
35442
  });
35443
35443
  }
@@ -37440,7 +37440,7 @@ var require_BufferList2 = __commonJS({
37440
37440
  this.head = this.tail = null;
37441
37441
  this.length = 0;
37442
37442
  };
37443
- BufferList.prototype.join = function join7(s) {
37443
+ BufferList.prototype.join = function join8(s) {
37444
37444
  if (this.length === 0) return "";
37445
37445
  var p = this.head;
37446
37446
  var ret2 = "" + p.data;
@@ -39205,7 +39205,7 @@ var require_BufferList3 = __commonJS({
39205
39205
  this.head = this.tail = null;
39206
39206
  this.length = 0;
39207
39207
  };
39208
- BufferList.prototype.join = function join7(s) {
39208
+ BufferList.prototype.join = function join8(s) {
39209
39209
  if (this.length === 0) return "";
39210
39210
  var p = this.head;
39211
39211
  var ret2 = "" + p.data;
@@ -41624,7 +41624,7 @@ var require_old = __commonJS({
41624
41624
  function maybeCallback(cb) {
41625
41625
  return typeof cb === "function" ? cb : rethrow();
41626
41626
  }
41627
- var normalize2 = pathModule.normalize;
41627
+ var normalize3 = pathModule.normalize;
41628
41628
  if (isWindows) {
41629
41629
  nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
41630
41630
  } else {
@@ -42813,7 +42813,7 @@ var require_common2 = __commonJS({
42813
42813
  var fs4 = __require("fs");
42814
42814
  var path = __require("path");
42815
42815
  var minimatch = require_minimatch2();
42816
- var isAbsolute3 = require_path_is_absolute();
42816
+ var isAbsolute4 = require_path_is_absolute();
42817
42817
  var Minimatch = minimatch.Minimatch;
42818
42818
  function alphasort(a, b) {
42819
42819
  return a.localeCompare(b, "en");
@@ -42883,7 +42883,7 @@ var require_common2 = __commonJS({
42883
42883
  self2.root = path.resolve(self2.root);
42884
42884
  if (process.platform === "win32")
42885
42885
  self2.root = self2.root.replace(/\\/g, "/");
42886
- self2.cwdAbs = isAbsolute3(self2.cwd) ? self2.cwd : makeAbs(self2, self2.cwd);
42886
+ self2.cwdAbs = isAbsolute4(self2.cwd) ? self2.cwd : makeAbs(self2, self2.cwd);
42887
42887
  if (process.platform === "win32")
42888
42888
  self2.cwdAbs = self2.cwdAbs.replace(/\\/g, "/");
42889
42889
  self2.nomount = !!options.nomount;
@@ -42963,7 +42963,7 @@ var require_common2 = __commonJS({
42963
42963
  var abs = f;
42964
42964
  if (f.charAt(0) === "/") {
42965
42965
  abs = path.join(self2.root, f);
42966
- } else if (isAbsolute3(f) || f === "") {
42966
+ } else if (isAbsolute4(f) || f === "") {
42967
42967
  abs = f;
42968
42968
  } else if (self2.changedCwd) {
42969
42969
  abs = path.resolve(self2.cwd, f);
@@ -43004,7 +43004,7 @@ var require_sync = __commonJS({
43004
43004
  var util2 = __require("util");
43005
43005
  var path = __require("path");
43006
43006
  var assert = __require("assert");
43007
- var isAbsolute3 = require_path_is_absolute();
43007
+ var isAbsolute4 = require_path_is_absolute();
43008
43008
  var common = require_common2();
43009
43009
  var setopts = common.setopts;
43010
43010
  var ownProp = common.ownProp;
@@ -43077,10 +43077,10 @@ var require_sync = __commonJS({
43077
43077
  var read2;
43078
43078
  if (prefix === null)
43079
43079
  read2 = ".";
43080
- else if (isAbsolute3(prefix) || isAbsolute3(pattern2.map(function(p) {
43080
+ else if (isAbsolute4(prefix) || isAbsolute4(pattern2.map(function(p) {
43081
43081
  return typeof p === "string" ? p : "[*]";
43082
43082
  }).join("/"))) {
43083
- if (!prefix || !isAbsolute3(prefix))
43083
+ if (!prefix || !isAbsolute4(prefix))
43084
43084
  prefix = "/" + prefix;
43085
43085
  read2 = prefix;
43086
43086
  } else
@@ -43279,7 +43279,7 @@ var require_sync = __commonJS({
43279
43279
  this.matches[index2] = /* @__PURE__ */ Object.create(null);
43280
43280
  if (!exists)
43281
43281
  return;
43282
- if (prefix && isAbsolute3(prefix) && !this.nomount) {
43282
+ if (prefix && isAbsolute4(prefix) && !this.nomount) {
43283
43283
  var trail = /[\/\\]$/.test(prefix);
43284
43284
  if (prefix.charAt(0) === "/") {
43285
43285
  prefix = path.join(this.root, prefix);
@@ -43482,7 +43482,7 @@ var require_glob = __commonJS({
43482
43482
  var EE = __require("events").EventEmitter;
43483
43483
  var path = __require("path");
43484
43484
  var assert = __require("assert");
43485
- var isAbsolute3 = require_path_is_absolute();
43485
+ var isAbsolute4 = require_path_is_absolute();
43486
43486
  var globSync = require_sync();
43487
43487
  var common = require_common2();
43488
43488
  var setopts = common.setopts;
@@ -43703,10 +43703,10 @@ var require_glob = __commonJS({
43703
43703
  var read2;
43704
43704
  if (prefix === null)
43705
43705
  read2 = ".";
43706
- else if (isAbsolute3(prefix) || isAbsolute3(pattern2.map(function(p) {
43706
+ else if (isAbsolute4(prefix) || isAbsolute4(pattern2.map(function(p) {
43707
43707
  return typeof p === "string" ? p : "[*]";
43708
43708
  }).join("/"))) {
43709
- if (!prefix || !isAbsolute3(prefix))
43709
+ if (!prefix || !isAbsolute4(prefix))
43710
43710
  prefix = "/" + prefix;
43711
43711
  read2 = prefix;
43712
43712
  } else
@@ -43791,7 +43791,7 @@ var require_glob = __commonJS({
43791
43791
  this._emitQueue.push([index2, e]);
43792
43792
  return;
43793
43793
  }
43794
- var abs = isAbsolute3(e) ? e : this._makeAbs(e);
43794
+ var abs = isAbsolute4(e) ? e : this._makeAbs(e);
43795
43795
  if (this.mark)
43796
43796
  e = this._mark(e);
43797
43797
  if (this.absolute)
@@ -43948,7 +43948,7 @@ var require_glob = __commonJS({
43948
43948
  this.matches[index2] = /* @__PURE__ */ Object.create(null);
43949
43949
  if (!exists)
43950
43950
  return cb();
43951
- if (prefix && isAbsolute3(prefix) && !this.nomount) {
43951
+ if (prefix && isAbsolute4(prefix) && !this.nomount) {
43952
43952
  var trail = /[\/\\]$/.test(prefix);
43953
43953
  if (prefix.charAt(0) === "/") {
43954
43954
  prefix = path.join(this.root, prefix);
@@ -44793,11 +44793,11 @@ var require_core = __commonJS({
44793
44793
  this._finalize();
44794
44794
  }
44795
44795
  var self2 = this;
44796
- return new Promise(function(resolve6, reject2) {
44796
+ return new Promise(function(resolve7, reject2) {
44797
44797
  var errored;
44798
44798
  self2._module.on("end", function() {
44799
44799
  if (!errored) {
44800
- resolve6();
44800
+ resolve7();
44801
44801
  }
44802
44802
  });
44803
44803
  self2._module.on("error", function(err) {
@@ -48568,7 +48568,7 @@ var require_worksheet_writer = __commonJS({
48568
48568
  // =========================================================================
48569
48569
  // Worksheet Protection
48570
48570
  protect(password, options) {
48571
- return new Promise((resolve6) => {
48571
+ return new Promise((resolve7) => {
48572
48572
  this.sheetProtection = {
48573
48573
  sheet: true
48574
48574
  };
@@ -48592,7 +48592,7 @@ var require_worksheet_writer = __commonJS({
48592
48592
  delete this.sheetProtection.spinCount;
48593
48593
  }
48594
48594
  }
48595
- resolve6();
48595
+ resolve7();
48596
48596
  });
48597
48597
  }
48598
48598
  unprotect() {
@@ -48811,9 +48811,9 @@ var require_workbook_writer = __commonJS({
48811
48811
  _commitWorksheets() {
48812
48812
  const commitWorksheet = function(worksheet) {
48813
48813
  if (!worksheet.committed) {
48814
- return new Promise((resolve6) => {
48814
+ return new Promise((resolve7) => {
48815
48815
  worksheet.stream.on("zipped", () => {
48816
- resolve6();
48816
+ resolve7();
48817
48817
  });
48818
48818
  worksheet.commit();
48819
48819
  });
@@ -48901,19 +48901,19 @@ var require_workbook_writer = __commonJS({
48901
48901
  return void 0;
48902
48902
  }
48903
48903
  addStyles() {
48904
- return new Promise((resolve6) => {
48904
+ return new Promise((resolve7) => {
48905
48905
  this.zip.append(this.styles.xml, { name: "xl/styles.xml" });
48906
- resolve6();
48906
+ resolve7();
48907
48907
  });
48908
48908
  }
48909
48909
  addThemes() {
48910
- return new Promise((resolve6) => {
48910
+ return new Promise((resolve7) => {
48911
48911
  this.zip.append(theme1Xml, { name: "xl/theme/theme1.xml" });
48912
- resolve6();
48912
+ resolve7();
48913
48913
  });
48914
48914
  }
48915
48915
  addOfficeRels() {
48916
- return new Promise((resolve6) => {
48916
+ return new Promise((resolve7) => {
48917
48917
  const xform = new RelationshipsXform();
48918
48918
  const xml = xform.toXml([
48919
48919
  { Id: "rId1", Type: RelType.OfficeDocument, Target: "xl/workbook.xml" },
@@ -48921,11 +48921,11 @@ var require_workbook_writer = __commonJS({
48921
48921
  { Id: "rId3", Type: RelType.ExtenderProperties, Target: "docProps/app.xml" }
48922
48922
  ]);
48923
48923
  this.zip.append(xml, { name: "/_rels/.rels" });
48924
- resolve6();
48924
+ resolve7();
48925
48925
  });
48926
48926
  }
48927
48927
  addContentTypes() {
48928
- return new Promise((resolve6) => {
48928
+ return new Promise((resolve7) => {
48929
48929
  const model = {
48930
48930
  worksheets: this._worksheets.filter(Boolean),
48931
48931
  sharedStrings: this.sharedStrings,
@@ -48935,7 +48935,7 @@ var require_workbook_writer = __commonJS({
48935
48935
  const xform = new ContentTypesXform();
48936
48936
  const xml = xform.toXml(model);
48937
48937
  this.zip.append(xml, { name: "[Content_Types].xml" });
48938
- resolve6();
48938
+ resolve7();
48939
48939
  });
48940
48940
  }
48941
48941
  addMedia() {
@@ -48960,31 +48960,31 @@ var require_workbook_writer = __commonJS({
48960
48960
  );
48961
48961
  }
48962
48962
  addApp() {
48963
- return new Promise((resolve6) => {
48963
+ return new Promise((resolve7) => {
48964
48964
  const model = {
48965
48965
  worksheets: this._worksheets.filter(Boolean)
48966
48966
  };
48967
48967
  const xform = new AppXform();
48968
48968
  const xml = xform.toXml(model);
48969
48969
  this.zip.append(xml, { name: "docProps/app.xml" });
48970
- resolve6();
48970
+ resolve7();
48971
48971
  });
48972
48972
  }
48973
48973
  addCore() {
48974
- return new Promise((resolve6) => {
48974
+ return new Promise((resolve7) => {
48975
48975
  const coreXform = new CoreXform();
48976
48976
  const xml = coreXform.toXml(this);
48977
48977
  this.zip.append(xml, { name: "docProps/core.xml" });
48978
- resolve6();
48978
+ resolve7();
48979
48979
  });
48980
48980
  }
48981
48981
  addSharedStrings() {
48982
48982
  if (this.sharedStrings.count) {
48983
- return new Promise((resolve6) => {
48983
+ return new Promise((resolve7) => {
48984
48984
  const sharedStringsXform = new SharedStringsXform();
48985
48985
  const xml = sharedStringsXform.toXml(this.sharedStrings);
48986
48986
  this.zip.append(xml, { name: "/xl/sharedStrings.xml" });
48987
- resolve6();
48987
+ resolve7();
48988
48988
  });
48989
48989
  }
48990
48990
  return Promise.resolve();
@@ -49012,11 +49012,11 @@ var require_workbook_writer = __commonJS({
49012
49012
  });
49013
49013
  }
49014
49014
  });
49015
- return new Promise((resolve6) => {
49015
+ return new Promise((resolve7) => {
49016
49016
  const xform = new RelationshipsXform();
49017
49017
  const xml = xform.toXml(relationships);
49018
49018
  this.zip.append(xml, { name: "/xl/_rels/workbook.xml.rels" });
49019
- resolve6();
49019
+ resolve7();
49020
49020
  });
49021
49021
  }
49022
49022
  addWorkbook() {
@@ -49028,18 +49028,18 @@ var require_workbook_writer = __commonJS({
49028
49028
  properties: {},
49029
49029
  calcProperties: {}
49030
49030
  };
49031
- return new Promise((resolve6) => {
49031
+ return new Promise((resolve7) => {
49032
49032
  const xform = new WorkbookXform();
49033
49033
  xform.prepare(model);
49034
49034
  zip.append(xform.toXml(model), { name: "/xl/workbook.xml" });
49035
- resolve6();
49035
+ resolve7();
49036
49036
  });
49037
49037
  }
49038
49038
  _finalize() {
49039
- return new Promise((resolve6, reject2) => {
49039
+ return new Promise((resolve7, reject2) => {
49040
49040
  this.stream.on("error", reject2);
49041
49041
  this.stream.on("finish", () => {
49042
- resolve6(this);
49042
+ resolve7(this);
49043
49043
  });
49044
49044
  this.zip.on("error", reject2);
49045
49045
  this.zip.finalize();
@@ -50973,13 +50973,13 @@ var require_thenables = __commonJS({
50973
50973
  promise._captureStackTrace();
50974
50974
  if (context) context._popContext();
50975
50975
  var synchronous = true;
50976
- var result = util2.tryCatch(then).call(x, resolve6, reject2);
50976
+ var result = util2.tryCatch(then).call(x, resolve7, reject2);
50977
50977
  synchronous = false;
50978
50978
  if (promise && result === errorObj2) {
50979
50979
  promise._rejectCallback(result.e, true, true);
50980
50980
  promise = null;
50981
50981
  }
50982
- function resolve6(value) {
50982
+ function resolve7(value) {
50983
50983
  if (!promise) return;
50984
50984
  promise._resolveCallback(value);
50985
50985
  promise = null;
@@ -51514,9 +51514,9 @@ var require_debuggability = __commonJS({
51514
51514
  return false;
51515
51515
  }
51516
51516
  Promise2.prototype._fireEvent = defaultFireEvent;
51517
- Promise2.prototype._execute = function(executor, resolve6, reject2) {
51517
+ Promise2.prototype._execute = function(executor, resolve7, reject2) {
51518
51518
  try {
51519
- executor(resolve6, reject2);
51519
+ executor(resolve7, reject2);
51520
51520
  } catch (e) {
51521
51521
  return e;
51522
51522
  }
@@ -51539,10 +51539,10 @@ var require_debuggability = __commonJS({
51539
51539
  ;
51540
51540
  ;
51541
51541
  };
51542
- function cancellationExecute(executor, resolve6, reject2) {
51542
+ function cancellationExecute(executor, resolve7, reject2) {
51543
51543
  var promise = this;
51544
51544
  try {
51545
- executor(resolve6, reject2, function(onCancel) {
51545
+ executor(resolve7, reject2, function(onCancel) {
51546
51546
  if (typeof onCancel !== "function") {
51547
51547
  throw new TypeError("onCancel must be a function, got: " + util2.toString(onCancel));
51548
51548
  }
@@ -55249,7 +55249,7 @@ var require_BufferList5 = __commonJS({
55249
55249
  this.head = this.tail = null;
55250
55250
  this.length = 0;
55251
55251
  };
55252
- BufferList.prototype.join = function join7(s) {
55252
+ BufferList.prototype.join = function join8(s) {
55253
55253
  if (this.length === 0) return "";
55254
55254
  var p = this.head;
55255
55255
  var ret2 = "" + p.data;
@@ -56796,7 +56796,7 @@ var require_PullStream = __commonJS({
56796
56796
  };
56797
56797
  var rejectHandler;
56798
56798
  var pullStreamRejectHandler;
56799
- return new Promise2(function(resolve6, reject2) {
56799
+ return new Promise2(function(resolve7, reject2) {
56800
56800
  rejectHandler = reject2;
56801
56801
  pullStreamRejectHandler = function(e) {
56802
56802
  self2.__emittedError = e;
@@ -56806,7 +56806,7 @@ var require_PullStream = __commonJS({
56806
56806
  return reject2(new Error("FILE_ENDED"));
56807
56807
  self2.once("error", pullStreamRejectHandler);
56808
56808
  self2.stream(eof, includeEof).on("error", reject2).pipe(concatStream).on("finish", function() {
56809
- resolve6(buffer2);
56809
+ resolve7(buffer2);
56810
56810
  }).on("error", reject2);
56811
56811
  }).finally(function() {
56812
56812
  self2.removeListener("error", rejectHandler);
@@ -56851,10 +56851,10 @@ var require_BufferStream = __commonJS({
56851
56851
  if (!Stream.Writable || !Stream.Writable.prototype.destroy)
56852
56852
  Stream = require_readable5();
56853
56853
  module2.exports = function(entry) {
56854
- return new Promise2(function(resolve6, reject2) {
56854
+ return new Promise2(function(resolve7, reject2) {
56855
56855
  var chunks = [];
56856
56856
  var bufferStream = Stream.Transform().on("finish", function() {
56857
- resolve6(Buffer2.concat(chunks));
56857
+ resolve7(Buffer2.concat(chunks));
56858
56858
  }).on("error", reject2);
56859
56859
  bufferStream._transform = function(d, e, cb) {
56860
56860
  chunks.push(d);
@@ -56996,8 +56996,8 @@ var require_parse = __commonJS({
56996
56996
  __autodraining = true;
56997
56997
  var draining2 = entry.pipe(NoopStream());
56998
56998
  draining2.promise = function() {
56999
- return new Promise2(function(resolve6, reject2) {
57000
- draining2.on("finish", resolve6);
56999
+ return new Promise2(function(resolve7, reject2) {
57000
+ draining2.on("finish", resolve7);
57001
57001
  draining2.on("error", reject2);
57002
57002
  });
57003
57003
  };
@@ -57052,11 +57052,11 @@ var require_parse = __commonJS({
57052
57052
  eof = Buffer2.alloc(4);
57053
57053
  eof.writeUInt32LE(134695760, 0);
57054
57054
  }
57055
- return new Promise2(function(resolve6, reject2) {
57055
+ return new Promise2(function(resolve7, reject2) {
57056
57056
  self2.stream(eof).pipe(inflater).on("error", function(err) {
57057
57057
  self2.emit("error", err);
57058
57058
  }).pipe(entry).on("finish", function() {
57059
- return fileSizeKnown ? self2._readRecord().then(resolve6).catch(reject2) : self2._processDataDescriptor(entry).then(resolve6).catch(reject2);
57059
+ return fileSizeKnown ? self2._readRecord().then(resolve7).catch(reject2) : self2._processDataDescriptor(entry).then(resolve7).catch(reject2);
57060
57060
  });
57061
57061
  });
57062
57062
  });
@@ -57098,8 +57098,8 @@ var require_parse = __commonJS({
57098
57098
  };
57099
57099
  Parse.prototype.promise = function() {
57100
57100
  var self2 = this;
57101
- return new Promise2(function(resolve6, reject2) {
57102
- self2.on("finish", resolve6);
57101
+ return new Promise2(function(resolve7, reject2) {
57102
+ self2.on("finish", resolve7);
57103
57103
  self2.on("error", reject2);
57104
57104
  });
57105
57105
  };
@@ -57161,7 +57161,7 @@ var require_BufferList6 = __commonJS({
57161
57161
  this.head = this.tail = null;
57162
57162
  this.length = 0;
57163
57163
  };
57164
- BufferList.prototype.join = function join7(s) {
57164
+ BufferList.prototype.join = function join8(s) {
57165
57165
  if (this.length === 0) return "";
57166
57166
  var p = this.head;
57167
57167
  var ret2 = "" + p.data;
@@ -60610,8 +60610,8 @@ var require_extract2 = __commonJS({
60610
60610
  extract.emit("close");
60611
60611
  });
60612
60612
  extract.promise = function() {
60613
- return new Promise2(function(resolve6, reject2) {
60614
- extract.on("close", resolve6);
60613
+ return new Promise2(function(resolve7, reject2) {
60614
+ extract.on("close", resolve7);
60615
60615
  extract.on("error", reject2);
60616
60616
  });
60617
60617
  };
@@ -62122,8 +62122,8 @@ var require_directory = __commonJS({
62122
62122
  return;
62123
62123
  }
62124
62124
  var writer = opts.getWriter ? opts.getWriter({ path: extractPath }) : Writer({ path: extractPath });
62125
- return new Promise2(function(resolve6, reject2) {
62126
- entry.stream(opts.password).on("error", reject2).pipe(writer).on("close", resolve6).on("error", reject2);
62125
+ return new Promise2(function(resolve7, reject2) {
62126
+ entry.stream(opts.password).on("error", reject2).pipe(writer).on("close", resolve7).on("error", reject2);
62127
62127
  });
62128
62128
  }, { concurrency: opts.concurrency > 1 ? opts.concurrency : 1 });
62129
62129
  });
@@ -62190,12 +62190,12 @@ var require_Open = __commonJS({
62190
62190
  return fs4.createReadStream(filename, { start: offset, end: length && offset + length });
62191
62191
  },
62192
62192
  size: function() {
62193
- return new Promise2(function(resolve6, reject2) {
62193
+ return new Promise2(function(resolve7, reject2) {
62194
62194
  fs4.stat(filename, function(err, d) {
62195
62195
  if (err)
62196
62196
  reject2(err);
62197
62197
  else
62198
- resolve6(d.size);
62198
+ resolve7(d.size);
62199
62199
  });
62200
62200
  });
62201
62201
  }
@@ -62216,14 +62216,14 @@ var require_Open = __commonJS({
62216
62216
  return request(options2);
62217
62217
  },
62218
62218
  size: function() {
62219
- return new Promise2(function(resolve6, reject2) {
62219
+ return new Promise2(function(resolve7, reject2) {
62220
62220
  var req = request(params);
62221
62221
  req.on("response", function(d) {
62222
62222
  req.abort();
62223
62223
  if (!d.headers["content-length"])
62224
62224
  reject2(new Error("Missing content length header"));
62225
62225
  else
62226
- resolve6(d.headers["content-length"]);
62226
+ resolve7(d.headers["content-length"]);
62227
62227
  }).on("error", reject2);
62228
62228
  });
62229
62229
  }
@@ -62233,12 +62233,12 @@ var require_Open = __commonJS({
62233
62233
  s3: function(client, params, options) {
62234
62234
  var source2 = {
62235
62235
  size: function() {
62236
- return new Promise2(function(resolve6, reject2) {
62236
+ return new Promise2(function(resolve7, reject2) {
62237
62237
  client.headObject(params, function(err, d) {
62238
62238
  if (err)
62239
62239
  reject2(err);
62240
62240
  else
62241
- resolve6(d.ContentLength);
62241
+ resolve7(d.ContentLength);
62242
62242
  });
62243
62243
  });
62244
62244
  },
@@ -62656,7 +62656,7 @@ var require_iterate_stream = __commonJS({
62656
62656
  const contents = [];
62657
62657
  stream2.on("data", (data) => contents.push(data));
62658
62658
  let resolveStreamEndedPromise;
62659
- const streamEndedPromise = new Promise((resolve6) => resolveStreamEndedPromise = resolve6);
62659
+ const streamEndedPromise = new Promise((resolve7) => resolveStreamEndedPromise = resolve7);
62660
62660
  let ended = false;
62661
62661
  stream2.on("end", () => {
62662
62662
  ended = true;
@@ -62681,13 +62681,13 @@ var require_iterate_stream = __commonJS({
62681
62681
  resolveStreamEndedPromise();
62682
62682
  };
62683
62683
  function once2(eventEmitter, type) {
62684
- return new Promise((resolve6) => {
62684
+ return new Promise((resolve7) => {
62685
62685
  let fired = false;
62686
62686
  const handler = () => {
62687
62687
  if (!fired) {
62688
62688
  fired = true;
62689
62689
  eventEmitter.removeListener(type, handler);
62690
- resolve6();
62690
+ resolve7();
62691
62691
  }
62692
62692
  };
62693
62693
  eventEmitter.addListener(type, handler);
@@ -63214,7 +63214,7 @@ var require_workbook_reader = __commonJS({
63214
63214
  if (this.sharedStrings && this.workbookRels) {
63215
63215
  yield* this._parseWorksheet(iterateStream(entry), sheetNo);
63216
63216
  } else {
63217
- await new Promise((resolve6, reject2) => {
63217
+ await new Promise((resolve7, reject2) => {
63218
63218
  tmp.file((err, path, fd, tempFileCleanupCallback) => {
63219
63219
  if (err) {
63220
63220
  return reject2(err);
@@ -63224,7 +63224,7 @@ var require_workbook_reader = __commonJS({
63224
63224
  tempStream.on("error", reject2);
63225
63225
  entry.pipe(tempStream);
63226
63226
  return tempStream.on("finish", () => {
63227
- return resolve6();
63227
+ return resolve7();
63228
63228
  });
63229
63229
  });
63230
63230
  });
@@ -64603,9 +64603,9 @@ var require_clone2 = __commonJS({
64603
64603
  } else if (_instanceof(parent3, nativeSet)) {
64604
64604
  child = new nativeSet();
64605
64605
  } else if (_instanceof(parent3, nativePromise)) {
64606
- child = new nativePromise(function(resolve6, reject2) {
64606
+ child = new nativePromise(function(resolve7, reject2) {
64607
64607
  parent3.then(function(value) {
64608
- resolve6(_clone(value, depth2 - 1));
64608
+ resolve7(_clone(value, depth2 - 1));
64609
64609
  }, function(err) {
64610
64610
  reject2(_clone(err, depth2 - 1));
64611
64611
  });
@@ -190984,126 +190984,6 @@ var init_script_fonts = __esm({
190984
190984
  import { readFileSync as readFileSync7, existsSync as existsSync5 } from "fs";
190985
190985
  import { spawnSync as spawnSync2 } from "child_process";
190986
190986
 
190987
- // ../core/src/ids.ts
190988
- var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
190989
- function newId(prefix = "", length = 8) {
190990
- const limit = 256 - 256 % ALPHABET.length;
190991
- let token2 = "";
190992
- while (token2.length < length) {
190993
- const bytes = new Uint8Array(length * 2);
190994
- globalThis.crypto.getRandomValues(bytes);
190995
- for (const b of bytes) {
190996
- if (b >= limit) continue;
190997
- token2 += ALPHABET[b % ALPHABET.length];
190998
- if (token2.length === length) break;
190999
- }
191000
- }
191001
- return prefix ? `${prefix}_${token2}` : token2;
191002
- }
191003
-
191004
- // ../core/src/handle.ts
191005
- function slug(name) {
191006
- const s = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
191007
- return s || "_";
191008
- }
191009
- function fnv32(input) {
191010
- let h = 2166136261;
191011
- for (let i = 0; i < input.length; i++) {
191012
- h ^= input.charCodeAt(i);
191013
- h = Math.imul(h, 16777619);
191014
- }
191015
- return h >>> 0;
191016
- }
191017
- function hash32(input) {
191018
- return fnv32(input).toString(36).padStart(7, "0");
191019
- }
191020
-
191021
- // ../model/src/index.ts
191022
- function walkNodes(nodes, visit) {
191023
- for (const node of nodes) {
191024
- visit(node);
191025
- const children = node.children;
191026
- if (children) walkNodes(children, visit);
191027
- }
191028
- }
191029
- function isContentlessBeat(beat, hasText) {
191030
- if (beat.kind === "gameEvent") return false;
191031
- if (hasText) return false;
191032
- if (beat.gameData && Object.keys(beat.gameData).length > 0) return false;
191033
- if (beat.tags && beat.tags.length > 0) return false;
191034
- return beat.kind === "text" || !beat.character && !beat.direction;
191035
- }
191036
- function gameIdify(text) {
191037
- return text.toLowerCase().replace(/['’]/g, "").replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
191038
- }
191039
- function isValidGameId(gameId) {
191040
- return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(gameId);
191041
- }
191042
- var RESERVED_PROPERTY_NAMES = ["true", "false", "and", "or", "not"];
191043
- function propertyNameify(text) {
191044
- const trimmed = text.trim();
191045
- const deliberateLeading = trimmed.startsWith("_");
191046
- let out = trimmed.toLowerCase().replace(/['\u2019]/g, "").replace(/[^a-z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
191047
- if (out === "") return "";
191048
- if (deliberateLeading || /^[0-9]/.test(out)) out = `_${out}`;
191049
- if (RESERVED_PROPERTY_NAMES.includes(out)) out = `${out}_`;
191050
- return out;
191051
- }
191052
- function isValidPropertyName(name) {
191053
- return /^[a-z_][a-z0-9_]*$/.test(name) && !RESERVED_PROPERTY_NAMES.includes(name);
191054
- }
191055
- function isCaseOnlyPropertyName(name) {
191056
- return !isValidPropertyName(name) && isValidPropertyName(name.toLowerCase());
191057
- }
191058
- function effectiveGameId(entity) {
191059
- const g = entity.gameId?.trim();
191060
- return g ? g : gameIdify(entity.name);
191061
- }
191062
- var DEFAULT_WRITING_STATUSES = [
191063
- { name: "stub", colour: 0 },
191064
- // red
191065
- { name: "draft 1", colour: 1 },
191066
- // rust
191067
- { name: "draft 2", colour: 2 },
191068
- // ochre
191069
- { name: "edited", readyToRecord: true, colour: 4 },
191070
- // green
191071
- { name: "final", readyToShip: true, colour: 9 }
191072
- // purple (violet)
191073
- ];
191074
- var DEFAULT_RECORDING_STATUSES = [
191075
- { name: "missing", colour: 0 },
191076
- // red
191077
- { name: "scratch", colour: 2 },
191078
- // ochre
191079
- { name: "recorded", colour: 4 },
191080
- // green
191081
- { name: "final", colour: 9 }
191082
- // purple
191083
- ];
191084
- var RERECORD_STATUS = "rerecord";
191085
- function deriveRecordingFolders(audioRoot, statuses) {
191086
- const root2 = audioRoot?.trim();
191087
- return statuses.map((s, i) => {
191088
- if (i === 0 || !root2) return { name: s.name };
191089
- return { name: s.name, folder: `${root2}/${gameIdify(s.name)}` };
191090
- });
191091
- }
191092
- var DEFAULT_DOCUMENTATION_CLASSES = [
191093
- { name: "everyone", deliver: "*" },
191094
- // every export, and (like all) the editor
191095
- { name: "vo", deliver: ["vo"] },
191096
- // voice-recording scripts
191097
- { name: "loc", deliver: ["loc"] }
191098
- // localisation handoff
191099
- ];
191100
- var PROJECT_LOCALE_SCENE = "@project";
191101
- function castStringKey(name) {
191102
- return `cast:${name}`;
191103
- }
191104
- var DEFAULT_CAPTION_DELIMITERS = { open: "[", close: "]" };
191105
- var DEFAULT_CAPTION_CHARACTER = "SFX";
191106
-
191107
190987
  // ../../node_modules/json5/dist/index.mjs
191108
190988
  var Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/;
191109
190989
  var ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/;
@@ -192189,11 +192069,1080 @@ var JSON5 = {
192189
192069
  var lib = JSON5;
192190
192070
  var dist_default = lib;
192191
192071
 
192192
- // ../core/src/serialize.ts
192072
+ // ../../node_modules/@wildwinter/toolkit/dist/index.js
192073
+ var ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
192074
+ function newId(prefix = "", length = 8) {
192075
+ const limit = 256 - 256 % ALPHABET.length;
192076
+ let token2 = "";
192077
+ while (token2.length < length) {
192078
+ const bytes = new Uint8Array(length * 2);
192079
+ globalThis.crypto.getRandomValues(bytes);
192080
+ for (const b of bytes) {
192081
+ if (b >= limit) continue;
192082
+ token2 += ALPHABET[b % ALPHABET.length];
192083
+ if (token2.length === length) break;
192084
+ }
192085
+ }
192086
+ return prefix ? `${prefix}_${token2}` : token2;
192087
+ }
192088
+ function fnv32(input) {
192089
+ let h = 2166136261;
192090
+ for (let i = 0; i < input.length; i++) {
192091
+ h ^= input.charCodeAt(i);
192092
+ h = Math.imul(h, 16777619);
192093
+ }
192094
+ return h >>> 0;
192095
+ }
192193
192096
  function parseSource(text) {
192194
192097
  const body = text.charCodeAt(0) === 65279 ? text.slice(1) : text;
192195
192098
  return dist_default.parse(body);
192196
192099
  }
192100
+
192101
+ // ../core/src/handle.ts
192102
+ function slug(name) {
192103
+ const s = name.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
192104
+ return s || "_";
192105
+ }
192106
+ function hash32(input) {
192107
+ return fnv32(input).toString(36).padStart(7, "0");
192108
+ }
192109
+
192110
+ // ../../../expr/packages/expr/src/parser.ts
192111
+ var ParseError = class extends Error {
192112
+ constructor(message, pos2, source2) {
192113
+ super(`Parse error at position ${pos2}: ${message}
192114
+ ${source2}
192115
+ ${" ".repeat(pos2)}^`);
192116
+ this.pos = pos2;
192117
+ this.source = source2;
192118
+ this.name = "ParseError";
192119
+ }
192120
+ pos;
192121
+ source;
192122
+ };
192123
+ var KEYWORDS = {
192124
+ true: "BOOL",
192125
+ false: "BOOL",
192126
+ and: "AND",
192127
+ or: "OR",
192128
+ not: "NOT"
192129
+ };
192130
+ var KEYWORD_NAMES = Object.freeze(Object.keys(KEYWORDS));
192131
+ function tokenise(src) {
192132
+ const tokens = [];
192133
+ let i = 0;
192134
+ while (i < src.length) {
192135
+ if (/\s/.test(src[i])) {
192136
+ i++;
192137
+ continue;
192138
+ }
192139
+ const pos2 = i;
192140
+ if (src[i] === "@") {
192141
+ const m = src.slice(i).match(/^@([a-z_][a-z0-9_]*)/);
192142
+ if (!m) throw new ParseError(`unexpected character '@'`, pos2, src);
192143
+ tokens.push({ kind: "VAR", value: m[1], pos: pos2 });
192144
+ i += m[0].length;
192145
+ continue;
192146
+ }
192147
+ if (src[i] === '"' || src[i] === "'") {
192148
+ const quote = src[i];
192149
+ let s = "";
192150
+ i++;
192151
+ while (i < src.length && src[i] !== quote) {
192152
+ if (src[i] === "\\" && i + 1 < src.length) {
192153
+ i++;
192154
+ const esc2 = { n: "\n", t: " ", r: "\r", "\\": "\\", "'": "'", '"': '"' };
192155
+ s += esc2[src[i]] ?? src[i];
192156
+ } else {
192157
+ s += src[i];
192158
+ }
192159
+ i++;
192160
+ }
192161
+ if (i >= src.length) throw new ParseError("unterminated string literal", pos2, src);
192162
+ i++;
192163
+ tokens.push({ kind: "STR", value: s, pos: pos2 });
192164
+ continue;
192165
+ }
192166
+ if (/[0-9]/.test(src[i])) {
192167
+ const m = src.slice(i).match(/^[0-9]+(\.[0-9]+)?/);
192168
+ tokens.push({ kind: "NUM", value: m[0], pos: pos2 });
192169
+ i += m[0].length;
192170
+ continue;
192171
+ }
192172
+ const two = src.slice(i, i + 2);
192173
+ if (two === "==") {
192174
+ tokens.push({ kind: "EQ", value: "==", pos: pos2 });
192175
+ i += 2;
192176
+ continue;
192177
+ }
192178
+ if (two === "!=") {
192179
+ tokens.push({ kind: "NEQ", value: "!=", pos: pos2 });
192180
+ i += 2;
192181
+ continue;
192182
+ }
192183
+ if (two === "<>") {
192184
+ tokens.push({ kind: "NEQ", value: "<>", pos: pos2 });
192185
+ i += 2;
192186
+ continue;
192187
+ }
192188
+ if (src[i] === "=" && src[i + 1] !== "=") {
192189
+ tokens.push({ kind: "EQ", value: "=", pos: pos2 });
192190
+ i++;
192191
+ continue;
192192
+ }
192193
+ if (two === ">=") {
192194
+ tokens.push({ kind: "GTE", value: ">=", pos: pos2 });
192195
+ i += 2;
192196
+ continue;
192197
+ }
192198
+ if (two === "<=") {
192199
+ tokens.push({ kind: "LTE", value: "<=", pos: pos2 });
192200
+ i += 2;
192201
+ continue;
192202
+ }
192203
+ if (two === "&&") {
192204
+ tokens.push({ kind: "AND", value: "&&", pos: pos2 });
192205
+ i += 2;
192206
+ continue;
192207
+ }
192208
+ if (two === "||") {
192209
+ tokens.push({ kind: "OR", value: "||", pos: pos2 });
192210
+ i += 2;
192211
+ continue;
192212
+ }
192213
+ const ch = src[i];
192214
+ if (ch === ">") {
192215
+ tokens.push({ kind: "GT", value: ">", pos: pos2 });
192216
+ i++;
192217
+ continue;
192218
+ }
192219
+ if (ch === "<") {
192220
+ tokens.push({ kind: "LT", value: "<", pos: pos2 });
192221
+ i++;
192222
+ continue;
192223
+ }
192224
+ if (ch === "+") {
192225
+ tokens.push({ kind: "PLUS", value: "+", pos: pos2 });
192226
+ i++;
192227
+ continue;
192228
+ }
192229
+ if (ch === "-") {
192230
+ tokens.push({ kind: "MINUS", value: "-", pos: pos2 });
192231
+ i++;
192232
+ continue;
192233
+ }
192234
+ if (ch === "*") {
192235
+ tokens.push({ kind: "STAR", value: "*", pos: pos2 });
192236
+ i++;
192237
+ continue;
192238
+ }
192239
+ if (ch === "/") {
192240
+ tokens.push({ kind: "SLASH", value: "/", pos: pos2 });
192241
+ i++;
192242
+ continue;
192243
+ }
192244
+ if (ch === "(") {
192245
+ tokens.push({ kind: "LPAREN", value: "(", pos: pos2 });
192246
+ i++;
192247
+ continue;
192248
+ }
192249
+ if (ch === ")") {
192250
+ tokens.push({ kind: "RPAREN", value: ")", pos: pos2 });
192251
+ i++;
192252
+ continue;
192253
+ }
192254
+ if (ch === ",") {
192255
+ tokens.push({ kind: "COMMA", value: ",", pos: pos2 });
192256
+ i++;
192257
+ continue;
192258
+ }
192259
+ if (ch === ".") {
192260
+ tokens.push({ kind: "DOT", value: ".", pos: pos2 });
192261
+ i++;
192262
+ continue;
192263
+ }
192264
+ if (ch === "!") {
192265
+ tokens.push({ kind: "NOT", value: "!", pos: pos2 });
192266
+ i++;
192267
+ continue;
192268
+ }
192269
+ if (/[a-zA-Z_]/.test(ch)) {
192270
+ const m = src.slice(i).match(/^[a-zA-Z_][a-zA-Z0-9_]*/);
192271
+ const word = m[0];
192272
+ const kw = KEYWORDS[word];
192273
+ tokens.push({ kind: kw ?? "IDENT", value: word, pos: pos2 });
192274
+ i += word.length;
192275
+ continue;
192276
+ }
192277
+ throw new ParseError(`unexpected character '${ch}'`, pos2, src);
192278
+ }
192279
+ tokens.push({ kind: "EOF", value: "", pos: i });
192280
+ return tokens;
192281
+ }
192282
+ var Parser = class {
192283
+ constructor(tokens, src, dialect) {
192284
+ this.tokens = tokens;
192285
+ this.src = src;
192286
+ this.scopes = new Set(dialect.scopes.map((s) => s.token));
192287
+ this.defaultScope = dialect.defaultScope;
192288
+ this.flagDeltaFns = new Set(
192289
+ Object.entries(dialect.functions).filter(([, def]) => def.flagDeltaArgs).map(([name]) => name)
192290
+ );
192291
+ }
192292
+ tokens;
192293
+ src;
192294
+ pos = 0;
192295
+ scopes;
192296
+ defaultScope;
192297
+ flagDeltaFns;
192298
+ peek() {
192299
+ return this.tokens[this.pos];
192300
+ }
192301
+ advance() {
192302
+ return this.tokens[this.pos++];
192303
+ }
192304
+ check(kind) {
192305
+ return this.peek().kind === kind;
192306
+ }
192307
+ expect(kind) {
192308
+ if (!this.check(kind)) {
192309
+ const tok = this.peek();
192310
+ throw new ParseError(`expected ${kind}, got '${tok.value}'`, tok.pos, this.src);
192311
+ }
192312
+ return this.advance();
192313
+ }
192314
+ parse() {
192315
+ const node = this.parseOr();
192316
+ if (!this.check("EOF")) {
192317
+ const tok = this.peek();
192318
+ throw new ParseError(`unexpected token '${tok.value}'`, tok.pos, this.src);
192319
+ }
192320
+ return node;
192321
+ }
192322
+ parseOr() {
192323
+ let left = this.parseAnd();
192324
+ while (this.check("OR")) {
192325
+ this.advance();
192326
+ const right = this.parseAnd();
192327
+ left = { kind: "binary", op: "or", left, right };
192328
+ }
192329
+ return left;
192330
+ }
192331
+ parseAnd() {
192332
+ let left = this.parseNot();
192333
+ while (this.check("AND")) {
192334
+ this.advance();
192335
+ const right = this.parseNot();
192336
+ left = { kind: "binary", op: "and", left, right };
192337
+ }
192338
+ return left;
192339
+ }
192340
+ parseNot() {
192341
+ if (this.check("NOT")) {
192342
+ this.advance();
192343
+ const operand = this.parseNot();
192344
+ return { kind: "unary", op: "not", operand };
192345
+ }
192346
+ return this.parseComparison();
192347
+ }
192348
+ parseComparison() {
192349
+ const left = this.parseAdditive();
192350
+ const opMap = {
192351
+ EQ: "==",
192352
+ NEQ: "!=",
192353
+ GT: ">",
192354
+ GTE: ">=",
192355
+ LT: "<",
192356
+ LTE: "<="
192357
+ };
192358
+ const op = opMap[this.peek().kind];
192359
+ if (op !== void 0) {
192360
+ this.advance();
192361
+ const right = this.parseAdditive();
192362
+ return { kind: "binary", op, left, right };
192363
+ }
192364
+ return left;
192365
+ }
192366
+ parseAdditive() {
192367
+ let left = this.parseMultiplicative();
192368
+ while (this.check("PLUS") || this.check("MINUS")) {
192369
+ const op = this.advance().kind === "PLUS" ? "+" : "-";
192370
+ const right = this.parseMultiplicative();
192371
+ left = { kind: "binary", op, left, right };
192372
+ }
192373
+ return left;
192374
+ }
192375
+ parseMultiplicative() {
192376
+ let left = this.parseUnaryMinus();
192377
+ while (this.check("STAR") || this.check("SLASH")) {
192378
+ const op = this.advance().kind === "STAR" ? "*" : "/";
192379
+ const right = this.parseUnaryMinus();
192380
+ left = { kind: "binary", op, left, right };
192381
+ }
192382
+ return left;
192383
+ }
192384
+ parseUnaryMinus() {
192385
+ if (this.check("MINUS")) {
192386
+ this.advance();
192387
+ const operand = this.parseUnaryMinus();
192388
+ if (operand.kind === "number") return { kind: "number", value: -operand.value };
192389
+ return { kind: "unary", op: "neg", operand };
192390
+ }
192391
+ return this.parsePrimary();
192392
+ }
192393
+ // Scope-qualified property ref: <scope>.<name> (after a VAR or IDENT token).
192394
+ maybeScopedVar(name) {
192395
+ if (this.scopes.has(name) && this.check("DOT")) {
192396
+ this.advance();
192397
+ const propTok = this.peek();
192398
+ if (propTok.kind !== "IDENT") {
192399
+ throw new ParseError(
192400
+ `expected a property name after '${name}.', got '${propTok.value}'`,
192401
+ propTok.pos,
192402
+ this.src
192403
+ );
192404
+ }
192405
+ this.advance();
192406
+ return { kind: "scopedvar", scope: name, name: propTok.value.toLowerCase() };
192407
+ }
192408
+ return null;
192409
+ }
192410
+ parsePrimary() {
192411
+ const tok = this.peek();
192412
+ if (tok.kind === "BOOL") {
192413
+ this.advance();
192414
+ return { kind: "bool", value: tok.value === "true" };
192415
+ }
192416
+ if (tok.kind === "NUM") {
192417
+ this.advance();
192418
+ return { kind: "number", value: Number(tok.value) };
192419
+ }
192420
+ if (tok.kind === "STR") {
192421
+ this.advance();
192422
+ return { kind: "string", value: tok.value };
192423
+ }
192424
+ if (tok.kind === "VAR") {
192425
+ const name = tok.value;
192426
+ this.advance();
192427
+ const scoped = this.maybeScopedVar(name);
192428
+ if (scoped) return scoped;
192429
+ return { kind: "scopedvar", scope: this.defaultScope, name: name.toLowerCase() };
192430
+ }
192431
+ if (tok.kind === "IDENT") {
192432
+ const name = tok.value;
192433
+ this.advance();
192434
+ const scoped = this.maybeScopedVar(name);
192435
+ if (scoped) return scoped;
192436
+ if (this.check("LPAREN")) {
192437
+ this.advance();
192438
+ const args = [];
192439
+ if (!this.check("RPAREN")) {
192440
+ args.push(this.parseOr());
192441
+ while (this.check("COMMA")) {
192442
+ this.advance();
192443
+ const wantsFlagDelta = this.flagDeltaFns.has(name) && args.length >= 1;
192444
+ if (wantsFlagDelta) {
192445
+ const sign2 = this.check("PLUS") ? "+" : this.check("MINUS") ? "-" : null;
192446
+ if (sign2 === null) {
192447
+ const t = this.peek();
192448
+ throw new ParseError(
192449
+ `${name}: expected +flagName or -flagName, got '${t.value}'`,
192450
+ t.pos,
192451
+ this.src
192452
+ );
192453
+ }
192454
+ this.advance();
192455
+ const flagTok = this.peek();
192456
+ if (flagTok.kind !== "IDENT") {
192457
+ throw new ParseError(
192458
+ `${name}: expected a flag name after '${sign2}', got '${flagTok.value}'`,
192459
+ flagTok.pos,
192460
+ this.src
192461
+ );
192462
+ }
192463
+ this.advance();
192464
+ args.push({ kind: "flagdelta", sign: sign2, name: flagTok.value });
192465
+ } else {
192466
+ args.push(this.parseOr());
192467
+ }
192468
+ }
192469
+ }
192470
+ this.expect("RPAREN");
192471
+ return { kind: "call", name, args };
192472
+ }
192473
+ return { kind: "string", value: name };
192474
+ }
192475
+ if (tok.kind === "LPAREN") {
192476
+ this.advance();
192477
+ const inner = this.parseOr();
192478
+ this.expect("RPAREN");
192479
+ return inner;
192480
+ }
192481
+ if (tok.kind === "EOF") {
192482
+ throw new ParseError("expression is incomplete - expected a value", tok.pos, this.src);
192483
+ }
192484
+ throw new ParseError(`unexpected token '${tok.value}'`, tok.pos, this.src);
192485
+ }
192486
+ };
192487
+ function parse3(source2, dialect) {
192488
+ const tokens = tokenise(source2);
192489
+ return new Parser(tokens, source2, dialect).parse();
192490
+ }
192491
+
192492
+ // ../../../expr/packages/expr/src/ast.ts
192493
+ function serialiseAst(node) {
192494
+ switch (node.kind) {
192495
+ case "bool":
192496
+ return ["b", node.value];
192497
+ case "number":
192498
+ return ["n", node.value];
192499
+ case "string":
192500
+ return ["s", node.value];
192501
+ case "scopedvar":
192502
+ return ["sv", node.scope, node.name];
192503
+ case "unary":
192504
+ return ["u", node.op, serialiseAst(node.operand)];
192505
+ case "binary":
192506
+ return ["bin", node.op, serialiseAst(node.left), serialiseAst(node.right)];
192507
+ case "call":
192508
+ return ["call", node.name, ...node.args.map(serialiseAst)];
192509
+ case "flagdelta":
192510
+ return ["fd", node.sign, node.name];
192511
+ }
192512
+ }
192513
+ function deserialiseAst(node) {
192514
+ switch (node[0]) {
192515
+ case "b":
192516
+ return { kind: "bool", value: node[1] };
192517
+ case "n":
192518
+ return { kind: "number", value: node[1] };
192519
+ case "s":
192520
+ return { kind: "string", value: node[1] };
192521
+ case "sv":
192522
+ return { kind: "scopedvar", scope: node[1], name: node[2] };
192523
+ case "u":
192524
+ return { kind: "unary", op: node[1], operand: deserialiseAst(node[2]) };
192525
+ case "bin":
192526
+ return { kind: "binary", op: node[1], left: deserialiseAst(node[2]), right: deserialiseAst(node[3]) };
192527
+ case "call": {
192528
+ const args = node.slice(2).map(deserialiseAst);
192529
+ return { kind: "call", name: node[1], args };
192530
+ }
192531
+ case "fd":
192532
+ return { kind: "flagdelta", sign: node[1], name: node[2] };
192533
+ }
192534
+ }
192535
+
192536
+ // ../../../expr/packages/expr/src/evaluate.ts
192537
+ var EvalError2 = class extends Error {
192538
+ constructor(message) {
192539
+ super(message);
192540
+ this.name = "EvalError";
192541
+ }
192542
+ };
192543
+ function evaluate(node, ctx, dialect) {
192544
+ const missingPolicy = new Map(
192545
+ dialect.scopes.map((s) => [s.token, s.missing ?? "false"])
192546
+ );
192547
+ const rec = (n) => {
192548
+ switch (n.kind) {
192549
+ case "bool":
192550
+ return n.value;
192551
+ case "number":
192552
+ return n.value;
192553
+ case "string":
192554
+ return n.value;
192555
+ case "scopedvar": {
192556
+ const scope = ctx.scopes[n.scope];
192557
+ if (scope === void 0) {
192558
+ return false;
192559
+ }
192560
+ const val = typeof scope.get === "function" ? scope.get(n.name) : scope[n.name];
192561
+ if (val === void 0) {
192562
+ if (missingPolicy.get(n.scope) === "throw") {
192563
+ throw new EvalError2(`@${n.scope}.${n.name} is not declared on the current ${n.scope}.`);
192564
+ }
192565
+ return false;
192566
+ }
192567
+ return val;
192568
+ }
192569
+ case "call": {
192570
+ if (n.name === "advance" && !dialect.functions[n.name]) {
192571
+ const arg = n.args[0];
192572
+ if (n.args.length !== 1 || arg === void 0) {
192573
+ throw new EvalError2(`advance() takes exactly 1 argument, got ${n.args.length}`);
192574
+ }
192575
+ const ladder = ladderOf(arg, ctx);
192576
+ if (ladder === void 0) {
192577
+ throw new EvalError2("advance() needs a quality reference (@scope.name of a quality property)");
192578
+ }
192579
+ const current = stageIndex(rec(arg), ladder, "advance");
192580
+ return ladder[Math.min(current + 1, ladder.length - 1)];
192581
+ }
192582
+ const def = dialect.functions[n.name];
192583
+ if (!def) throw new EvalError2(`unknown function '${n.name}'`);
192584
+ return def.eval(n.args, { evaluate: rec, ctx });
192585
+ }
192586
+ case "flagdelta":
192587
+ throw new EvalError2("flagdelta node is only valid as an argument to a flag-delta function");
192588
+ case "unary": {
192589
+ if (n.op === "not") {
192590
+ const val2 = rec(n.operand);
192591
+ if (typeof val2 !== "boolean") throw new EvalError2(`'not' requires a boolean operand, got ${typeof val2}`);
192592
+ return !val2;
192593
+ }
192594
+ const val = rec(n.operand);
192595
+ if (typeof val !== "number") throw new EvalError2(`unary '-' requires a numeric operand, got ${typeof val}`);
192596
+ return -val;
192597
+ }
192598
+ case "binary": {
192599
+ if (n.op === "and") {
192600
+ const l2 = rec(n.left);
192601
+ if (typeof l2 !== "boolean") throw new EvalError2(`'and' requires boolean operands, left is ${typeof l2}`);
192602
+ if (!l2) return false;
192603
+ const r = rec(n.right);
192604
+ if (typeof r !== "boolean") throw new EvalError2(`'and' requires boolean operands, right is ${typeof r}`);
192605
+ return r;
192606
+ }
192607
+ if (n.op === "or") {
192608
+ const l2 = rec(n.left);
192609
+ if (typeof l2 !== "boolean") throw new EvalError2(`'or' requires boolean operands, left is ${typeof l2}`);
192610
+ if (l2) return true;
192611
+ const r = rec(n.right);
192612
+ if (typeof r !== "boolean") throw new EvalError2(`'or' requires boolean operands, right is ${typeof r}`);
192613
+ return r;
192614
+ }
192615
+ const left = rec(n.left);
192616
+ const right = rec(n.right);
192617
+ const lLadder = ladderOf(n.left, ctx);
192618
+ const rLadder = ladderOf(n.right, ctx);
192619
+ const ladder = lLadder ?? rLadder;
192620
+ if (ladder !== void 0) {
192621
+ if (lLadder && rLadder && !sameLadder(lLadder, rLadder)) {
192622
+ if (n.op === ">" || n.op === ">=" || n.op === "<" || n.op === "<=") {
192623
+ throw new EvalError2(`'${n.op}' compares two different qualities, whose stage orders are unrelated`);
192624
+ }
192625
+ }
192626
+ switch (n.op) {
192627
+ case ">":
192628
+ return stageIndex(left, ladder, ">") > stageIndex(right, ladder, ">");
192629
+ case ">=":
192630
+ return stageIndex(left, ladder, ">=") >= stageIndex(right, ladder, ">=");
192631
+ case "<":
192632
+ return stageIndex(left, ladder, "<") < stageIndex(right, ladder, "<");
192633
+ case "<=":
192634
+ return stageIndex(left, ladder, "<=") <= stageIndex(right, ladder, "<=");
192635
+ case "+":
192636
+ case "-":
192637
+ case "*":
192638
+ case "/":
192639
+ throw new EvalError2(`'${n.op}' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);
192640
+ default:
192641
+ break;
192642
+ }
192643
+ }
192644
+ switch (n.op) {
192645
+ case "==":
192646
+ return valueEquals(left, right);
192647
+ case "!=":
192648
+ return !valueEquals(left, right);
192649
+ case ">":
192650
+ assertNumbers(left, right, ">");
192651
+ return left > right;
192652
+ case ">=":
192653
+ assertNumbers(left, right, ">=");
192654
+ return left >= right;
192655
+ case "<":
192656
+ assertNumbers(left, right, "<");
192657
+ return left < right;
192658
+ case "<=":
192659
+ assertNumbers(left, right, "<=");
192660
+ return left <= right;
192661
+ case "+":
192662
+ if (typeof left === "number" && typeof right === "number") return left + right;
192663
+ if (typeof left === "string" && typeof right === "string") return left + right;
192664
+ throw new EvalError2(`'+' requires two numbers or two strings, got ${typeof left} and ${typeof right}`);
192665
+ case "-":
192666
+ assertNumbers(left, right, "-");
192667
+ return left - right;
192668
+ case "*":
192669
+ assertNumbers(left, right, "*");
192670
+ return left * right;
192671
+ case "/":
192672
+ assertNumbers(left, right, "/");
192673
+ if (right === 0) throw new EvalError2("division by zero");
192674
+ return left / right;
192675
+ }
192676
+ }
192677
+ }
192678
+ };
192679
+ return rec(node);
192680
+ }
192681
+ function valueEquals(a, b) {
192682
+ if (Array.isArray(a) || Array.isArray(b)) {
192683
+ if (!Array.isArray(a) || !Array.isArray(b)) return false;
192684
+ if (a.length !== b.length) return false;
192685
+ const x = [...a].sort();
192686
+ const y = [...b].sort();
192687
+ for (let i = 0; i < x.length; i++) if (x[i] !== y[i]) return false;
192688
+ return true;
192689
+ }
192690
+ return a === b;
192691
+ }
192692
+ function assertNumbers(l2, r, op) {
192693
+ if (typeof l2 !== "number" || typeof r !== "number") {
192694
+ throw new EvalError2(`'${op}' requires numeric operands, got ${typeof l2} and ${typeof r}`);
192695
+ }
192696
+ }
192697
+ function ladderOf(node, ctx) {
192698
+ if (node.kind !== "scopedvar" || ctx.qualities === void 0) return void 0;
192699
+ return ctx.qualities(node.scope, node.name);
192700
+ }
192701
+ function stageIndex(value, ladder, op) {
192702
+ if (typeof value !== "string") {
192703
+ throw new EvalError2(`'${op}' on a quality compares stages, got ${typeof value}`);
192704
+ }
192705
+ const i = ladder.indexOf(value);
192706
+ if (i < 0) throw new EvalError2(`"${value}" is not a stage of this quality (stages: ${ladder.join(", ")})`);
192707
+ return i;
192708
+ }
192709
+ var sameLadder = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
192710
+
192711
+ // ../../../expr/packages/expr/src/prng.ts
192712
+ function toUint32(seed) {
192713
+ if (Number.isNaN(seed) || !Number.isFinite(seed)) return 0;
192714
+ const modded = Math.trunc(seed) % 4294967296;
192715
+ return modded < 0 ? modded + 4294967296 : modded;
192716
+ }
192717
+ function makePrng(seed) {
192718
+ let s = toUint32(seed);
192719
+ return {
192720
+ next() {
192721
+ s = s + 1831565813 >>> 0;
192722
+ let t = Math.imul(s ^ s >>> 15, 1 | s);
192723
+ t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
192724
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
192725
+ },
192726
+ state() {
192727
+ return s;
192728
+ }
192729
+ };
192730
+ }
192731
+
192732
+ // ../../../expr/packages/expr/src/latches.ts
192733
+ var scopedRef = (ast) => Array.isArray(ast) && ast[0] === "sv" ? `@${String(ast[1])}.${String(ast[2])}` : void 0;
192734
+ function latchOf(ast, owner, keyOf2) {
192735
+ const direct = scopedRef(ast);
192736
+ if (direct !== void 0) return keyOf2(direct, owner);
192737
+ if (!Array.isArray(ast)) return void 0;
192738
+ if (ast[0] === "bin" && ast[1] === "==") {
192739
+ const [, , l2, r] = ast;
192740
+ for (const [a, b] of [[l2, r], [r, l2]]) {
192741
+ const ref = scopedRef(a);
192742
+ if (ref !== void 0 && Array.isArray(b) && b[0] === "b" && b[1] === true) return keyOf2(ref, owner);
192743
+ }
192744
+ return void 0;
192745
+ }
192746
+ if (ast[0] === "call" && ast[1] === "check_flags") {
192747
+ const ref = scopedRef(ast[2]);
192748
+ const args = ast.slice(3);
192749
+ if (ref === void 0 || args.length !== 1) return void 0;
192750
+ const arg = args[0];
192751
+ if (Array.isArray(arg) && arg[0] === "fd" && arg[1] === "+") {
192752
+ return `${keyOf2(ref, owner)}:${String(arg[2])}`;
192753
+ }
192754
+ }
192755
+ return void 0;
192756
+ }
192757
+ function disjuncts(ast) {
192758
+ if (Array.isArray(ast) && ast[0] === "bin" && ast[1] === "or") {
192759
+ const [, , l2, r] = ast;
192760
+ return [...disjuncts(l2), ...disjuncts(r)];
192761
+ }
192762
+ return [ast];
192763
+ }
192764
+ function terms(ast, owner, keyOf2, negated = false, into = []) {
192765
+ const latch = latchOf(ast, owner, keyOf2);
192766
+ if (latch !== void 0) {
192767
+ into.push({ key: latch, negated });
192768
+ return into;
192769
+ }
192770
+ if (!Array.isArray(ast)) return into;
192771
+ if (ast[0] === "u" && ast[1] === "not") return terms(ast[2], owner, keyOf2, !negated, into);
192772
+ if (ast[0] === "bin" && ast[1] === "and" && !negated) {
192773
+ terms(ast[2], owner, keyOf2, false, into);
192774
+ terms(ast[3], owner, keyOf2, false, into);
192775
+ }
192776
+ return into;
192777
+ }
192778
+
192779
+ // ../../../expr/packages/expr/src/names.ts
192780
+ var RESERVED_PROPERTY_NAMES = KEYWORD_NAMES;
192781
+ function propertyNameify(text) {
192782
+ const trimmed = text.trim();
192783
+ const deliberateLeading = trimmed.startsWith("_");
192784
+ let out = trimmed.toLowerCase().replace(/['’]/g, "").replace(/[^a-z0-9_]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
192785
+ if (out === "") return "";
192786
+ if (deliberateLeading || /^[0-9]/.test(out)) out = `_${out}`;
192787
+ if (RESERVED_PROPERTY_NAMES.includes(out)) out = `${out}_`;
192788
+ return out;
192789
+ }
192790
+ function isValidPropertyName(name) {
192791
+ return /^[a-z_][a-z0-9_]*$/.test(name) && !RESERVED_PROPERTY_NAMES.includes(name);
192792
+ }
192793
+ function isCaseOnlyPropertyName(name) {
192794
+ return !isValidPropertyName(name) && isValidPropertyName(name.toLowerCase());
192795
+ }
192796
+
192797
+ // ../../../expr/packages/expr/src/validate.ts
192798
+ function validateExpressionAst(node, schema, dialect) {
192799
+ const issues = [];
192800
+ walkValidate(node, schema, dialect, [], issues);
192801
+ return finaliseResult(issues);
192802
+ }
192803
+ function validateExpr(node, schema, dialect) {
192804
+ return validateExpressionAst(node, schema, dialect).issues;
192805
+ }
192806
+ function finaliseResult(issues) {
192807
+ const hasError = issues.some((i) => i.severity === "error");
192808
+ const summary = issues.map((i) => i.message).join("; ");
192809
+ return { ok: !hasError, issues, summary };
192810
+ }
192811
+ function walkValidate(node, schema, dialect, path, issues) {
192812
+ switch (node.kind) {
192813
+ case "bool":
192814
+ case "number":
192815
+ case "string":
192816
+ case "flagdelta":
192817
+ return;
192818
+ case "scopedvar": {
192819
+ const scopeMap = schema.properties.get(node.scope);
192820
+ if (scopeMap && !scopeMap.has(node.name)) {
192821
+ const isDefault = node.scope === dialect.defaultScope;
192822
+ issues.push({
192823
+ path,
192824
+ kind: isDefault ? "unresolved-property" : "unresolved-scoped-property",
192825
+ severity: "error",
192826
+ message: isDefault ? `unresolved property reference '@${node.name}'` : `unresolved ${node.scope} property reference '@${node.scope}.${node.name}'`,
192827
+ reference: isDefault ? node.name : `${node.scope}.${node.name}`
192828
+ });
192829
+ }
192830
+ return;
192831
+ }
192832
+ case "call": {
192833
+ if (node.name === "advance" && !dialect.functions[node.name]) {
192834
+ if (node.args.length !== 1) {
192835
+ issues.push({ path, kind: "wrong-arg-count", severity: "error", message: `advance() takes exactly 1 argument, got ${node.args.length}` });
192836
+ }
192837
+ const arg = node.args[0];
192838
+ if (arg) {
192839
+ walkValidate(arg, schema, dialect, [...path, "args", 0], issues);
192840
+ if (stagesOf(arg, schema) === void 0 && typeOf(arg, schema, dialect) !== "unknown") {
192841
+ issues.push({
192842
+ path: [...path, "args", 0],
192843
+ kind: "wrong-arg-type",
192844
+ severity: "error",
192845
+ message: "advance() needs a quality reference (@scope.name of a quality property)"
192846
+ });
192847
+ }
192848
+ }
192849
+ return;
192850
+ }
192851
+ const def = dialect.functions[node.name];
192852
+ if (!def) {
192853
+ issues.push({ path, kind: "unknown-function", severity: "error", message: `unknown function '${node.name}'` });
192854
+ return;
192855
+ }
192856
+ if (node.args.length < def.minArgs) {
192857
+ issues.push({
192858
+ path,
192859
+ kind: "wrong-arg-count",
192860
+ severity: "error",
192861
+ message: `${node.name}() requires at least ${def.minArgs} argument(s), got ${node.args.length}`
192862
+ });
192863
+ }
192864
+ if (def.maxArgs !== void 0 && node.args.length > def.maxArgs) {
192865
+ issues.push({
192866
+ path,
192867
+ kind: "wrong-arg-count",
192868
+ severity: "error",
192869
+ message: `${node.name}() takes at most ${def.maxArgs} argument(s), got ${node.args.length}`
192870
+ });
192871
+ }
192872
+ for (let i = 0; i < node.args.length; i++) {
192873
+ walkValidate(node.args[i], schema, dialect, [...path, "args", i], issues);
192874
+ }
192875
+ if (def.validate) {
192876
+ def.validate(node.args, {
192877
+ schema,
192878
+ path,
192879
+ defaultScope: dialect.defaultScope,
192880
+ report: (issue) => issues.push(issue)
192881
+ });
192882
+ }
192883
+ return;
192884
+ }
192885
+ case "unary": {
192886
+ walkValidate(node.operand, schema, dialect, [...path, "operand"], issues);
192887
+ checkUnaryOperandType(node.op, node.operand, schema, dialect, [...path, "operand"], issues);
192888
+ return;
192889
+ }
192890
+ case "binary": {
192891
+ walkValidate(node.left, schema, dialect, [...path, "left"], issues);
192892
+ walkValidate(node.right, schema, dialect, [...path, "right"], issues);
192893
+ checkBinaryOperandTypes(node.op, node.left, node.right, schema, dialect, path, issues);
192894
+ if (node.op === "/" && node.right.kind === "number" && node.right.value === 0) {
192895
+ issues.push({
192896
+ path: [...path, "right"],
192897
+ kind: "division-by-zero",
192898
+ severity: "error",
192899
+ message: "division by zero - pick a non-zero divisor"
192900
+ });
192901
+ }
192902
+ if (node.op === "==" || node.op === "!=") {
192903
+ const left = node.left, right = node.right;
192904
+ let propNode = null;
192905
+ let strNode = null;
192906
+ let strSide = null;
192907
+ if (left.kind === "scopedvar" && right.kind === "string") {
192908
+ propNode = left;
192909
+ strNode = right;
192910
+ strSide = "right";
192911
+ } else if (right.kind === "scopedvar" && left.kind === "string") {
192912
+ propNode = right;
192913
+ strNode = left;
192914
+ strSide = "left";
192915
+ }
192916
+ if (propNode && strNode && strSide) {
192917
+ const meta = schema.properties.get(propNode.scope)?.get(propNode.name);
192918
+ if (meta?.type === "enum" && meta.enumValues && !meta.enumValues.includes(strNode.value)) {
192919
+ issues.push({
192920
+ path: [...path, strSide],
192921
+ kind: "unknown-enum-value",
192922
+ severity: "error",
192923
+ message: `'${strNode.value}' is not a valid value for this property - expected one of: ${meta.enumValues.join(", ")}`,
192924
+ reference: strNode.value
192925
+ });
192926
+ }
192927
+ }
192928
+ }
192929
+ return;
192930
+ }
192931
+ }
192932
+ }
192933
+ function inferredFromPropertyType(t) {
192934
+ if (t === "boolean") return "boolean";
192935
+ if (t === "number") return "number";
192936
+ if (t === "string" || t === "enum") return "string";
192937
+ if (t === "flags") return "flags";
192938
+ if (t === "quality") return "quality";
192939
+ return "unknown";
192940
+ }
192941
+ function inferredFromReturn(t) {
192942
+ return t;
192943
+ }
192944
+ function stagesOf(node, schema) {
192945
+ if (node.kind !== "scopedvar") return void 0;
192946
+ const meta = schema.properties.get(node.scope)?.get(node.name);
192947
+ return meta?.type === "quality" ? meta.stages : void 0;
192948
+ }
192949
+ function typeOf(node, schema, dialect) {
192950
+ switch (node.kind) {
192951
+ case "bool":
192952
+ return "boolean";
192953
+ case "number":
192954
+ return "number";
192955
+ case "string":
192956
+ return "string";
192957
+ case "flagdelta":
192958
+ return "unknown";
192959
+ case "scopedvar": {
192960
+ const meta = schema.properties.get(node.scope)?.get(node.name);
192961
+ return meta ? inferredFromPropertyType(meta.type) : "unknown";
192962
+ }
192963
+ case "call": {
192964
+ if (node.name === "advance") return "quality";
192965
+ const def = dialect.functions[node.name];
192966
+ return def ? inferredFromReturn(def.returnType) : "unknown";
192967
+ }
192968
+ case "unary":
192969
+ return node.op === "not" ? "boolean" : "number";
192970
+ case "binary":
192971
+ switch (node.op) {
192972
+ case "+":
192973
+ case "-":
192974
+ case "*":
192975
+ case "/":
192976
+ return "number";
192977
+ case "==":
192978
+ case "!=":
192979
+ case ">":
192980
+ case "<":
192981
+ case ">=":
192982
+ case "<=":
192983
+ case "and":
192984
+ case "or":
192985
+ return "boolean";
192986
+ }
192987
+ }
192988
+ }
192989
+ function describeType(t) {
192990
+ return t === "unknown" ? "unknown type" : t;
192991
+ }
192992
+ function checkBinaryOperandTypes(op, left, right, schema, dialect, path, issues) {
192993
+ const lt = typeOf(left, schema, dialect);
192994
+ const rt = typeOf(right, schema, dialect);
192995
+ const ordering = op === ">" || op === "<" || op === ">=" || op === "<=";
192996
+ if (lt === "quality" || rt === "quality") {
192997
+ if (ordering || op === "==" || op === "!=") {
192998
+ const ls = stagesOf(left, schema);
192999
+ const rs = stagesOf(right, schema);
193000
+ if (ls && rs) {
193001
+ if (ls.join("\0") !== rs.join("\0")) {
193002
+ issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `'${op}' compares two different qualities, whose stages are unrelated` });
193003
+ }
193004
+ return;
193005
+ }
193006
+ const ladder = ls ?? rs;
193007
+ const other = ls ? right : left;
193008
+ const otherSide = ls ? "right" : "left";
193009
+ if (other.kind === "string") {
193010
+ if (ladder && !ladder.includes(other.value)) {
193011
+ issues.push({
193012
+ path: [...path, otherSide],
193013
+ kind: "unknown-stage",
193014
+ severity: "error",
193015
+ message: `'${other.value}' is not a stage of this quality - expected one of: ${ladder.join(", ")}`,
193016
+ reference: other.value
193017
+ });
193018
+ }
193019
+ return;
193020
+ }
193021
+ const ot = ls ? rt : lt;
193022
+ if (ot !== "unknown" && ot !== "quality") {
193023
+ issues.push({
193024
+ path: [...path, otherSide],
193025
+ kind: "operand-type-mismatch",
193026
+ severity: "error",
193027
+ message: `'${op}' on a quality compares stages, got ${describeType(ot)} on the ${otherSide}`
193028
+ });
193029
+ }
193030
+ return;
193031
+ }
193032
+ if (op === "+" || op === "-" || op === "*" || op === "/") {
193033
+ issues.push({
193034
+ path,
193035
+ kind: "operand-type-mismatch",
193036
+ severity: "error",
193037
+ message: `'${op}' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`
193038
+ });
193039
+ return;
193040
+ }
193041
+ }
193042
+ if (op === "+" || op === "-" || op === "*" || op === "/" || ordering) {
193043
+ if (lt !== "unknown" && lt !== "number")
193044
+ issues.push({ path: [...path, "left"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a number on the left, got ${describeType(lt)}` });
193045
+ if (rt !== "unknown" && rt !== "number")
193046
+ issues.push({ path: [...path, "right"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a number on the right, got ${describeType(rt)}` });
193047
+ return;
193048
+ }
193049
+ if (op === "and" || op === "or") {
193050
+ if (lt !== "unknown" && lt !== "boolean")
193051
+ issues.push({ path: [...path, "left"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a boolean on the left, got ${describeType(lt)}` });
193052
+ if (rt !== "unknown" && rt !== "boolean")
193053
+ issues.push({ path: [...path, "right"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a boolean on the right, got ${describeType(rt)}` });
193054
+ return;
193055
+ }
193056
+ if (op === "==" || op === "!=") {
193057
+ if (lt !== "unknown" && rt !== "unknown" && lt !== rt)
193058
+ issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `'${op}' compares ${describeType(lt)} with ${describeType(rt)}; the values can never be equal` });
193059
+ }
193060
+ }
193061
+ function checkUnaryOperandType(op, operand, schema, dialect, path, issues) {
193062
+ const t = typeOf(operand, schema, dialect);
193063
+ if (t === "unknown") return;
193064
+ if (op === "not" && t !== "boolean")
193065
+ issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `'not' requires a boolean operand, got ${describeType(t)}` });
193066
+ if (op === "neg" && t !== "number")
193067
+ issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `unary '-' requires a number, got ${describeType(t)}` });
193068
+ }
193069
+
193070
+ // ../../../expr/packages/expr/src/index.ts
193071
+ function compile(src, dialect) {
193072
+ return { src, ast: serialiseAst(parse3(src, dialect)) };
193073
+ }
193074
+
193075
+ // ../model/src/index.ts
193076
+ function walkNodes(nodes, visit) {
193077
+ for (const node of nodes) {
193078
+ visit(node);
193079
+ const children = node.children;
193080
+ if (children) walkNodes(children, visit);
193081
+ }
193082
+ }
193083
+ function isContentlessBeat(beat, hasText) {
193084
+ if (beat.kind === "gameEvent") return false;
193085
+ if (hasText) return false;
193086
+ if (beat.gameData && Object.keys(beat.gameData).length > 0) return false;
193087
+ if (beat.tags && beat.tags.length > 0) return false;
193088
+ return beat.kind === "text" || !beat.character && !beat.direction;
193089
+ }
193090
+ function gameIdify(text) {
193091
+ return text.toLowerCase().replace(/['’]/g, "").replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
193092
+ }
193093
+ function isValidGameId(gameId) {
193094
+ return /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(gameId);
193095
+ }
193096
+ function effectiveGameId(entity) {
193097
+ const g = entity.gameId?.trim();
193098
+ return g ? g : gameIdify(entity.name);
193099
+ }
193100
+ var DEFAULT_WRITING_STATUSES = [
193101
+ { name: "stub", colour: 0 },
193102
+ // red
193103
+ { name: "draft 1", colour: 1 },
193104
+ // rust
193105
+ { name: "draft 2", colour: 2 },
193106
+ // ochre
193107
+ { name: "edited", readyToRecord: true, colour: 4 },
193108
+ // green
193109
+ { name: "final", readyToShip: true, colour: 9 }
193110
+ // purple (violet)
193111
+ ];
193112
+ var DEFAULT_RECORDING_STATUSES = [
193113
+ { name: "missing", colour: 0 },
193114
+ // red
193115
+ { name: "scratch", colour: 2 },
193116
+ // ochre
193117
+ { name: "recorded", colour: 4 },
193118
+ // green
193119
+ { name: "final", colour: 9 }
193120
+ // purple
193121
+ ];
193122
+ var RERECORD_STATUS = "rerecord";
193123
+ function deriveRecordingFolders(audioRoot, statuses) {
193124
+ const root2 = audioRoot?.trim();
193125
+ return statuses.map((s, i) => {
193126
+ if (i === 0 || !root2) return { name: s.name };
193127
+ return { name: s.name, folder: `${root2}/${gameIdify(s.name)}` };
193128
+ });
193129
+ }
193130
+ var DEFAULT_DOCUMENTATION_CLASSES = [
193131
+ { name: "everyone", deliver: "*" },
193132
+ // every export, and (like all) the editor
193133
+ { name: "vo", deliver: ["vo"] },
193134
+ // voice-recording scripts
193135
+ { name: "loc", deliver: ["loc"] }
193136
+ // localisation handoff
193137
+ ];
193138
+ var PROJECT_LOCALE_SCENE = "@project";
193139
+ function castStringKey(name) {
193140
+ return `cast:${name}`;
193141
+ }
193142
+ var DEFAULT_CAPTION_DELIMITERS = { open: "[", close: "]" };
193143
+ var DEFAULT_CAPTION_CHARACTER = "SFX";
193144
+
193145
+ // ../core/src/serialize.ts
192197
193146
  function canonicalStringify(value, opts) {
192198
193147
  return write(value, "", opts?.trailingComma ?? true) + "\n";
192199
193148
  }
@@ -192793,7 +193742,7 @@ function merge3(base, ours, theirs, id, path, conflicts) {
192793
193742
  conflicts.push({ id, path, base, ours, theirs, kind: deletedKind(base, ours, theirs) });
192794
193743
  return ours;
192795
193744
  }
192796
- function mergeMap(base, ours, theirs, prefix, conflicts, resolve6) {
193745
+ function mergeMap(base, ours, theirs, prefix, conflicts, resolve7) {
192797
193746
  const out = {};
192798
193747
  for (const k of /* @__PURE__ */ new Set([...Object.keys(base), ...Object.keys(ours), ...Object.keys(theirs)])) {
192799
193748
  const b = base[k], o = ours[k], t = theirs[k];
@@ -192802,7 +193751,7 @@ function mergeMap(base, ours, theirs, prefix, conflicts, resolve6) {
192802
193751
  else if (eq(b, o)) v = t;
192803
193752
  else if (eq(b, t)) v = o;
192804
193753
  else {
192805
- const r = resolve6?.(k, b, o, t);
193754
+ const r = resolve7?.(k, b, o, t);
192806
193755
  if (r && r.resolved) v = r.value;
192807
193756
  else {
192808
193757
  conflicts.push({ id: k, path: `${prefix}.${k}`, base: b, ours: o, theirs: t, kind: r ? r.kind : deletedKind(b, o, t) });
@@ -193090,882 +194039,6 @@ function checkDuplicateIds(root2, conflicts) {
193090
194039
  var idMap = (nodes) => new Map(nodes.filter((n) => n.id).map((n) => [n.id, n]));
193091
194040
  var arrEq = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
193092
194041
 
193093
- // ../../../expr/packages/expr/src/parser.ts
193094
- var ParseError = class extends Error {
193095
- constructor(message, pos2, source2) {
193096
- super(`Parse error at position ${pos2}: ${message}
193097
- ${source2}
193098
- ${" ".repeat(pos2)}^`);
193099
- this.pos = pos2;
193100
- this.source = source2;
193101
- this.name = "ParseError";
193102
- }
193103
- pos;
193104
- source;
193105
- };
193106
- var KEYWORDS = {
193107
- true: "BOOL",
193108
- false: "BOOL",
193109
- and: "AND",
193110
- or: "OR",
193111
- not: "NOT"
193112
- };
193113
- function tokenise(src) {
193114
- const tokens = [];
193115
- let i = 0;
193116
- while (i < src.length) {
193117
- if (/\s/.test(src[i])) {
193118
- i++;
193119
- continue;
193120
- }
193121
- const pos2 = i;
193122
- if (src[i] === "@") {
193123
- const m = src.slice(i).match(/^@([a-z_][a-z0-9_]*)/);
193124
- if (!m) throw new ParseError(`unexpected character '@'`, pos2, src);
193125
- tokens.push({ kind: "VAR", value: m[1], pos: pos2 });
193126
- i += m[0].length;
193127
- continue;
193128
- }
193129
- if (src[i] === '"' || src[i] === "'") {
193130
- const quote = src[i];
193131
- let s = "";
193132
- i++;
193133
- while (i < src.length && src[i] !== quote) {
193134
- if (src[i] === "\\" && i + 1 < src.length) {
193135
- i++;
193136
- const esc2 = { n: "\n", t: " ", r: "\r", "\\": "\\", "'": "'", '"': '"' };
193137
- s += esc2[src[i]] ?? src[i];
193138
- } else {
193139
- s += src[i];
193140
- }
193141
- i++;
193142
- }
193143
- if (i >= src.length) throw new ParseError("unterminated string literal", pos2, src);
193144
- i++;
193145
- tokens.push({ kind: "STR", value: s, pos: pos2 });
193146
- continue;
193147
- }
193148
- if (/[0-9]/.test(src[i])) {
193149
- const m = src.slice(i).match(/^[0-9]+(\.[0-9]+)?/);
193150
- tokens.push({ kind: "NUM", value: m[0], pos: pos2 });
193151
- i += m[0].length;
193152
- continue;
193153
- }
193154
- const two = src.slice(i, i + 2);
193155
- if (two === "==") {
193156
- tokens.push({ kind: "EQ", value: "==", pos: pos2 });
193157
- i += 2;
193158
- continue;
193159
- }
193160
- if (two === "!=") {
193161
- tokens.push({ kind: "NEQ", value: "!=", pos: pos2 });
193162
- i += 2;
193163
- continue;
193164
- }
193165
- if (two === "<>") {
193166
- tokens.push({ kind: "NEQ", value: "<>", pos: pos2 });
193167
- i += 2;
193168
- continue;
193169
- }
193170
- if (src[i] === "=" && src[i + 1] !== "=") {
193171
- tokens.push({ kind: "EQ", value: "=", pos: pos2 });
193172
- i++;
193173
- continue;
193174
- }
193175
- if (two === ">=") {
193176
- tokens.push({ kind: "GTE", value: ">=", pos: pos2 });
193177
- i += 2;
193178
- continue;
193179
- }
193180
- if (two === "<=") {
193181
- tokens.push({ kind: "LTE", value: "<=", pos: pos2 });
193182
- i += 2;
193183
- continue;
193184
- }
193185
- if (two === "&&") {
193186
- tokens.push({ kind: "AND", value: "&&", pos: pos2 });
193187
- i += 2;
193188
- continue;
193189
- }
193190
- if (two === "||") {
193191
- tokens.push({ kind: "OR", value: "||", pos: pos2 });
193192
- i += 2;
193193
- continue;
193194
- }
193195
- const ch = src[i];
193196
- if (ch === ">") {
193197
- tokens.push({ kind: "GT", value: ">", pos: pos2 });
193198
- i++;
193199
- continue;
193200
- }
193201
- if (ch === "<") {
193202
- tokens.push({ kind: "LT", value: "<", pos: pos2 });
193203
- i++;
193204
- continue;
193205
- }
193206
- if (ch === "+") {
193207
- tokens.push({ kind: "PLUS", value: "+", pos: pos2 });
193208
- i++;
193209
- continue;
193210
- }
193211
- if (ch === "-") {
193212
- tokens.push({ kind: "MINUS", value: "-", pos: pos2 });
193213
- i++;
193214
- continue;
193215
- }
193216
- if (ch === "*") {
193217
- tokens.push({ kind: "STAR", value: "*", pos: pos2 });
193218
- i++;
193219
- continue;
193220
- }
193221
- if (ch === "/") {
193222
- tokens.push({ kind: "SLASH", value: "/", pos: pos2 });
193223
- i++;
193224
- continue;
193225
- }
193226
- if (ch === "(") {
193227
- tokens.push({ kind: "LPAREN", value: "(", pos: pos2 });
193228
- i++;
193229
- continue;
193230
- }
193231
- if (ch === ")") {
193232
- tokens.push({ kind: "RPAREN", value: ")", pos: pos2 });
193233
- i++;
193234
- continue;
193235
- }
193236
- if (ch === ",") {
193237
- tokens.push({ kind: "COMMA", value: ",", pos: pos2 });
193238
- i++;
193239
- continue;
193240
- }
193241
- if (ch === ".") {
193242
- tokens.push({ kind: "DOT", value: ".", pos: pos2 });
193243
- i++;
193244
- continue;
193245
- }
193246
- if (ch === "!") {
193247
- tokens.push({ kind: "NOT", value: "!", pos: pos2 });
193248
- i++;
193249
- continue;
193250
- }
193251
- if (/[a-zA-Z_]/.test(ch)) {
193252
- const m = src.slice(i).match(/^[a-zA-Z_][a-zA-Z0-9_]*/);
193253
- const word = m[0];
193254
- const kw = KEYWORDS[word];
193255
- tokens.push({ kind: kw ?? "IDENT", value: word, pos: pos2 });
193256
- i += word.length;
193257
- continue;
193258
- }
193259
- throw new ParseError(`unexpected character '${ch}'`, pos2, src);
193260
- }
193261
- tokens.push({ kind: "EOF", value: "", pos: i });
193262
- return tokens;
193263
- }
193264
- var Parser = class {
193265
- constructor(tokens, src, dialect) {
193266
- this.tokens = tokens;
193267
- this.src = src;
193268
- this.scopes = new Set(dialect.scopes.map((s) => s.token));
193269
- this.defaultScope = dialect.defaultScope;
193270
- this.flagDeltaFns = new Set(
193271
- Object.entries(dialect.functions).filter(([, def]) => def.flagDeltaArgs).map(([name]) => name)
193272
- );
193273
- }
193274
- tokens;
193275
- src;
193276
- pos = 0;
193277
- scopes;
193278
- defaultScope;
193279
- flagDeltaFns;
193280
- peek() {
193281
- return this.tokens[this.pos];
193282
- }
193283
- advance() {
193284
- return this.tokens[this.pos++];
193285
- }
193286
- check(kind) {
193287
- return this.peek().kind === kind;
193288
- }
193289
- expect(kind) {
193290
- if (!this.check(kind)) {
193291
- const tok = this.peek();
193292
- throw new ParseError(`expected ${kind}, got '${tok.value}'`, tok.pos, this.src);
193293
- }
193294
- return this.advance();
193295
- }
193296
- parse() {
193297
- const node = this.parseOr();
193298
- if (!this.check("EOF")) {
193299
- const tok = this.peek();
193300
- throw new ParseError(`unexpected token '${tok.value}'`, tok.pos, this.src);
193301
- }
193302
- return node;
193303
- }
193304
- parseOr() {
193305
- let left = this.parseAnd();
193306
- while (this.check("OR")) {
193307
- this.advance();
193308
- const right = this.parseAnd();
193309
- left = { kind: "binary", op: "or", left, right };
193310
- }
193311
- return left;
193312
- }
193313
- parseAnd() {
193314
- let left = this.parseNot();
193315
- while (this.check("AND")) {
193316
- this.advance();
193317
- const right = this.parseNot();
193318
- left = { kind: "binary", op: "and", left, right };
193319
- }
193320
- return left;
193321
- }
193322
- parseNot() {
193323
- if (this.check("NOT")) {
193324
- this.advance();
193325
- const operand = this.parseNot();
193326
- return { kind: "unary", op: "not", operand };
193327
- }
193328
- return this.parseComparison();
193329
- }
193330
- parseComparison() {
193331
- const left = this.parseAdditive();
193332
- const opMap = {
193333
- EQ: "==",
193334
- NEQ: "!=",
193335
- GT: ">",
193336
- GTE: ">=",
193337
- LT: "<",
193338
- LTE: "<="
193339
- };
193340
- const op = opMap[this.peek().kind];
193341
- if (op !== void 0) {
193342
- this.advance();
193343
- const right = this.parseAdditive();
193344
- return { kind: "binary", op, left, right };
193345
- }
193346
- return left;
193347
- }
193348
- parseAdditive() {
193349
- let left = this.parseMultiplicative();
193350
- while (this.check("PLUS") || this.check("MINUS")) {
193351
- const op = this.advance().kind === "PLUS" ? "+" : "-";
193352
- const right = this.parseMultiplicative();
193353
- left = { kind: "binary", op, left, right };
193354
- }
193355
- return left;
193356
- }
193357
- parseMultiplicative() {
193358
- let left = this.parseUnaryMinus();
193359
- while (this.check("STAR") || this.check("SLASH")) {
193360
- const op = this.advance().kind === "STAR" ? "*" : "/";
193361
- const right = this.parseUnaryMinus();
193362
- left = { kind: "binary", op, left, right };
193363
- }
193364
- return left;
193365
- }
193366
- parseUnaryMinus() {
193367
- if (this.check("MINUS")) {
193368
- this.advance();
193369
- const operand = this.parseUnaryMinus();
193370
- if (operand.kind === "number") return { kind: "number", value: -operand.value };
193371
- return { kind: "unary", op: "neg", operand };
193372
- }
193373
- return this.parsePrimary();
193374
- }
193375
- // Scope-qualified property ref: <scope>.<name> (after a VAR or IDENT token).
193376
- maybeScopedVar(name) {
193377
- if (this.scopes.has(name) && this.check("DOT")) {
193378
- this.advance();
193379
- const propTok = this.peek();
193380
- if (propTok.kind !== "IDENT") {
193381
- throw new ParseError(
193382
- `expected a property name after '${name}.', got '${propTok.value}'`,
193383
- propTok.pos,
193384
- this.src
193385
- );
193386
- }
193387
- this.advance();
193388
- return { kind: "scopedvar", scope: name, name: propTok.value.toLowerCase() };
193389
- }
193390
- return null;
193391
- }
193392
- parsePrimary() {
193393
- const tok = this.peek();
193394
- if (tok.kind === "BOOL") {
193395
- this.advance();
193396
- return { kind: "bool", value: tok.value === "true" };
193397
- }
193398
- if (tok.kind === "NUM") {
193399
- this.advance();
193400
- return { kind: "number", value: Number(tok.value) };
193401
- }
193402
- if (tok.kind === "STR") {
193403
- this.advance();
193404
- return { kind: "string", value: tok.value };
193405
- }
193406
- if (tok.kind === "VAR") {
193407
- const name = tok.value;
193408
- this.advance();
193409
- const scoped = this.maybeScopedVar(name);
193410
- if (scoped) return scoped;
193411
- return { kind: "scopedvar", scope: this.defaultScope, name: name.toLowerCase() };
193412
- }
193413
- if (tok.kind === "IDENT") {
193414
- const name = tok.value;
193415
- this.advance();
193416
- const scoped = this.maybeScopedVar(name);
193417
- if (scoped) return scoped;
193418
- if (this.check("LPAREN")) {
193419
- this.advance();
193420
- const args = [];
193421
- if (!this.check("RPAREN")) {
193422
- args.push(this.parseOr());
193423
- while (this.check("COMMA")) {
193424
- this.advance();
193425
- const wantsFlagDelta = this.flagDeltaFns.has(name) && args.length >= 1;
193426
- if (wantsFlagDelta) {
193427
- const sign2 = this.check("PLUS") ? "+" : this.check("MINUS") ? "-" : null;
193428
- if (sign2 === null) {
193429
- const t = this.peek();
193430
- throw new ParseError(
193431
- `${name}: expected +flagName or -flagName, got '${t.value}'`,
193432
- t.pos,
193433
- this.src
193434
- );
193435
- }
193436
- this.advance();
193437
- const flagTok = this.peek();
193438
- if (flagTok.kind !== "IDENT") {
193439
- throw new ParseError(
193440
- `${name}: expected a flag name after '${sign2}', got '${flagTok.value}'`,
193441
- flagTok.pos,
193442
- this.src
193443
- );
193444
- }
193445
- this.advance();
193446
- args.push({ kind: "flagdelta", sign: sign2, name: flagTok.value });
193447
- } else {
193448
- args.push(this.parseOr());
193449
- }
193450
- }
193451
- }
193452
- this.expect("RPAREN");
193453
- return { kind: "call", name, args };
193454
- }
193455
- return { kind: "string", value: name };
193456
- }
193457
- if (tok.kind === "LPAREN") {
193458
- this.advance();
193459
- const inner = this.parseOr();
193460
- this.expect("RPAREN");
193461
- return inner;
193462
- }
193463
- if (tok.kind === "EOF") {
193464
- throw new ParseError("expression is incomplete - expected a value", tok.pos, this.src);
193465
- }
193466
- throw new ParseError(`unexpected token '${tok.value}'`, tok.pos, this.src);
193467
- }
193468
- };
193469
- function parse3(source2, dialect) {
193470
- const tokens = tokenise(source2);
193471
- return new Parser(tokens, source2, dialect).parse();
193472
- }
193473
-
193474
- // ../../../expr/packages/expr/src/ast.ts
193475
- function serialiseAst(node) {
193476
- switch (node.kind) {
193477
- case "bool":
193478
- return ["b", node.value];
193479
- case "number":
193480
- return ["n", node.value];
193481
- case "string":
193482
- return ["s", node.value];
193483
- case "scopedvar":
193484
- return ["sv", node.scope, node.name];
193485
- case "unary":
193486
- return ["u", node.op, serialiseAst(node.operand)];
193487
- case "binary":
193488
- return ["bin", node.op, serialiseAst(node.left), serialiseAst(node.right)];
193489
- case "call":
193490
- return ["call", node.name, ...node.args.map(serialiseAst)];
193491
- case "flagdelta":
193492
- return ["fd", node.sign, node.name];
193493
- }
193494
- }
193495
- function deserialiseAst(node) {
193496
- switch (node[0]) {
193497
- case "b":
193498
- return { kind: "bool", value: node[1] };
193499
- case "n":
193500
- return { kind: "number", value: node[1] };
193501
- case "s":
193502
- return { kind: "string", value: node[1] };
193503
- case "sv":
193504
- return { kind: "scopedvar", scope: node[1], name: node[2] };
193505
- case "u":
193506
- return { kind: "unary", op: node[1], operand: deserialiseAst(node[2]) };
193507
- case "bin":
193508
- return { kind: "binary", op: node[1], left: deserialiseAst(node[2]), right: deserialiseAst(node[3]) };
193509
- case "call": {
193510
- const args = node.slice(2).map(deserialiseAst);
193511
- return { kind: "call", name: node[1], args };
193512
- }
193513
- case "fd":
193514
- return { kind: "flagdelta", sign: node[1], name: node[2] };
193515
- }
193516
- }
193517
-
193518
- // ../../../expr/packages/expr/src/evaluate.ts
193519
- var EvalError2 = class extends Error {
193520
- constructor(message) {
193521
- super(message);
193522
- this.name = "EvalError";
193523
- }
193524
- };
193525
- function evaluate(node, ctx, dialect) {
193526
- const missingPolicy = new Map(
193527
- dialect.scopes.map((s) => [s.token, s.missing ?? "false"])
193528
- );
193529
- const rec = (n) => {
193530
- switch (n.kind) {
193531
- case "bool":
193532
- return n.value;
193533
- case "number":
193534
- return n.value;
193535
- case "string":
193536
- return n.value;
193537
- case "scopedvar": {
193538
- const scope = ctx.scopes[n.scope];
193539
- if (scope === void 0) {
193540
- return false;
193541
- }
193542
- const val = typeof scope.get === "function" ? scope.get(n.name) : scope[n.name];
193543
- if (val === void 0) {
193544
- if (missingPolicy.get(n.scope) === "throw") {
193545
- throw new EvalError2(`@${n.scope}.${n.name} is not declared on the current ${n.scope}.`);
193546
- }
193547
- return false;
193548
- }
193549
- return val;
193550
- }
193551
- case "call": {
193552
- if (n.name === "advance" && !dialect.functions[n.name]) {
193553
- const arg = n.args[0];
193554
- if (n.args.length !== 1 || arg === void 0) {
193555
- throw new EvalError2(`advance() takes exactly 1 argument, got ${n.args.length}`);
193556
- }
193557
- const ladder = ladderOf(arg, ctx);
193558
- if (ladder === void 0) {
193559
- throw new EvalError2("advance() needs a quality reference (@scope.name of a quality property)");
193560
- }
193561
- const current = stageIndex(rec(arg), ladder, "advance");
193562
- return ladder[Math.min(current + 1, ladder.length - 1)];
193563
- }
193564
- const def = dialect.functions[n.name];
193565
- if (!def) throw new EvalError2(`unknown function '${n.name}'`);
193566
- return def.eval(n.args, { evaluate: rec, ctx });
193567
- }
193568
- case "flagdelta":
193569
- throw new EvalError2("flagdelta node is only valid as an argument to a flag-delta function");
193570
- case "unary": {
193571
- if (n.op === "not") {
193572
- const val2 = rec(n.operand);
193573
- if (typeof val2 !== "boolean") throw new EvalError2(`'not' requires a boolean operand, got ${typeof val2}`);
193574
- return !val2;
193575
- }
193576
- const val = rec(n.operand);
193577
- if (typeof val !== "number") throw new EvalError2(`unary '-' requires a numeric operand, got ${typeof val}`);
193578
- return -val;
193579
- }
193580
- case "binary": {
193581
- if (n.op === "and") {
193582
- const l2 = rec(n.left);
193583
- if (typeof l2 !== "boolean") throw new EvalError2(`'and' requires boolean operands, left is ${typeof l2}`);
193584
- if (!l2) return false;
193585
- const r = rec(n.right);
193586
- if (typeof r !== "boolean") throw new EvalError2(`'and' requires boolean operands, right is ${typeof r}`);
193587
- return r;
193588
- }
193589
- if (n.op === "or") {
193590
- const l2 = rec(n.left);
193591
- if (typeof l2 !== "boolean") throw new EvalError2(`'or' requires boolean operands, left is ${typeof l2}`);
193592
- if (l2) return true;
193593
- const r = rec(n.right);
193594
- if (typeof r !== "boolean") throw new EvalError2(`'or' requires boolean operands, right is ${typeof r}`);
193595
- return r;
193596
- }
193597
- const left = rec(n.left);
193598
- const right = rec(n.right);
193599
- const lLadder = ladderOf(n.left, ctx);
193600
- const rLadder = ladderOf(n.right, ctx);
193601
- const ladder = lLadder ?? rLadder;
193602
- if (ladder !== void 0) {
193603
- if (lLadder && rLadder && !sameLadder(lLadder, rLadder)) {
193604
- if (n.op === ">" || n.op === ">=" || n.op === "<" || n.op === "<=") {
193605
- throw new EvalError2(`'${n.op}' compares two different qualities, whose stage orders are unrelated`);
193606
- }
193607
- }
193608
- switch (n.op) {
193609
- case ">":
193610
- return stageIndex(left, ladder, ">") > stageIndex(right, ladder, ">");
193611
- case ">=":
193612
- return stageIndex(left, ladder, ">=") >= stageIndex(right, ladder, ">=");
193613
- case "<":
193614
- return stageIndex(left, ladder, "<") < stageIndex(right, ladder, "<");
193615
- case "<=":
193616
- return stageIndex(left, ladder, "<=") <= stageIndex(right, ladder, "<=");
193617
- case "+":
193618
- case "-":
193619
- case "*":
193620
- case "/":
193621
- throw new EvalError2(`'${n.op}' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);
193622
- default:
193623
- break;
193624
- }
193625
- }
193626
- switch (n.op) {
193627
- case "==":
193628
- return valueEquals(left, right);
193629
- case "!=":
193630
- return !valueEquals(left, right);
193631
- case ">":
193632
- assertNumbers(left, right, ">");
193633
- return left > right;
193634
- case ">=":
193635
- assertNumbers(left, right, ">=");
193636
- return left >= right;
193637
- case "<":
193638
- assertNumbers(left, right, "<");
193639
- return left < right;
193640
- case "<=":
193641
- assertNumbers(left, right, "<=");
193642
- return left <= right;
193643
- case "+":
193644
- if (typeof left === "number" && typeof right === "number") return left + right;
193645
- if (typeof left === "string" && typeof right === "string") return left + right;
193646
- throw new EvalError2(`'+' requires two numbers or two strings, got ${typeof left} and ${typeof right}`);
193647
- case "-":
193648
- assertNumbers(left, right, "-");
193649
- return left - right;
193650
- case "*":
193651
- assertNumbers(left, right, "*");
193652
- return left * right;
193653
- case "/":
193654
- assertNumbers(left, right, "/");
193655
- if (right === 0) throw new EvalError2("division by zero");
193656
- return left / right;
193657
- }
193658
- }
193659
- }
193660
- };
193661
- return rec(node);
193662
- }
193663
- function valueEquals(a, b) {
193664
- if (Array.isArray(a) || Array.isArray(b)) {
193665
- if (!Array.isArray(a) || !Array.isArray(b)) return false;
193666
- if (a.length !== b.length) return false;
193667
- for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
193668
- return true;
193669
- }
193670
- return a === b;
193671
- }
193672
- function assertNumbers(l2, r, op) {
193673
- if (typeof l2 !== "number" || typeof r !== "number") {
193674
- throw new EvalError2(`'${op}' requires numeric operands, got ${typeof l2} and ${typeof r}`);
193675
- }
193676
- }
193677
- function ladderOf(node, ctx) {
193678
- if (node.kind !== "scopedvar" || ctx.qualities === void 0) return void 0;
193679
- return ctx.qualities(node.scope, node.name);
193680
- }
193681
- function stageIndex(value, ladder, op) {
193682
- if (typeof value !== "string") {
193683
- throw new EvalError2(`'${op}' on a quality compares stages, got ${typeof value}`);
193684
- }
193685
- const i = ladder.indexOf(value);
193686
- if (i < 0) throw new EvalError2(`"${value}" is not a stage of this quality (stages: ${ladder.join(", ")})`);
193687
- return i;
193688
- }
193689
- var sameLadder = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]);
193690
-
193691
- // ../../../expr/packages/expr/src/validate.ts
193692
- function validateExpressionAst(node, schema, dialect) {
193693
- const issues = [];
193694
- walkValidate(node, schema, dialect, [], issues);
193695
- return finaliseResult(issues);
193696
- }
193697
- function validateExpr(node, schema, dialect) {
193698
- return validateExpressionAst(node, schema, dialect).issues;
193699
- }
193700
- function finaliseResult(issues) {
193701
- const hasError = issues.some((i) => i.severity === "error");
193702
- const summary = issues.map((i) => i.message).join("; ");
193703
- return { ok: !hasError, issues, summary };
193704
- }
193705
- function walkValidate(node, schema, dialect, path, issues) {
193706
- switch (node.kind) {
193707
- case "bool":
193708
- case "number":
193709
- case "string":
193710
- case "flagdelta":
193711
- return;
193712
- case "scopedvar": {
193713
- const scopeMap = schema.properties.get(node.scope);
193714
- if (scopeMap && !scopeMap.has(node.name)) {
193715
- const isDefault = node.scope === dialect.defaultScope;
193716
- issues.push({
193717
- path,
193718
- kind: isDefault ? "unresolved-property" : "unresolved-scoped-property",
193719
- severity: "error",
193720
- message: isDefault ? `unresolved property reference '@${node.name}'` : `unresolved ${node.scope} property reference '@${node.scope}.${node.name}'`,
193721
- reference: isDefault ? node.name : `${node.scope}.${node.name}`
193722
- });
193723
- }
193724
- return;
193725
- }
193726
- case "call": {
193727
- if (node.name === "advance" && !dialect.functions[node.name]) {
193728
- if (node.args.length !== 1) {
193729
- issues.push({ path, kind: "wrong-arg-count", severity: "error", message: `advance() takes exactly 1 argument, got ${node.args.length}` });
193730
- }
193731
- const arg = node.args[0];
193732
- if (arg) {
193733
- walkValidate(arg, schema, dialect, [...path, "args", 0], issues);
193734
- if (stagesOf(arg, schema) === void 0 && typeOf(arg, schema, dialect) !== "unknown") {
193735
- issues.push({
193736
- path: [...path, "args", 0],
193737
- kind: "wrong-arg-type",
193738
- severity: "error",
193739
- message: "advance() needs a quality reference (@scope.name of a quality property)"
193740
- });
193741
- }
193742
- }
193743
- return;
193744
- }
193745
- const def = dialect.functions[node.name];
193746
- if (!def) {
193747
- issues.push({ path, kind: "unknown-function", severity: "error", message: `unknown function '${node.name}'` });
193748
- return;
193749
- }
193750
- if (node.args.length < def.minArgs) {
193751
- issues.push({
193752
- path,
193753
- kind: "wrong-arg-count",
193754
- severity: "error",
193755
- message: `${node.name}() requires at least ${def.minArgs} argument(s), got ${node.args.length}`
193756
- });
193757
- }
193758
- if (def.maxArgs !== void 0 && node.args.length > def.maxArgs) {
193759
- issues.push({
193760
- path,
193761
- kind: "wrong-arg-count",
193762
- severity: "error",
193763
- message: `${node.name}() takes at most ${def.maxArgs} argument(s), got ${node.args.length}`
193764
- });
193765
- }
193766
- for (let i = 0; i < node.args.length; i++) {
193767
- walkValidate(node.args[i], schema, dialect, [...path, "args", i], issues);
193768
- }
193769
- if (def.validate) {
193770
- def.validate(node.args, {
193771
- schema,
193772
- path,
193773
- defaultScope: dialect.defaultScope,
193774
- report: (issue) => issues.push(issue)
193775
- });
193776
- }
193777
- return;
193778
- }
193779
- case "unary": {
193780
- walkValidate(node.operand, schema, dialect, [...path, "operand"], issues);
193781
- checkUnaryOperandType(node.op, node.operand, schema, dialect, [...path, "operand"], issues);
193782
- return;
193783
- }
193784
- case "binary": {
193785
- walkValidate(node.left, schema, dialect, [...path, "left"], issues);
193786
- walkValidate(node.right, schema, dialect, [...path, "right"], issues);
193787
- checkBinaryOperandTypes(node.op, node.left, node.right, schema, dialect, path, issues);
193788
- if (node.op === "/" && node.right.kind === "number" && node.right.value === 0) {
193789
- issues.push({
193790
- path: [...path, "right"],
193791
- kind: "division-by-zero",
193792
- severity: "error",
193793
- message: "division by zero - pick a non-zero divisor"
193794
- });
193795
- }
193796
- if (node.op === "==" || node.op === "!=") {
193797
- const left = node.left, right = node.right;
193798
- let propNode = null;
193799
- let strNode = null;
193800
- let strSide = null;
193801
- if (left.kind === "scopedvar" && right.kind === "string") {
193802
- propNode = left;
193803
- strNode = right;
193804
- strSide = "right";
193805
- } else if (right.kind === "scopedvar" && left.kind === "string") {
193806
- propNode = right;
193807
- strNode = left;
193808
- strSide = "left";
193809
- }
193810
- if (propNode && strNode && strSide) {
193811
- const meta = schema.properties.get(propNode.scope)?.get(propNode.name);
193812
- if (meta?.type === "enum" && meta.enumValues && !meta.enumValues.includes(strNode.value)) {
193813
- issues.push({
193814
- path: [...path, strSide],
193815
- kind: "unknown-enum-value",
193816
- severity: "error",
193817
- message: `'${strNode.value}' is not a valid value for this property - expected one of: ${meta.enumValues.join(", ")}`,
193818
- reference: strNode.value
193819
- });
193820
- }
193821
- }
193822
- }
193823
- return;
193824
- }
193825
- }
193826
- }
193827
- function inferredFromPropertyType(t) {
193828
- if (t === "boolean") return "boolean";
193829
- if (t === "number") return "number";
193830
- if (t === "string" || t === "enum") return "string";
193831
- if (t === "flags") return "flags";
193832
- if (t === "quality") return "quality";
193833
- return "unknown";
193834
- }
193835
- function inferredFromReturn(t) {
193836
- return t;
193837
- }
193838
- function stagesOf(node, schema) {
193839
- if (node.kind !== "scopedvar") return void 0;
193840
- const meta = schema.properties.get(node.scope)?.get(node.name);
193841
- return meta?.type === "quality" ? meta.stages : void 0;
193842
- }
193843
- function typeOf(node, schema, dialect) {
193844
- switch (node.kind) {
193845
- case "bool":
193846
- return "boolean";
193847
- case "number":
193848
- return "number";
193849
- case "string":
193850
- return "string";
193851
- case "flagdelta":
193852
- return "unknown";
193853
- case "scopedvar": {
193854
- const meta = schema.properties.get(node.scope)?.get(node.name);
193855
- return meta ? inferredFromPropertyType(meta.type) : "unknown";
193856
- }
193857
- case "call": {
193858
- if (node.name === "advance") return "quality";
193859
- const def = dialect.functions[node.name];
193860
- return def ? inferredFromReturn(def.returnType) : "unknown";
193861
- }
193862
- case "unary":
193863
- return node.op === "not" ? "boolean" : "number";
193864
- case "binary":
193865
- switch (node.op) {
193866
- case "+":
193867
- case "-":
193868
- case "*":
193869
- case "/":
193870
- return "number";
193871
- case "==":
193872
- case "!=":
193873
- case ">":
193874
- case "<":
193875
- case ">=":
193876
- case "<=":
193877
- case "and":
193878
- case "or":
193879
- return "boolean";
193880
- }
193881
- }
193882
- }
193883
- function describeType(t) {
193884
- return t === "unknown" ? "unknown type" : t;
193885
- }
193886
- function checkBinaryOperandTypes(op, left, right, schema, dialect, path, issues) {
193887
- const lt = typeOf(left, schema, dialect);
193888
- const rt = typeOf(right, schema, dialect);
193889
- const ordering = op === ">" || op === "<" || op === ">=" || op === "<=";
193890
- if (lt === "quality" || rt === "quality") {
193891
- if (ordering || op === "==" || op === "!=") {
193892
- const ls = stagesOf(left, schema);
193893
- const rs = stagesOf(right, schema);
193894
- if (ls && rs) {
193895
- if (ls.join("\0") !== rs.join("\0")) {
193896
- issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `'${op}' compares two different qualities, whose stages are unrelated` });
193897
- }
193898
- return;
193899
- }
193900
- const ladder = ls ?? rs;
193901
- const other = ls ? right : left;
193902
- const otherSide = ls ? "right" : "left";
193903
- if (other.kind === "string") {
193904
- if (ladder && !ladder.includes(other.value)) {
193905
- issues.push({
193906
- path: [...path, otherSide],
193907
- kind: "unknown-stage",
193908
- severity: "error",
193909
- message: `'${other.value}' is not a stage of this quality - expected one of: ${ladder.join(", ")}`,
193910
- reference: other.value
193911
- });
193912
- }
193913
- return;
193914
- }
193915
- const ot = ls ? rt : lt;
193916
- if (ot !== "unknown" && ot !== "quality") {
193917
- issues.push({
193918
- path: [...path, otherSide],
193919
- kind: "operand-type-mismatch",
193920
- severity: "error",
193921
- message: `'${op}' on a quality compares stages, got ${describeType(ot)} on the ${otherSide}`
193922
- });
193923
- }
193924
- return;
193925
- }
193926
- if (op === "+" || op === "-" || op === "*" || op === "/") {
193927
- issues.push({
193928
- path,
193929
- kind: "operand-type-mismatch",
193930
- severity: "error",
193931
- message: `'${op}' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`
193932
- });
193933
- return;
193934
- }
193935
- }
193936
- if (op === "+" || op === "-" || op === "*" || op === "/" || ordering) {
193937
- if (lt !== "unknown" && lt !== "number")
193938
- issues.push({ path: [...path, "left"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a number on the left, got ${describeType(lt)}` });
193939
- if (rt !== "unknown" && rt !== "number")
193940
- issues.push({ path: [...path, "right"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a number on the right, got ${describeType(rt)}` });
193941
- return;
193942
- }
193943
- if (op === "and" || op === "or") {
193944
- if (lt !== "unknown" && lt !== "boolean")
193945
- issues.push({ path: [...path, "left"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a boolean on the left, got ${describeType(lt)}` });
193946
- if (rt !== "unknown" && rt !== "boolean")
193947
- issues.push({ path: [...path, "right"], kind: "operand-type-mismatch", severity: "error", message: `'${op}' requires a boolean on the right, got ${describeType(rt)}` });
193948
- return;
193949
- }
193950
- if (op === "==" || op === "!=") {
193951
- if (lt !== "unknown" && rt !== "unknown" && lt !== rt)
193952
- issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `'${op}' compares ${describeType(lt)} with ${describeType(rt)}; the values can never be equal` });
193953
- }
193954
- }
193955
- function checkUnaryOperandType(op, operand, schema, dialect, path, issues) {
193956
- const t = typeOf(operand, schema, dialect);
193957
- if (t === "unknown") return;
193958
- if (op === "not" && t !== "boolean")
193959
- issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `'not' requires a boolean operand, got ${describeType(t)}` });
193960
- if (op === "neg" && t !== "number")
193961
- issues.push({ path, kind: "operand-type-mismatch", severity: "error", message: `unary '-' requires a number, got ${describeType(t)}` });
193962
- }
193963
-
193964
- // ../../../expr/packages/expr/src/index.ts
193965
- function compile(src, dialect) {
193966
- return { src, ast: serialiseAst(parse3(src, dialect)) };
193967
- }
193968
-
193969
194042
  // ../dialect/src/index.ts
193970
194043
  function host(h) {
193971
194044
  return h.ctx.host ?? {};
@@ -194279,7 +194352,7 @@ function stripCaptions(text, open, close) {
194279
194352
  }
194280
194353
  return removed ? collapseCaptionWs(out) : text;
194281
194354
  }
194282
- function interpolate(text, resolve6) {
194355
+ function interpolate(text, resolve7) {
194283
194356
  if (text.indexOf("{") < 0) return text;
194284
194357
  let out = "";
194285
194358
  for (const tok of tokenise2(text)) {
@@ -194291,7 +194364,7 @@ function interpolate(text, resolve6) {
194291
194364
  out += tok.raw;
194292
194365
  continue;
194293
194366
  }
194294
- const v = resolve6(tok.ref);
194367
+ const v = resolve7(tok.ref);
194295
194368
  out += v === void 0 ? "" : renderSlotValue(v);
194296
194369
  }
194297
194370
  return out;
@@ -194637,50 +194710,8 @@ var shown = (key2) => {
194637
194710
  const at = bare.indexOf(":");
194638
194711
  return at < 0 ? bare : `${bare.slice(0, at)} +${bare.slice(at + 1)}`;
194639
194712
  };
194640
- var svRef = (ast) => Array.isArray(ast) && ast[0] === "sv" ? `@${String(ast[1])}.${String(ast[2])}` : void 0;
194641
- function latchOf(ast, sceneId) {
194642
- const direct = svRef(ast);
194643
- if (direct !== void 0) return keyOf(direct, sceneId);
194644
- if (!Array.isArray(ast)) return void 0;
194645
- if (ast[0] === "bin" && ast[1] === "==") {
194646
- const [, , l2, r] = ast;
194647
- for (const [a, b] of [[l2, r], [r, l2]]) {
194648
- const ref = svRef(a);
194649
- if (ref !== void 0 && Array.isArray(b) && b[0] === "b" && b[1] === true) return keyOf(ref, sceneId);
194650
- }
194651
- return void 0;
194652
- }
194653
- if (ast[0] === "call" && ast[1] === "check_flags") {
194654
- const ref = svRef(ast[2]);
194655
- const args = ast.slice(3);
194656
- if (ref === void 0 || args.length !== 1) return void 0;
194657
- const arg = args[0];
194658
- if (Array.isArray(arg) && arg[0] === "fd" && arg[1] === "+") return `${keyOf(ref, sceneId)}:${String(arg[2])}`;
194659
- }
194660
- return void 0;
194661
- }
194662
- function disjuncts(ast) {
194663
- if (Array.isArray(ast) && ast[0] === "bin" && ast[1] === "or") {
194664
- const [, , l2, r] = ast;
194665
- return [...disjuncts(l2), ...disjuncts(r)];
194666
- }
194667
- return [ast];
194668
- }
194669
- function terms(ast, sceneId, negated = false, into = []) {
194670
- const latch = latchOf(ast, sceneId);
194671
- if (latch !== void 0) {
194672
- into.push({ key: latch, negated });
194673
- return into;
194674
- }
194675
- if (!Array.isArray(ast)) return into;
194676
- if (ast[0] === "u" && ast[1] === "not") return terms(ast[2], sceneId, !negated, into);
194677
- if (ast[0] === "bin" && ast[1] === "and" && !negated) {
194678
- terms(ast[2], sceneId, false, into);
194679
- terms(ast[3], sceneId, false, into);
194680
- }
194681
- return into;
194682
- }
194683
- var requirementsOf = (expr, sceneId) => expr === void 0 ? [] : terms(expr.ast, sceneId);
194713
+ var termsOfAst = (ast, sceneId) => terms(ast, sceneId, keyOf);
194714
+ var requirementsOf = (expr, sceneId) => expr === void 0 ? [] : termsOfAst(expr.ast, sceneId);
194684
194715
  var asFlags = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
194685
194716
  function reachabilityIssues(loaded, compiled) {
194686
194717
  const bundle = compiled ?? exportBundle({ project: loaded.project, scenes: loaded.scenes, locales: loaded.locales });
@@ -194719,7 +194750,7 @@ function reachabilityIssues(loaded, compiled) {
194719
194750
  noteWrite(key2, need);
194720
194751
  continue;
194721
194752
  }
194722
- if (Array.isArray(ast) && ast[0] === "call" && ast[1] === "set_flags" && svRef(ast[2]) === ref) {
194753
+ if (Array.isArray(ast) && ast[0] === "call" && ast[1] === "set_flags" && scopedRef(ast[2]) === ref) {
194723
194754
  let clean3 = true;
194724
194755
  for (const arg of ast.slice(3)) {
194725
194756
  if (Array.isArray(arg) && arg[0] === "fd" && arg[1] === "+") noteWrite(`${key2}:${String(arg[2])}`, need);
@@ -194800,7 +194831,7 @@ function reachabilityIssues(loaded, compiled) {
194800
194831
  const branches = own ? disjuncts(own.ast) : [void 0];
194801
194832
  let reason;
194802
194833
  const refuted = branches.every((b) => {
194803
- const r = refute([...gate, ...b ? terms(b, sceneId) : []]);
194834
+ const r = refute([...gate, ...b ? termsOfAst(b, sceneId) : []]);
194804
194835
  reason ??= r;
194805
194836
  return r !== void 0;
194806
194837
  });
@@ -194978,7 +195009,7 @@ function bundleOutputPath(loaded) {
194978
195009
  }
194979
195010
 
194980
195011
  // ../ops/src/playable-runtime.ts
194981
- var PLAYABLE_RUNTIME_JS = '"use strict";var Patterplay=(()=>{var G=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var ye=Object.getOwnPropertyNames;var ve=Object.prototype.hasOwnProperty;var be=(n,e)=>{for(var t in e)G(n,t,{get:e[t],enumerable:!0})},we=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ye(e))!ve.call(n,s)&&s!==t&&G(n,s,{get:()=>e[s],enumerable:!(r=Se(e,s))||r.enumerable});return n};var xe=n=>we(G({},"__esModule",{value:!0}),n);var Me={};be(Me,{Engine:()=>N,Flow:()=>k,buildTagIndex:()=>P,describeBundle:()=>ue,effectiveGameData:()=>fe,gameDataFields:()=>ge,gameDataValue:()=>U});function v(n){switch(n[0]){case"b":return{kind:"bool",value:n[1]};case"n":return{kind:"number",value:n[1]};case"s":return{kind:"string",value:n[1]};case"sv":return{kind:"scopedvar",scope:n[1],name:n[2]};case"u":return{kind:"unary",op:n[1],operand:v(n[2])};case"bin":return{kind:"binary",op:n[1],left:v(n[2]),right:v(n[3])};case"call":{let e=n.slice(2).map(v);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var l=class extends Error{constructor(e){super(e),this.name="EvalError"}};function D(n,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=e.scopes[i.scope];if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):o[i.name];if(a===void 0){if(r.get(i.scope)==="throw")throw new l(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!t.functions[i.name]){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new l(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=T(a,e);if(c===void 0)throw new l("advance() needs a quality reference (@scope.name of a quality property)");let d=S(s(a),c,"advance");return c[Math.min(d+1,c.length-1)]}let o=t.functions[i.name];if(!o)throw new l(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new l("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new l(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new l(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let g=s(i.left);if(typeof g!="boolean")throw new l(`\'and\' requires boolean operands, left is ${typeof g}`);if(!g)return!1;let h=s(i.right);if(typeof h!="boolean")throw new l(`\'and\' requires boolean operands, right is ${typeof h}`);return h}if(i.op==="or"){let g=s(i.left);if(typeof g!="boolean")throw new l(`\'or\' requires boolean operands, left is ${typeof g}`);if(g)return!0;let h=s(i.right);if(typeof h!="boolean")throw new l(`\'or\' requires boolean operands, right is ${typeof h}`);return h}let o=s(i.left),a=s(i.right),c=T(i.left,e),d=T(i.right,e),p=c??d;if(p!==void 0){if(c&&d&&!ke(c,d)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new l(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return S(o,p,">")>S(a,p,">");case">=":return S(o,p,">=")>=S(a,p,">=");case"<":return S(o,p,"<")<S(a,p,"<");case"<=":return S(o,p,"<=")<=S(a,p,"<=");case"+":case"-":case"*":case"/":throw new l(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return X(o,a);case"!=":return!X(o,a);case">":return b(o,a,">"),o>a;case">=":return b(o,a,">="),o>=a;case"<":return b(o,a,"<"),o<a;case"<=":return b(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new l(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return b(o,a,"-"),o-a;case"*":return b(o,a,"*"),o*a;case"/":if(b(o,a,"/"),a===0)throw new l("division by zero");return o/a}}}};return s(n)}function X(n,e){if(Array.isArray(n)||Array.isArray(e)){if(!Array.isArray(n)||!Array.isArray(e)||n.length!==e.length)return!1;for(let t=0;t<n.length;t++)if(n[t]!==e[t])return!1;return!0}return n===e}function b(n,e,t){if(typeof n!="number"||typeof e!="number")throw new l(`\'${t}\' requires numeric operands, got ${typeof n} and ${typeof e}`)}function T(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function S(n,e,t){if(typeof n!="string")throw new l(`\'${t}\' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new l(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var ke=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);var Ce={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Ee=[Ce];function Y(n,e,t){let r=t?.countingCalls??Ee;return I(n,t?.want??!0,e,r)}function I(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=I(n.left,e,t,r),i=I(n.right,e,t,r);return n.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(n.kind==="unary"&&n.op==="not")return I(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(i=>i.name===n.name);if(s){let i=s.count(n),o=t(n);return e?o?i:0:o?0:1}}return t(n)===e?1:0}var M=class n{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.seed(e)}seed(e){for(let t of e){let r=this.norm(t.name);this.decls.set(r,t),this.values[r]=structuredClone(t.default??Q(t))}}get(e){return this.values[this.norm(e)]}set(e,t,r){let s=this.norm(e);if(this.decls.get(s)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=t;for(let o of this.auditors)o(i);if(!i.silent)for(let o of this.subscribers)o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>Z(t,this.get(e),void 0,e))}declarations(){return[...this.decls.values()]}clone(){let e=new n([],{normalise:this.norm});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e){for(let[t,r]of Object.entries(e))this.values[this.norm(t)]=r}};function Z(n,e,t,r){return{name:r??n.name.toLowerCase(),type:n.type,value:e,default:n.default??Q(n),...n.values!==void 0?{values:n.values}:{},writable:t??n.writable??!0}}var V=1,C=class{scopes=new Map;defineOwned(e,t){return this.mountOwned(e,new M(t))}mountOwned(e,t){return this.assertFree(e),this.scopes.set(e,{kind:"owned",bag:t}),this}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,r=[],s=!0){this.assertFree(e);let i=new Map;for(let o of r)i.set(o.name.toLowerCase(),o);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:i,scopeWritable:s}),this}has(e){return this.scopes.has(e)}get(e,t){let r=this.scopes.get(e);if(r)return r.kind==="owned"?r.bag.get(t):r.resolver.get(t.toLowerCase())}set(e,t,r){let s=this.scopes.get(e);if(!s)throw new Error(`unknown scope \'@${e}\'`);if(s.kind==="owned"){try{s.bag.set(t,r)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let i=t.toLowerCase();if(!this.foreignWritable(s,i))throw new Error(`\'@${e}.${t}\' is read-only`);s.resolver.set(i,r)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,r]of this.scopes)if(r.kind==="owned")for(let s of r.bag.rows())e.push({scope:t,...s});else for(let s of r.decls.values())e.push({scope:t,...Z(s,r.resolver.get(s.name.toLowerCase()),this.foreignWritable(r,s.name.toLowerCase()))});return e}toEvalContext(e){let t={};for(let[s,i]of this.scopes)t[s]=i.kind==="owned"?i.bag.values:i.resolver;let r=this.qualityLadders();return r.size===0?{scopes:t,host:e}:{scopes:t,host:e,qualities:(s,i)=>r.get(s)?.get(i.toLowerCase())}}qualityLadders(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];for(let i of s){if(i.type!=="quality"||i.stages===void 0)continue;let o=e.get(t);o||(o=new Map,e.set(t,o)),o.set(i.name.toLowerCase(),i.stages)}}return e}toSchema(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];if(s.length===0)continue;let i=new Map;for(let o of s)i.set(o.name.toLowerCase(),{type:o.type,enumValues:o.values,...o.stages!==void 0?{stages:o.stages}:{}});e.set(t,i)}return{properties:e}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]=r.bag.save());return e}load(e){for(let[t,r]of Object.entries(e)){let s=this.scopes.get(t);s?.kind==="owned"&&s.bag.load(r)}}saveFragment(){return{version:V,scopes:this.save()}}loadFragment(e){if(e.version!==V)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${V})`);this.load(e.scopes)}assertFree(e){if(this.scopes.has(e))throw new Error(`scope \'@${e}\' is already registered`)}};function Q(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return n.values?.[0]??"";case"flags":return[];case"quality":return n.stages?.[0]??""}}function E(n){return n.ctx.host??{}}var L={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new l("random(a, b) requires exactly 2 arguments");let t=E(e).nextRandom;if(!t)throw new l("random() called without a PRNG in context");let r=e.evaluate(n[0]),s=e.evaluate(n[1]);if(typeof r!="number"||typeof s!="number")throw new l("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new l("random(a, b) arguments must be integers");let i=Math.min(r,s),o=Math.max(r,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:te("check_flags"),eval(n,e){let t=ee(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:te("set_flags"),eval(n,e){let t=[...ee(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:B("visits"),eval:(n,e)=>E(e).visits?.(R(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:B("seen"),eval:(n,e)=>(E(e).visits?.(R(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:B("patter_visits"),eval:(n,e)=>E(e).patterVisits?.(R(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:B("patter_seen"),eval:(n,e)=>(E(e).patterVisits?.(R(n,e,"patter_seen"))??0)>0}}};function j(n,e){let t=n.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function R(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new l(`${t}(id) requires a string node id`);return r}function B(n){return(e,t)=>{let r=e[0];r&&r.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(id): the argument must be a string id literal (a scene / block / node id)`})}}function ee(n,e,t){if(!n)throw new l(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(n);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new l(`${t}() first argument must be a flags property`)}function te(n){return(e,t)=>{if(e.length===0)return;let r=e[0];if(r.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(r.scope)?.get(r.name);if(s&&s.type!=="flags"){let i=r.scope===t.defaultScope?r.name:`${r.scope}.${r.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): \'@${i}\' is not a flags property (got ${s.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${n}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var De=/^@[A-Za-z0-9_.]+$/;function*Ie(n){let e="",t=0;for(;t<n.length;){let r=n[t];if(r==="{"&&n[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&n[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let s=n.indexOf("}",t+1);if(s!==-1){let i=n.slice(t,s+1),o=n.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:De.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function Re(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function Be(n){return n===" "||n===" "||n===`\n`||n==="\\r"||n==="\\f"||n==="\\v"}function Oe(n){let e="",t=!1;for(let r of n){if(Be(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function re(n,e,t){if(e.length===0||n.indexOf(e)<0)return n;let r="",s=0,i=!1;for(;s<n.length;){if(n.startsWith(e,s)){let o=n.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return i?Oe(r):n}function ne(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of Ie(n)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let s=e(r.ref);t+=s===void 0?"":Re(s)}return t}function x(n,e){for(let t of n){e(t);let r=t.children;r&&x(r,e)}}function Pe(n){return n.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function f(n){let e=n.gameId?.trim();return e||Pe(n.name)}function $(n){return`cast:${n}`}var _={open:"[",close:"]"},se="SFX";function O(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function P(n){let e=new Map,t=(r,s)=>{let i=O([...s,...r.tags??[]]);if(e.set(r.id,i),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,O([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=O(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=O([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var ie=new WeakMap,N=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,s=e.strings;this.allStrings=s,this.currentLocale=r;let i=s[r]??{},o=s[e.locales.default]??{},a=e.localisation,c=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let d=new Map;for(let u of e.cast??[])u.displayName&&d.set(u.name,u.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let p=new Map,g=new Map,h=new Map;for(let[u,y]of Object.entries(e.scenes)){this.sceneGameIdToId.set(f(y),u);let w=new Map;for(let m of y.blocks)g.set(m.id,{sceneId:u}),h.set(m.id,m),w.set(f(m),m.id),x(m.children,J=>p.set(J.id,J));this.blockGameIdToId.set(u,w)}let W=e.properties??[],A=W.filter(u=>u.shared??!0).map(ae),he=W.filter(u=>!(u.shared??!0)).map(ae),me=new Set(A.map(u=>u.name.toLowerCase())),F=new C().defineOwned("patter",A),K=new Set;if(t.world){let u=e.scopeRegistry?.scopes.find(w=>w.token==="world"),y=(u?.declarations??[]).map(ce);F.defineForeign("world",t.world,y,u?.writable??!0),K.add("world")}for(let u of e.scopeRegistry?.scopes??[]){if(K.has(u.token))continue;let y=(u.declarations??[]).map(ce);F.defineForeign(u.token,Fe(u.declarations??[]),y,u.writable??!0)}let z=new Map;for(let[u,y]of Object.entries(e.scenes)){let w=new Set((y.sceneProps??[]).filter(m=>m.shared??!1).map(m=>m.name.toLowerCase()));z.set(u,w)}this.host={bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:d,nodeIndex:p,blockIndex:g,blockById:h,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:P(e),shared:F,patterSharedDecls:A,patterLocalDecls:he,patterSharedNames:me,sceneSharedNames:z,sharedVisits:new Map,sharedSelectors:new Map,stageBags:new Map,customRng:t.rng,onDryChoice:t.onDryChoice,replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??_).open,captionClose:(e.closedCaptions??_).close,captionCharacter:e.closedCaptions?.character||se,refSplitCache:new Map}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}setLocale(e){this.currentLocale=e,this.host.strings=this.allStrings[e]??{}}replaceStrings(e){this.allStrings=e.strings,this.host.strings=this.allStrings[this.currentLocale]??{},this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{}}hotSwap(e){let t=this.saveGame(),r=i=>(i.setLocale(this.currentLocale),i.setClosedCaptions(this.host.captionsOn),i),s=new n(e,this.creationOptions);try{return s.loadGame(t),r(s)}catch{let i=new n(e,this.creationOptions);for(let[o,a]of Object.entries(t.flows)){let c=a.cursor.currentSceneId;try{i.openFlow(o,c!==null?{scene:c}:{})}catch{}}return r(i)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){let r=this.resolveSceneRef(t.scene),s=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new k(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,s),i}runFlow(e,t,r){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!s.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return s.advanceToStop().played}resolveSceneRef(e){if(e!=null)return this.host.bundle.scenes[e]?e:this.sceneGameIdToId.get(e)??e}resolveBlockRef(e,t){if(t!=null){if(this.host.blockById.has(t))return t;if(e!=null){let r=this.blockGameIdToId.get(e)?.get(t);if(r)return r}return t}}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?f(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?f(t):void 0}tagsForBeat(e){return this.host.tagIndex.get(e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?this.host.tagIndex.get(t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t);return(s!=null?this.host.tagIndex.get(s):void 0)??[]}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),r=t!=null?this.host.bundle.scenes[t]:void 0;if(!r)return[];let s=new Set;for(let i of r.blocks)oe(i.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return oe(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...f(e)?{gameId:f(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...f(t)?{gameId:f(t)}:{},name:t.name,...this.tagsField(t.id),children:t.children.map(r=>this.outlineNode(r))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let r of t.blocks)x(r.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=this.host.tagIndex.get(e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let s=this.host.defaultStrings[$(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let s=this.host.defaultStrings[e.id];s!==void 0&&(r.text=s)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=this.host.tagIndex.get(e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}closeFlow(e){this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.shared.reseedOwned("patter",this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear(),this.host.stageBags.clear()}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitShared(e);this.host.shared.set(r,s,t)}listProperties(){return this.host.patterSharedDecls.map(e=>({ref:`@${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:Ne(e)}))}splitShared(e){let t=this.host.refSplitCache.get(e);if(t||(t=j(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}save(){return this.host.shared.save()}load(e){this.host.shared.load(e)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:2,shared:this.host.shared.save(),sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:pe(this.host.sharedSelectors),stageBags:Object.fromEntries([...this.host.stageBags].map(([t,r])=>[t,{...r}])),flows:e}}loadGame(e){if(e.version!==2)throw new Error(`unsupported save version: ${e.version}`);this.host.shared.load(e.shared),this.host.sharedVisits.clear();for(let[t,r]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(t,r);this.host.sharedSelectors.clear();for(let[t,r]of de(e.sharedSelectors))this.host.sharedSelectors.set(t,r);this.host.stageBags.clear();for(let[t,r]of Object.entries(e.stageBags??{}))this.host.stageBags.set(t,{...r});this.flowsById.clear();for(let[t,r]of Object.entries(e.flows)){let s=new k(t,this.host,this.defaultSeed);s.restore(r),this.flowsById.set(t,s)}}},k=class{id;host;local;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPromptBeat=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.shared.get("patter",e):this.local.get("patter",e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.shared.set("patter",e,t):this.local.set("patter",e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;return t===null?void 0:(this.host.sceneSharedNames.get(t)?.has(e)?this.host.stageBags.get(t):this.sceneBags.get(t))?.[e]},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let s=this.host.sceneSharedNames.get(r)?.has(e)?this.host.stageBags.get(r):this.sceneBags.get(r);s&&(s[e]=t)}};evalCtx;constructor(e,t,r){this.id=e,this.host=t,this.rngState=r>>>0,this.local=this.freshLocal();let s={...t.shared.toEvalContext().scopes};s.patter=this.patterResolver,s.scene=this.sceneResolver,this.evalCtx={scopes:s,host:{nextRandom:this.rng,visits:i=>this.visitCounts.get(i)??0,patterVisits:i=>this.host.sharedVisits.get(i)??0},qualities:(i,o)=>this.stagesFor(i,o)}}stagesFor(e,t){let r=t.toLowerCase(),s=i=>i?.find(o=>o.name.toLowerCase()===r&&o.type==="quality")?.stages;if(e==="patter")return s(this.host.patterSharedDecls)??s(this.host.patterLocalDecls);if(e==="scene"){let i=this.currentSceneId!=null?this.host.bundle.scenes[this.currentSceneId]:void 0;return s(i?.sceneProps)}return s(this.host.bundle.scopeRegistry?.scopes.find(i=>i.token===e)?.declarations)}start(e,t){if(this.sceneBags.clear(),this.local=this.freshLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.started=!0,t){let r=this.host.blockIndex.get(t);if(!r)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(r.sceneId),this.stack=[{sceneId:r.sceneId,containerId:t,index:0}],this.enter(t)}else{let r=e??Object.keys(this.host.bundle.scenes)[0],s=r?this.host.bundle.scenes[r]:void 0;if(!s)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=s.blocks[0];i&&(this.stack=[{sceneId:r,containerId:i.id,index:0}],this.enter(i.id))}this.settle()}reset(e,t){this.start(e,t)}goto(e,t){if(this.closed)return!1;if(e==="END")return this.started=!0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=this.host.sceneGameIdToId.get(e)??(this.host.bundle.scenes[e]?e:void 0);if(r===void 0)return!1;let s;return t!==void 0&&(s=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),s===void 0)?!1:this.started?(this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(s??r,"jump"),this.settle(),!0):(this.start(r,s),!0)}close(){this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end"};if(!this.started)throw new Error("flow has not been started");if(this.pendingPromptBeat){let e=this.pendingPromptBeat;return this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.beatResult(e)}return this.settle(),this.flowEnded?{type:"end"}:this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.pendingChoice.options}:this.activeSnippet?this.beatResult(this.activeSnippet.beats[this.beatIndex++]):(this.flowEnded=!0,{type:"end"})}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit);let s=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(s);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let r=this.childrenOf(t.containerId);if(!r){this.stack.pop();continue}for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}getChoices(){return this.pendingChoice?.options??[]}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let r=t.options.find(i=>i.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);let s=t.byId.get(e);this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(s)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?s.id:null,this.enterChild(s)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:r}=this.splitRef(e);return t==="patter"?this.patterResolver.get(r):t==="scene"?this.sceneResolver.get(r):this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitRef(e);if(r==="patter")this.patterResolver.set(s,t);else if(r==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(s,t)}else this.host.shared.set(r,s,t)}snapshot(){return{scopes:this.local.save(),sceneBags:Object.fromEntries([...this.sceneBags].map(([e,t])=>[e,{...t}])),rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,currentSceneId:this.currentSceneId,stack:this.stack.map(e=>{let t=this.childrenOf(e.containerId)?.[e.index];return t?{...e,nextId:t.id}:{...e}}),activeSnippetId:this.activeSnippet?.id??null,beatIndex:this.beatIndex,pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(e=>({...e}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,selectors:pe(this.selectors)}}}restore(e){this.rngState=e.rngState>>>0,this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;if(this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:s,...i}=r;if(s!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===s)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.sceneBags=new Map(Object.entries(e.sceneBags??{}).map(([r,s])=>[r,{...s}])),this.local=this.freshLocal(),this.local.load(e.scopes),this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=de(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),s.push({...i}))}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,byId:r})}if(this.pendingPromptBeat=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId);this.pendingPromptBeat=r?this.promptBeatOf(r)??null:null,this.pendingPromptBeat||(this.pendingPromptOwnerId=null)}}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let r=this.selectChild(e);r&&this.enterChild(r)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let r=this.host.nodeIndex.get(e);if(r&&r.type==="group")return r.children}beginSnippet(e){this.runEffects(e.onEnter),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}r=e,s=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),r=a.sceneId,s=e}this.enter(s);let o={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.filter(s=>this.eligible(s));if(t.length===0)return null;let r=this.selectorState(e);switch(e.selector){case"branch":return t[0];case"sequence":{let s=e.options?.order??"sequential",i=e.options?.exhaust??"once";return s==="shuffle"?this.pickShuffle(t,i,r):s==="specificity"?this.pickSpecificity(t,i,r):this.pickSequential(t,i,r)}default:return null}}pickSequential(e,t,r){let s=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(g=>g.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let g=e[s-1];return r.last=g.id,g}r.bag=o()}let a=r.bag,c=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,d=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&d>=c&&d++;let p=a[d];return a.splice(d,1),r.last=p,e.find(g=>g.id===p)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(p=>p.id));let d=new Set(r.bag);if(s=e.filter(p=>d.has(p.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(p=>p.id===r.last)??null:null}let i=-1,a=s.map(d=>{let p=this.specScore(d);return p>i&&(i=p),{c:d,s:p}}).filter(d=>d.s===i).map(d=>d.c),c;if(a.length===1)c=a[0];else{let d=r.last!==void 0?a.findIndex(g=>g.id===r.last):-1,p=Math.floor(this.rng()*(d>=0?a.length-1:a.length));d>=0&&p>=d&&p++,c=a[p]}return t!=="repeat"&&(r.bag=r.bag.filter(d=>d!==c.id)),r.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return Y(e,s=>le(D(s,this.evalCtx,L)),{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=t.get(e.id);return r||(r={},t.set(e.id,r)),r}runEffects(e){for(let t of e??[])this.setProperty(t.target,this.evalExpr(t.value))}eligible(e){return e.condition?le(this.evalExpr(e.condition)):!0}evalExpr(e){return D(this.conditionAst(e),this.evalCtx,L)}conditionAst(e){let t=ie.get(e);return t||(t=v(e.ast),ie.set(e,t)),t}enter(e){this.visitCounts.set(e,(this.visitCounts.get(e)??0)+1),this.host.sharedVisits.set(e,(this.host.sharedVisits.get(e)??0)+1)}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=this.rngState+1831565813|0;this.rngState=e;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296};beatResult(e){let t=this.host.tagIndex.get(e.id),r=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:e.gameData,...r};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),gameData:e.gameData,...r};case"line":{let s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return ne(e,t=>this.getProperty(t))}stripCaptions(e){return re(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let r=this.interpolate(this.resolveString(t.id));return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction}:{kind:"text",text:r}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(r=>r.kind==="line"||r.kind==="text")}firstTextSnippetIn(e){let t;return x(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(s=>s.kind==="line"||s.kind==="text")&&(t=r)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let r=this.host.defaultStrings[e];return r!==void 0?`<Untranslated: ${e}> ${r}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=$(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){let t=this.host.refSplitCache.get(e);return t||(t=j(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t}freshLocal(){return new C().defineOwned("patter",this.host.patterLocalDecls)}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set;if(!this.sceneBags.has(e.id)){let r={};for(let s of e.sceneProps??[]){let i=s.name.toLowerCase();t.has(i)||(r[i]=q(s))}this.sceneBags.set(e.id,r)}if(!this.host.stageBags.has(e.id)){let r={};for(let s of e.sceneProps??[]){let i=s.name.toLowerCase();t.has(i)&&(r[i]=q(s))}this.host.stageBags.set(e.id,r)}for(let r of e.sceneProps??[]){if(!r.temporary)continue;let s=r.name.toLowerCase(),i=t.has(s)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);i&&(i[s]=q(r))}}};function oe(n,e){x(n,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let r of t.beats??[])r.kind==="line"&&r.character&&e.add(r.character)})}function pe(n){let e={};for(let[t,r]of n){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e[t]=s}return e}function de(n){let e=new Map;for(let[t,r]of Object.entries(n??{})){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e.set(t,s)}return e}function ae(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function Ne(n){if(n.default!==void 0)return n.default;switch(n.type){case"number":return 0;case"string":return"";case"flags":return[];case"enum":return n.values?.[0]??"";case"quality":return n.stages?.[0]??"";default:return!1}}function ce(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function Ae(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"flags":return[];case"enum":return n.values?.[0]??"";case"quality":return n.stages?.[0]??""}}function Fe(n){let e=r=>r.toLowerCase(),t=new Map;for(let r of n)t.set(e(r.name),Ae(r));return{get:r=>t.get(e(r)),set:(r,s)=>{t.set(e(r),s)}}}function q(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"flags":return[];case"enum":return n.values?.[0]??"";case"quality":return n.stages?.[0]??""}}function le(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Ge=(n,e)=>n.shared??e;function H(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Ge(n,e)}}function Te(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function Ve(n,e){e.blocks++;let t=[...n.children];for(;t.length;){let r=t.pop();if(r.type==="group"){e.groups++,r.prompt&&e.prompts++,t.push(...r.children);continue}e.snippets++;for(let s of r.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function ue(n){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:n.cast?.length??0},t=[],r=[];for(let o of Object.values(n.scenes)){e.scenes++;let a=f(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:f(c),name:c.name}))});for(let c of o.blocks)Ve(c,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(c=>H(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>H(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(Te)}));return{identity:{schema:n.schema,project:n.content.project,...n.content.version!==void 0?{version:n.content.version}:{},...n.content.hash!==void 0?{hash:n.content.hash}:{},...n.content.structureHash!==void 0?{structureHash:n.content.structureHash}:{},voiced:n.voiced,defaultLocale:n.locales.default,locales:[...n.locales.included],localisation:n.localisation?.mode??"embedded",sourceDebug:n.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(n.properties??[]).map(o=>H(o,!0)),scene:r},gameData:i,counts:e}}function ge(n,e){return n.gameDataFields?.[e]??[]}function U(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function fe(n,e){let t={};for(let r of n){let s=U(n,e,r.name);s!==void 0&&(t[r.name]=s)}for(let[r,s]of Object.entries(e??{}))r in t||(t[r]=s);return t}return xe(Me);})();\n//# sourceMappingURL=patterplay.min.js.map';
195012
+ var PLAYABLE_RUNTIME_JS = '"use strict";var Patterplay=(()=>{var L=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var ve=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var we=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},xe=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of ve(e))!be.call(n,s)&&s!==t&&L(n,s,{get:()=>e[s],enumerable:!(r=Se(e,s))||r.enumerable});return n};var Ee=n=>xe(L({},"__esModule",{value:!0}),n);var Ve={};we(Ve,{Engine:()=>F,Flow:()=>C,buildTagIndex:()=>A,describeBundle:()=>ue,effectiveGameData:()=>fe,gameDataFields:()=>he,gameDataValue:()=>K});function w(n){switch(n[0]){case"b":return{kind:"bool",value:n[1]};case"n":return{kind:"number",value:n[1]};case"s":return{kind:"string",value:n[1]};case"sv":return{kind:"scopedvar",scope:n[1],name:n[2]};case"u":return{kind:"unary",op:n[1],operand:w(n[2])};case"bin":return{kind:"binary",op:n[1],left:w(n[2]),right:w(n[3])};case"call":{let e=n.slice(2).map(w);return{kind:"call",name:n[1],args:e}}case"fd":return{kind:"flagdelta",sign:n[1],name:n[2]}}}var l=class extends Error{constructor(e){super(e),this.name="EvalError"}};function B(n,e,t){let r=new Map(t.scopes.map(i=>[i.token,i.missing??"false"])),s=i=>{switch(i.kind){case"bool":return i.value;case"number":return i.value;case"string":return i.value;case"scopedvar":{let o=e.scopes[i.scope];if(o===void 0)return!1;let a=typeof o.get=="function"?o.get(i.name):o[i.name];if(a===void 0){if(r.get(i.scope)==="throw")throw new l(`@${i.scope}.${i.name} is not declared on the current ${i.scope}.`);return!1}return a}case"call":{if(i.name==="advance"&&!t.functions[i.name]){let a=i.args[0];if(i.args.length!==1||a===void 0)throw new l(`advance() takes exactly 1 argument, got ${i.args.length}`);let c=M(a,e);if(c===void 0)throw new l("advance() needs a quality reference (@scope.name of a quality property)");let d=S(s(a),c,"advance");return c[Math.min(d+1,c.length-1)]}let o=t.functions[i.name];if(!o)throw new l(`unknown function \'${i.name}\'`);return o.eval(i.args,{evaluate:s,ctx:e})}case"flagdelta":throw new l("flagdelta node is only valid as an argument to a flag-delta function");case"unary":{if(i.op==="not"){let a=s(i.operand);if(typeof a!="boolean")throw new l(`\'not\' requires a boolean operand, got ${typeof a}`);return!a}let o=s(i.operand);if(typeof o!="number")throw new l(`unary \'-\' requires a numeric operand, got ${typeof o}`);return-o}case"binary":{if(i.op==="and"){let u=s(i.left);if(typeof u!="boolean")throw new l(`\'and\' requires boolean operands, left is ${typeof u}`);if(!u)return!1;let f=s(i.right);if(typeof f!="boolean")throw new l(`\'and\' requires boolean operands, right is ${typeof f}`);return f}if(i.op==="or"){let u=s(i.left);if(typeof u!="boolean")throw new l(`\'or\' requires boolean operands, left is ${typeof u}`);if(u)return!0;let f=s(i.right);if(typeof f!="boolean")throw new l(`\'or\' requires boolean operands, right is ${typeof f}`);return f}let o=s(i.left),a=s(i.right),c=M(i.left,e),d=M(i.right,e),p=c??d;if(p!==void 0){if(c&&d&&!ke(c,d)&&(i.op===">"||i.op===">="||i.op==="<"||i.op==="<="))throw new l(`\'${i.op}\' compares two different qualities, whose stage orders are unrelated`);switch(i.op){case">":return S(o,p,">")>S(a,p,">");case">=":return S(o,p,">=")>=S(a,p,">=");case"<":return S(o,p,"<")<S(a,p,"<");case"<=":return S(o,p,"<=")<=S(a,p,"<=");case"+":case"-":case"*":case"/":throw new l(`\'${i.op}\' cannot be applied to a quality - a stage is a position, not a number; use advance() to move it`);default:break}}switch(i.op){case"==":return Z(o,a);case"!=":return!Z(o,a);case">":return x(o,a,">"),o>a;case">=":return x(o,a,">="),o>=a;case"<":return x(o,a,"<"),o<a;case"<=":return x(o,a,"<="),o<=a;case"+":if(typeof o=="number"&&typeof a=="number"||typeof o=="string"&&typeof a=="string")return o+a;throw new l(`\'+\' requires two numbers or two strings, got ${typeof o} and ${typeof a}`);case"-":return x(o,a,"-"),o-a;case"*":return x(o,a,"*"),o*a;case"/":if(x(o,a,"/"),a===0)throw new l("division by zero");return o/a}}}};return s(n)}function Z(n,e){if(Array.isArray(n)||Array.isArray(e)){if(!Array.isArray(n)||!Array.isArray(e)||n.length!==e.length)return!1;let t=[...n].sort(),r=[...e].sort();for(let s=0;s<t.length;s++)if(t[s]!==r[s])return!1;return!0}return n===e}function x(n,e,t){if(typeof n!="number"||typeof e!="number")throw new l(`\'${t}\' requires numeric operands, got ${typeof n} and ${typeof e}`)}function M(n,e){if(!(n.kind!=="scopedvar"||e.qualities===void 0))return e.qualities(n.scope,n.name)}function S(n,e,t){if(typeof n!="string")throw new l(`\'${t}\' on a quality compares stages, got ${typeof n}`);let r=e.indexOf(n);if(r<0)throw new l(`"${n}" is not a stage of this quality (stages: ${e.join(", ")})`);return r}var ke=(n,e)=>n.length===e.length&&n.every((t,r)=>t===e[r]);function I(n){if(Number.isNaN(n)||!Number.isFinite(n))return 0;let e=Math.trunc(n)%4294967296;return e<0?e+4294967296:e}function j(n){let e=I(n);return{next(){e=e+1831565813>>>0;let t=Math.imul(e^e>>>15,1|e);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296},state(){return e}}}var Ce={name:"check_flags",count:n=>Math.max(1,n.args.length-1)},Ie=[Ce];function Q(n,e,t){let r=t?.countingCalls??Ie;return P(n,t?.want??!0,e,r)}function P(n,e,t,r){if(n.kind==="binary"&&(n.op==="and"||n.op==="or")){let s=P(n.left,e,t,r),i=P(n.right,e,t,r);return n.op==="and"===e?s>0&&i>0?s+i:0:Math.max(s,i)}if(n.kind==="unary"&&n.op==="not")return P(n.operand,!e,t,r);if(n.kind==="call"){let s=r.find(i=>i.name===n.name);if(s){let i=s.count(n),o=t(n);return e?o?i:0:o?0:1}}return t(n)===e?1:0}var b=class n{values={};decls=new Map;subscribers=new Set;auditors=new Set;norm;pathPrefix;constructor(e=[],t){this.norm=t?.normalise??(r=>r.toLowerCase()),this.pathPrefix=t?.pathPrefix??"",this.seed(e)}seed(e){for(let t of e){let r=this.norm(t.name);this.decls.set(r,t),this.values[r]=structuredClone(t.default??E(t))}}get(e){return this.values[this.norm(e)]}set(e,t,r){let s=this.norm(e);if(this.decls.get(s)?.writable===!1)throw new Error(`\'${e}\' is read-only`);let i={name:s,prev:this.values[s],next:t,silent:r?.silent??!1,reason:r?.reason};this.values[s]=t;for(let o of this.auditors)o(i);if(!i.silent)for(let o of this.subscribers)o(i);return i}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}onAudit(e){return this.auditors.add(e),()=>this.auditors.delete(e)}rows(){return[...this.decls.entries()].map(([e,t])=>ee(t,this.get(e),void 0,e,this.pathPrefix))}declarations(){return[...this.decls.values()]}clone(){let e=new n([],{normalise:this.norm,pathPrefix:this.pathPrefix});return e.decls=new Map(this.decls),Object.assign(e.values,structuredClone(this.values)),e}reseed(e){for(let t of Object.keys(this.values))delete this.values[t];this.decls.clear(),this.seed(e)}save(){return structuredClone(this.values)}load(e){for(let[t,r]of Object.entries(e))this.values[this.norm(t)]=r}};function ee(n,e,t,r,s=""){let i=r??n.name.toLowerCase();return{name:i,path:s+i,type:n.type,value:e,default:n.default??E(n),...n.values!==void 0?{values:n.values}:{},...n.stages!==void 0?{stages:n.stages}:{},writable:t??n.writable??!0}}var $=1,D=class{scopes=new Map;defineOwned(e,t,r){return this.mountOwned(e,new b(t,{pathPrefix:r??`${e}.`}))}mountOwned(e,t){return this.assertFree(e),this.scopes.set(e,{kind:"owned",bag:t}),this}ownedBag(e){let t=this.scopes.get(e);if(!t||t.kind!=="owned")throw new Error(`\'@${e}\' is not an owned scope`);return t.bag}reseedOwned(e,t){return this.ownedBag(e).reseed(t),this}defineForeign(e,t,r=[],s=!0){this.assertFree(e);let i=new Map;for(let o of r)i.set(o.name.toLowerCase(),o);return this.scopes.set(e,{kind:"foreign",resolver:t,decls:i,scopeWritable:s}),this}has(e){return this.scopes.has(e)}get(e,t){let r=this.scopes.get(e);if(r)return r.kind==="owned"?r.bag.get(t):r.resolver.get(t.toLowerCase())}set(e,t,r){let s=this.scopes.get(e);if(!s)throw new Error(`unknown scope \'@${e}\'`);if(s.kind==="owned"){try{s.bag.set(t,r)}catch{throw new Error(`\'@${e}.${t}\' is read-only`)}return}let i=t.toLowerCase();if(!this.foreignWritable(s,i))throw new Error(`\'@${e}.${t}\' is read-only`);s.resolver.set(i,r)}foreignWritable(e,t){return e.resolver.set?e.decls.get(t)?.writable??e.scopeWritable:!1}listProperties(){let e=[];for(let[t,r]of this.scopes)if(r.kind==="owned")for(let s of r.bag.rows())e.push({scope:t,...s});else for(let s of r.decls.values())e.push({scope:t,...ee(s,r.resolver.get(s.name.toLowerCase()),this.foreignWritable(r,s.name.toLowerCase()),void 0,`${t}.`)});return e}toEvalContext(e){let t={};for(let[s,i]of this.scopes)t[s]=i.kind==="owned"?i.bag.values:i.resolver;let r=this.qualityLadders();return r.size===0?{scopes:t,host:e}:{scopes:t,host:e,qualities:(s,i)=>r.get(s)?.get(i.toLowerCase())}}qualityLadders(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];for(let i of s){if(i.type!=="quality"||i.stages===void 0)continue;let o=e.get(t);o||(o=new Map,e.set(t,o)),o.set(i.name.toLowerCase(),i.stages)}}return e}toSchema(){let e=new Map;for(let[t,r]of this.scopes){let s=r.kind==="owned"?r.bag.declarations():[...r.decls.values()];if(s.length===0)continue;let i=new Map;for(let o of s)i.set(o.name.toLowerCase(),{type:o.type,enumValues:o.values,...o.stages!==void 0?{stages:o.stages}:{}});e.set(t,i)}return{properties:e}}save(){let e={};for(let[t,r]of this.scopes)r.kind==="owned"&&(e[t]=r.bag.save());return e}load(e){for(let[t,r]of Object.entries(e)){let s=this.scopes.get(t);s?.kind==="owned"&&s.bag.load(r)}}saveFragment(){return{version:$,scopes:this.save()}}loadFragment(e){if(e.version!==$)throw new Error(`unsupported owned-state fragment version ${e.version} (supported: ${$})`);this.load(e.scopes)}assertFree(e){if(this.scopes.has(e))throw new Error(`scope \'@${e}\' is already registered`)}};function E(n){if(n.default!==void 0)return n.default;switch(n.type){case"boolean":return!1;case"number":return 0;case"string":return"";case"enum":return n.values?.[0]??"";case"flags":return[];case"quality":return n.stages?.[0]??"";default:return!1}}function R(n){return n.ctx.host??{}}var q={defaultScope:"patter",scopes:[{token:"patter"},{token:"scene"}],functions:{random:{minArgs:2,maxArgs:2,returnType:"number",eval(n,e){if(n.length!==2)throw new l("random(a, b) requires exactly 2 arguments");let t=R(e).nextRandom;if(!t)throw new l("random() called without a PRNG in context");let r=e.evaluate(n[0]),s=e.evaluate(n[1]);if(typeof r!="number"||typeof s!="number")throw new l("random(a, b) arguments must be numbers");if(!Number.isInteger(r)||!Number.isInteger(s))throw new l("random(a, b) arguments must be integers");let i=Math.min(r,s),o=Math.max(r,s);return Math.floor(t()*(o-i+1))+i}},check_flags:{minArgs:1,returnType:"boolean",flagDeltaArgs:!0,validate:re("check_flags"),eval(n,e){let t=te(n[0],e,"check_flags");for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("check_flags() flag args must be +flagName or -flagName");if(s.sign==="+"?!t.includes(s.name):t.includes(s.name))return!1}return!0}},set_flags:{minArgs:1,returnType:"flags",flagDeltaArgs:!0,validate:re("set_flags"),eval(n,e){let t=[...te(n[0],e,"set_flags")];for(let r=1;r<n.length;r++){let s=n[r];if(s.kind!=="flagdelta")throw new l("set_flags() flag args must be +flagName or -flagName");if(s.sign==="+")t.includes(s.name)||t.push(s.name);else{let i=t.indexOf(s.name);i>=0&&t.splice(i,1)}}return t}},visits:{minArgs:1,maxArgs:1,returnType:"number",validate:N("visits"),eval:(n,e)=>R(e).visits?.(O(n,e,"visits"))??0},seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:N("seen"),eval:(n,e)=>(R(e).visits?.(O(n,e,"seen"))??0)>0},patter_visits:{minArgs:1,maxArgs:1,returnType:"number",validate:N("patter_visits"),eval:(n,e)=>R(e).patterVisits?.(O(n,e,"patter_visits"))??0},patter_seen:{minArgs:1,maxArgs:1,returnType:"boolean",validate:N("patter_seen"),eval:(n,e)=>(R(e).patterVisits?.(O(n,e,"patter_seen"))??0)>0}}};function H(n,e){let t=n.replace(/^@/,"").split(".");return t.length===2&&e(t[0])?{scope:t[0],name:t[1].toLowerCase()}:{scope:"patter",name:t.join(".").toLowerCase()}}function O(n,e,t){let r=e.evaluate(n[0]);if(typeof r!="string")throw new l(`${t}(id) requires a string node id`);return r}function N(n){return(e,t)=>{let r=e[0];r&&r.kind!=="string"&&t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(id): the argument must be a string id literal (a scene / block / node id)`})}}function te(n,e,t){if(!n)throw new l(`${t}() requires at least one argument (the flags variable)`);let r=e.evaluate(n);if(Array.isArray(r))return r;if(r===!1||r===null||r===void 0)return[];throw new l(`${t}() first argument must be a flags property`)}function re(n){return(e,t)=>{if(e.length===0)return;let r=e[0];if(r.kind!=="scopedvar"){t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): first argument must be a flags property reference (@name or @scope.name)`});return}let s=t.schema.properties.get(r.scope)?.get(r.name);if(s&&s.type!=="flags"){let i=r.scope===t.defaultScope?r.name:`${r.scope}.${r.name}`;t.report({path:[...t.path,"args",0],kind:"wrong-arg-type",severity:"error",message:`${n}(): \'@${i}\' is not a flags property (got ${s.type})`});return}for(let i=1;i<e.length;i++){let o=e[i];o.kind!=="flagdelta"?t.report({path:[...t.path,"args",i],kind:"wrong-arg-type",severity:"error",message:`${n}(): argument ${i+1} must be +flagName or -flagName`}):s?.type==="flags"&&s.enumValues&&!s.enumValues.includes(o.name)&&t.report({path:[...t.path,"args",i],kind:"unknown-flag-name",severity:"error",message:`${n}(): unknown flag \'${o.name}\'`,reference:o.name})}}}var De=/^@[A-Za-z0-9_.]+$/;function*Re(n){let e="",t=0;for(;t<n.length;){let r=n[t];if(r==="{"&&n[t+1]==="{"){e+="{",t+=2;continue}if(r==="}"&&n[t+1]==="}"){e+="}",t+=2;continue}if(r==="{"){let s=n.indexOf("}",t+1);if(s!==-1){let i=n.slice(t,s+1),o=n.slice(t+1,s).trim();if(o.startsWith("@")){e&&(yield{kind:"text",value:e},e=""),yield{kind:"slot",raw:i,inner:o,ref:De.test(o)?o:void 0},t=s+1;continue}e+=i,t=s+1;continue}}e+=r,t+=1}e&&(yield{kind:"text",value:e})}function Be(n){return Array.isArray(n)?n.join(", "):typeof n=="boolean"?n?"true":"false":String(n)}function Pe(n){return n===" "||n===" "||n===`\n`||n==="\\r"||n==="\\f"||n==="\\v"}function Oe(n){let e="",t=!1;for(let r of n){if(Pe(r)){t=!0;continue}t&&e.length>0&&(e+=" "),t=!1,e+=r}return e}function ne(n,e,t){if(e.length===0||n.indexOf(e)<0)return n;let r="",s=0,i=!1;for(;s<n.length;){if(n.startsWith(e,s)){let o=n.indexOf(t,s+e.length);if(o>=0){s=o+t.length,i=!0;continue}r+=n.slice(s);break}r+=n[s],s+=1}return i?Oe(r):n}function se(n,e){if(n.indexOf("{")<0)return n;let t="";for(let r of Re(n)){if(r.kind==="text"){t+=r.value;continue}if(!r.ref){t+=r.raw;continue}let s=e(r.ref);t+=s===void 0?"":Be(s)}return t}function k(n,e){for(let t of n){e(t);let r=t.children;r&&k(r,e)}}function Ne(n){return n.toLowerCase().replace(/[\'\u2019]/g,"").replace(/[^a-z0-9-]+/g,"-").replace(/-+/g,"-").replace(/^-+|-+$/g,"")}function h(n){let e=n.gameId?.trim();return e||Ne(n.name)}function _(n){return`cast:${n}`}var U={open:"[",close:"]"},ie="SFX";function T(n){let e=new Set,t=[];for(let r of n)e.has(r)||(e.add(r),t.push(r));return t}function A(n){let e=new Map,t=(r,s)=>{let i=T([...s,...r.tags??[]]);if(e.set(r.id,i),r.type==="group")for(let o of r.children)t(o,i);else for(let o of r.beats??[])e.set(o.id,T([...i,...o.tags??[]]))};for(let r of Object.values(n.scenes)){let s=T(r.tags??[]);e.set(r.id,s);for(let i of r.blocks){let o=T([...s,...i.tags??[]]);e.set(i.id,o);for(let a of i.children)t(a,o)}}return e}var oe=new WeakMap,F=class n{host;defaultSeed;flowsById=new Map;allStrings;currentLocale;sourceDebug;sceneGameIdToId=new Map;blockGameIdToId=new Map;creationOptions;engineLog=[];engineTraceHandlers=new Set;constructor(e,t={}){this.creationOptions=t;let r=t.locale??e.locales.default,s=e.strings;this.allStrings=s,this.currentLocale=r;let i=s[r]??{},o=s[e.locales.default]??{},a=e.localisation,c=a?.mode==="ids"&&!a.sourceDebug;this.sourceDebug=a?.mode==="ids"&&!!a.sourceDebug,this.sourceDebug&&typeof console<"u"&&console.warn("[Patterplay] source-only DEBUG build: strings are the source language for debugging, not a shippable localised build.");let d=new Map;for(let g of e.cast??[])g.displayName&&d.set(g.name,g.displayName);this.defaultSeed=(t.seed??2654435769)>>>0;let p=new Map,u=new Map,f=new Map;for(let[g,m]of Object.entries(e.scenes)){this.sceneGameIdToId.set(h(m),g);let v=new Map;for(let y of m.blocks)u.set(y.id,{sceneId:g}),f.set(y.id,y),v.set(h(y),y.id),k(y.children,X=>p.set(X.id,X));this.blockGameIdToId.set(g,v)}let J=e.properties??[],G=J.filter(g=>g.shared??!0).map(ce),me=J.filter(g=>!(g.shared??!0)).map(ce),ye=new Set(G.map(g=>g.name.toLowerCase())),V=new D().defineOwned("patter",G,"@patter."),z=new Set;if(t.world){let g=e.scopeRegistry?.scopes.find(v=>v.token==="world"),m=(g?.declarations??[]).map(le);V.defineForeign("world",t.world,m,g?.writable??!0),z.add("world")}for(let g of e.scopeRegistry?.scopes??[]){if(z.has(g.token))continue;let m=(g.declarations??[]).map(le);V.defineForeign(g.token,Te(g.declarations??[]),m,g.writable??!0)}let Y=new Map;for(let[g,m]of Object.entries(e.scenes)){let v=new Set((m.sceneProps??[]).filter(y=>y.shared??!1).map(y=>y.name.toLowerCase()));Y.set(g,v)}this.host={logEnabled:t.log??!1,emitEngine:(g,m,v)=>this.emitEngine(g,m,v),bundle:e,emitIds:c,strings:i,defaultStrings:o,castDisplay:d,nodeIndex:p,blockIndex:u,blockById:f,sceneGameIdToId:this.sceneGameIdToId,blockGameIdToId:this.blockGameIdToId,tagIndex:A(e),shared:V,patterSharedDecls:G,patterLocalDecls:me,patterSharedNames:ye,sceneSharedNames:Y,sharedVisits:new Map,sharedSelectors:new Map,stageBags:new Map,customRng:t.rng,onDryChoice:t.onDryChoice,replayPromptOnChoose:t.replayPromptOnChoose??!1,captionsOn:t.closedCaptions??!0,captionOpen:(e.closedCaptions??U).open,captionClose:(e.closedCaptions??U).close,captionCharacter:e.closedCaptions?.character||ie,refSplitCache:new Map}}get locale(){return this.currentLocale}get isSourceDebug(){return this.sourceDebug}setLocale(e){this.currentLocale=e,this.host.strings=this.allStrings[e]??{}}replaceStrings(e){this.allStrings=e.strings,this.host.strings=this.allStrings[this.currentLocale]??{},this.host.defaultStrings=this.allStrings[this.host.bundle.locales.default]??{}}hotSwap(e){let t=this.saveGame(),r=i=>(i.setLocale(this.currentLocale),i.setClosedCaptions(this.host.captionsOn),i),s=new n(e,this.creationOptions);try{return s.loadGame(t),r(s)}catch{let i=new n(e,this.creationOptions);for(let[o,a]of Object.entries(t.flows)){let c=a.cursor.currentSceneId;try{i.openFlow(o,c!==null?{scene:c}:{})}catch{}}return r(i)}}get closedCaptions(){return this.host.captionsOn}setClosedCaptions(e){this.host.captionsOn=e}openFlow(e,t={}){let r=this.resolveSceneRef(t.scene),s=this.resolveBlockRef(r,t.block);this.flowsById.get(e)?.close();let i=new C(e,this.host,t.seed??this.defaultSeed);return this.flowsById.set(e,i),i.start(r,s),i}runFlow(e,t,r){let s=this.flowsById.get(e);if(!s)return this.openFlow(e,{scene:t,block:r}).advanceToStop().played;if(!s.goto(t,r))throw new Error(`runFlow: address not found: ${t}${r===void 0?"":` / ${r}`}`);return s.advanceToStop().played}resolveSceneRef(e){if(e!=null)return this.host.bundle.scenes[e]?e:this.sceneGameIdToId.get(e)??e}resolveBlockRef(e,t){if(t!=null){if(this.host.blockById.has(t))return t;if(e!=null){let r=this.blockGameIdToId.get(e)?.get(t);if(r)return r}return t}}sceneAddress(e){let t=this.host.bundle.scenes[e];return t?h(t):void 0}blockAddress(e){let t=this.host.blockById.get(e);return t?h(t):void 0}tagsForBeat(e){return this.host.tagIndex.get(e)??[]}tagsForScene(e){let t=this.resolveSceneRef(e);return(t!=null?this.host.tagIndex.get(t):void 0)??[]}tagsForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t);return(s!=null?this.host.tagIndex.get(s):void 0)??[]}getCast(){let e=[];for(let t of this.host.bundle.cast??[])t?.name&&e.push(t.name);return e}castForScene(e){let t=this.resolveSceneRef(e),r=t!=null?this.host.bundle.scenes[t]:void 0;if(!r)return[];let s=new Set;for(let i of r.blocks)ae(i.children,s);return[...s]}castForBlock(e,t){let r=this.resolveSceneRef(e),s=this.resolveBlockRef(r,t),i=s!=null?this.host.blockById.get(s):void 0;if(!i)return[];let o=new Set;return ae(i.children,o),[...o]}getOutline(){return Object.values(this.host.bundle.scenes).map(e=>({id:e.id,...h(e)?{gameId:h(e)}:{},name:e.name,...this.tagsField(e.id),blocks:e.blocks.map(t=>({id:t.id,...h(t)?{gameId:h(t)}:{},name:t.name,...this.tagsField(t.id),children:t.children.map(r=>this.outlineNode(r))}))}))}getBeatSequence(){let e=[];for(let t of Object.values(this.host.bundle.scenes))for(let r of t.blocks)k(r.children,s=>{if(s.type==="snippet")for(let i of s.beats??[])e.push({sceneId:t.id,blockId:r.id,snippetId:s.id,beat:this.beatInfo(i)})});return e}outlineNode(e){return e.type==="group"?{type:"group",id:e.id,...this.tagsField(e.id),...e.selector?{selector:e.selector}:{},...e.prompt?{prompt:this.beatInfo(e.prompt)}:{},children:e.children.map(t=>this.outlineNode(t))}:{type:"snippet",id:e.id,...this.tagsField(e.id),beats:(e.beats??[]).map(t=>this.beatInfo(t)),...e.jump?{jumpTo:e.jump.to,...e.jump.mode?{jumpMode:e.jump.mode}:{}}:{}}}beatInfo(e){let t=this.host.tagIndex.get(e.id),r={id:e.id,kind:e.kind};if(e.kind==="line"){if(e.character!==void 0){r.character=e.character;let s=this.host.defaultStrings[_(e.character)]??this.host.castDisplay.get(e.character);s!==void 0&&(r.characterName=s)}e.direction!==void 0&&(r.direction=e.direction)}if(e.kind==="line"||e.kind==="text"){let s=this.host.defaultStrings[e.id];s!==void 0&&(r.text=s)}return e.gameData&&Object.keys(e.gameData).length&&(r.gameData=e.gameData),t&&t.length&&(r.tags=t),r}tagsField(e){let t=this.host.tagIndex.get(e);return t&&t.length?{tags:t}:{}}getFlow(e){return this.flowsById.get(e)}flows(){return[...this.flowsById.values()]}closeFlow(e){this.flowsById.get(e)?.close(),this.flowsById.delete(e)}reset(){for(let e of this.flowsById.values())e.close();this.flowsById.clear(),this.host.shared.reseedOwned("patter",this.host.patterSharedDecls),this.host.sharedVisits.clear(),this.host.sharedSelectors.clear(),this.host.stageBags.clear()}getProperty(e){let{scope:t,name:r}=this.splitShared(e);return this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitShared(e);this.host.shared.set(r,s,t)}log(){return this.engineLog}clearLog(){this.engineLog.length=0}onTrace(e){return this.engineTraceHandlers.add(e),()=>this.engineTraceHandlers.delete(e)}emitEngine(e,t,r){for(let s of this.engineTraceHandlers)s(e,t);this.host.logEnabled&&this.engineLog.push({...t,flow:e,seq:this.engineLog.length,...r?{scene:r}:{}})}listProperties(){return this.host.patterSharedDecls.map(e=>({name:e.name,path:`@patter.${e.name}`,type:e.type,values:e.values,stages:e.stages,value:this.getProperty(`@${e.name}`),default:E(e),writable:e.writable??!0}))}splitShared(e){let t=this.host.refSplitCache.get(e);if(t||(t=H(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t.scope==="scene")throw new Error(`\'${e}\': @scene properties are scene-scoped - read/write them on a Flow, not the Engine`);return t}save(){return this.host.shared.save()}load(e){this.host.shared.load(e)}saveGame(){let e={};for(let[t,r]of this.flowsById)e[t]=r.snapshot();return{version:2,shared:this.host.shared.save(),sharedVisits:Object.fromEntries(this.host.sharedVisits),sharedSelectors:de(this.host.sharedSelectors),stageBags:Object.fromEntries([...this.host.stageBags].map(([t,r])=>[t,r.save()])),flows:e}}loadGame(e){if(e.version!==2)throw new Error(`unsupported save version: ${e.version}`);this.host.shared.load(e.shared),this.host.sharedVisits.clear();for(let[t,r]of Object.entries(e.sharedVisits??{}))this.host.sharedVisits.set(t,r);this.host.sharedSelectors.clear();for(let[t,r]of ge(e.sharedSelectors))this.host.sharedSelectors.set(t,r);this.host.stageBags.clear();for(let[t,r]of Object.entries(e.stageBags??{})){let s=this.host.sceneSharedNames.get(t)??new Set,i=(this.host.bundle.scenes[t]?.sceneProps??[]).filter(a=>s.has(a.name.toLowerCase())),o=new b(i);o.load(r),this.host.stageBags.set(t,o)}this.flowsById.clear();for(let[t,r]of Object.entries(e.flows)){let s=new C(t,this.host,this.defaultSeed);s.restore(r),this.flowsById.set(t,s)}}},C=class{id;host;local;rngState;started=!1;flowEnded=!1;closed=!1;currentSceneId=null;stack=[];activeSnippet=null;beatIndex=0;pendingChoice=null;pendingPromptBeat=null;pendingPromptOwnerId=null;selectors=new Map;visitCounts=new Map;sceneBags=new Map;patterResolver={get:e=>this.host.patterSharedNames.has(e)?this.host.shared.get("patter",e):this.local.get("patter",e),set:(e,t)=>{this.host.patterSharedNames.has(e)?this.host.shared.set("patter",e,t):this.local.set("patter",e,t)}};sceneResolver={get:e=>{let t=this.currentSceneId;return t===null?void 0:(this.host.sceneSharedNames.get(t)?.has(e)?this.host.stageBags.get(t):this.sceneBags.get(t))?.get(e)},set:(e,t)=>{let r=this.currentSceneId;if(r===null)return;let s=this.host.sceneSharedNames.get(r)?.has(e)?this.host.stageBags.get(r):this.sceneBags.get(r);s&&s.set(e,t)}};evalCtx;flowLog=[];flowSeq=0;constructor(e,t,r){this.id=e,this.host=t,this.rngState=I(r),this.local=this.freshLocal();let s={...t.shared.toEvalContext().scopes};s.patter=this.patterResolver,s.scene=this.sceneResolver,this.evalCtx={scopes:s,host:{nextRandom:this.rng,visits:i=>this.visitCounts.get(i)??0,patterVisits:i=>this.host.sharedVisits.get(i)??0},qualities:(i,o)=>this.stagesFor(i,o)}}stagesFor(e,t){let r=t.toLowerCase(),s=i=>i?.find(o=>o.name.toLowerCase()===r&&o.type==="quality")?.stages;if(e==="patter")return s(this.host.patterSharedDecls)??s(this.host.patterLocalDecls);if(e==="scene"){let i=this.currentSceneId!=null?this.host.bundle.scenes[this.currentSceneId]:void 0;return s(i?.sceneProps)}return s(this.host.bundle.scopeRegistry?.scopes.find(i=>i.token===e)?.declarations)}start(e,t){if(this.sceneBags.clear(),this.local=this.freshLocal(),this.selectors.clear(),this.visitCounts.clear(),this.stack=[],this.currentSceneId=null,this.flowEnded=!1,this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.started=!0,t){let r=this.host.blockIndex.get(t);if(!r)throw new Error(`unknown block: ${t}`);this.enterSceneSetup(r.sceneId),this.stack=[{sceneId:r.sceneId,containerId:t,index:0}],this.enter(t)}else{let r=e??Object.keys(this.host.bundle.scenes)[0],s=r?this.host.bundle.scenes[r]:void 0;if(!s)throw new Error(r?`unknown scene: ${r}`:"no scenes in bundle");this.enterSceneSetup(r);let i=s.blocks[0];i&&(this.stack=[{sceneId:r,containerId:i.id,index:0}],this.enter(i.id))}this.settle()}reset(e,t){this.start(e,t)}goto(e,t){if(this.closed)return!1;if(e==="END")return this.started=!0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!0,this.stack=[],!0;let r=this.host.sceneGameIdToId.get(e)??(this.host.bundle.scenes[e]?e:void 0);if(r===void 0)return!1;let s;return t!==void 0&&(s=this.host.blockGameIdToId.get(r)?.get(t)??(this.host.blockIndex.get(t)?.sceneId===r?t:void 0),s===void 0)?!1:this.started?(this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.activeSnippet=null,this.beatIndex=0,this.flowEnded=!1,this.enterTarget(s??r,"jump"),this.settle(),!0):(this.start(r,s),!0)}close(){this.closed=!0,this.flowEnded=!0,this.stack=[],this.activeSnippet=null,this.beatIndex=0,this.pendingChoice=null,this.pendingPromptBeat=null,this.pendingPromptOwnerId=null}get isClosed(){return this.closed}get currentScene(){return this.currentSceneId}advance(){if(this.closed)return{type:"end"};if(!this.started)throw new Error("flow has not been started");if(this.pendingPromptBeat){let e=this.pendingPromptBeat;return this.pendingPromptBeat=null,this.pendingPromptOwnerId=null,this.beatResult(e)}return this.settle(),this.flowEnded?{type:"end"}:this.pendingChoice?{type:"choice",groupId:this.pendingChoice.groupId,options:this.pendingChoice.options}:this.activeSnippet?this.beatResult(this.activeSnippet.beats[this.beatIndex++]):(this.flowEnded=!0,{type:"end"})}advanceToStop(){let e=[];for(;;){let t=this.advance();if(t.type==="choice"||t.type==="end")return{played:e,stop:t};e.push(t)}}settle(){let e=0;for(;;){if(++e>1e4)throw new Error("flow did not settle after 10000 transitions - likely a jump cycle with no deliverable content");if(this.flowEnded||this.pendingChoice)return;if(this.activeSnippet){if(this.beatIndex<(this.activeSnippet.beats?.length??0))return;this.runEffects(this.activeSnippet.onExit);let i=this.activeSnippet.jump;this.activeSnippet=null,this.beatIndex=0,this.resolveJump(i);continue}let t=this.stack[this.stack.length-1];if(!t){this.flowEnded=!0;return}t.sceneId!==this.currentSceneId&&(this.currentSceneId=t.sceneId);let r=this.childrenOf(t.containerId);if(!r){this.stack.pop();continue}let s=t.index;for(;t.index<r.length&&!this.eligible(r[t.index]);)t.index++;if(this.host.logEnabled&&t.index!==s&&this.emit({type:"select",group:t.containerId,selector:"run",children:r.slice(s,t.index+1).map((i,o)=>({id:i.id,eligible:s+o===t.index})),picked:r[t.index]?.id??null}),t.index>=r.length){this.stack.pop();continue}this.enterChild(r[t.index++])}}log(){return this.flowLog}clearLog(){this.flowLog.length=0}emit(e){let t=this.currentSceneId??void 0;this.host.emitEngine(this.id,e,t),this.host.logEnabled&&this.flowLog.push({...e,seq:this.flowSeq++,...t?{scene:t}:{}})}getChoices(){return this.pendingChoice?.options??[]}choose(e){let t=this.pendingChoice;if(!t)throw new Error("no choice is pending");let r=t.options.find(i=>i.id===e);if(!r)throw new Error(`unknown choice option: ${e}`);if(!r.eligible)throw new Error(`choice option is not eligible: ${e}`);let s=t.byId.get(e);this.emit({type:"chose",group:t.groupId,option:e}),this.pendingChoice=null,this.pendingPromptBeat=this.host.replayPromptOnChoose?this.promptBeatOf(s)??null:null,this.pendingPromptOwnerId=this.pendingPromptBeat?s.id:null,this.enterChild(s)}isEnded(){return this.flowEnded}getProperty(e){let{scope:t,name:r}=this.splitRef(e);return t==="patter"?this.patterResolver.get(r):t==="scene"?this.sceneResolver.get(r):this.host.shared.get(t,r)}setProperty(e,t){let{scope:r,name:s}=this.splitRef(e);if(r==="patter")this.patterResolver.set(s,t);else if(r==="scene"){if(this.currentSceneId===null)throw new Error(`\'${e}\': the flow has not entered a scene yet`);this.sceneResolver.set(s,t)}else this.host.shared.set(r,s,t)}snapshot(){return{scopes:this.local.save(),sceneBags:Object.fromEntries([...this.sceneBags].map(([e,t])=>[e,t.save()])),rngState:this.rngState,visits:Object.fromEntries(this.visitCounts),cursor:{flowEnded:this.flowEnded,currentSceneId:this.currentSceneId,stack:this.stack.map(e=>{let t=this.childrenOf(e.containerId)?.[e.index];return t?{...e,nextId:t.id}:{...e}}),activeSnippetId:this.activeSnippet?.id??null,beatIndex:this.beatIndex,pendingChoice:this.pendingChoice?{groupId:this.pendingChoice.groupId,options:this.pendingChoice.options.map(e=>({...e}))}:null,pendingPromptOwnerId:this.pendingPromptOwnerId,selectors:de(this.selectors)}}}restore(e){this.rngState=I(e.rngState),this.visitCounts=new Map(Object.entries(e.visits??{}));let t=e.cursor;if(this.started=!0,this.flowEnded=t.flowEnded,this.beatIndex=t.beatIndex,this.currentSceneId=t.currentSceneId,this.stack=t.stack.map(r=>{let{nextId:s,...i}=r;if(s!==void 0){let o=this.childrenOf(i.containerId)?.findIndex(a=>a.id===s)??-1;if(o>=0)return{...i,index:o}}return{...i}}),this.sceneBags=new Map(Object.entries(e.sceneBags??{}).map(([r,s])=>{let i=this.host.sceneSharedNames.get(r)??new Set,o=(this.host.bundle.scenes[r]?.sceneProps??[]).filter(c=>!i.has(c.name.toLowerCase())),a=new b(o);return a.load(s),[r,a]})),this.local=this.freshLocal(),this.local.load(e.scopes),this.activeSnippet=null,t.activeSnippetId!==null){let r=this.host.nodeIndex.get(t.activeSnippetId);r&&r.type==="snippet"&&(this.activeSnippet=r)}if(this.selectors=ge(t.selectors),this.pendingChoice=null,t.pendingChoice!==null){let r=new Map,s=[];for(let i of t.pendingChoice.options){let o=this.host.nodeIndex.get(i.id);o&&(r.set(i.id,o),s.push({...i}))}s.length>0&&(this.pendingChoice={groupId:t.pendingChoice.groupId,options:s,byId:r})}if(this.pendingPromptBeat=null,this.pendingPromptOwnerId=t.pendingPromptOwnerId??null,this.pendingPromptOwnerId){let r=this.host.nodeIndex.get(this.pendingPromptOwnerId);this.pendingPromptBeat=r?this.promptBeatOf(r)??null:null,this.pendingPromptBeat||(this.pendingPromptOwnerId=null)}}enterSceneSetup(e){let t=this.host.bundle.scenes[e];if(!t)throw new Error(`unknown scene: ${e}`);this.currentSceneId=e,this.enter(e),this.seedScene(t),this.runEffects(t.onEntry)}enterChild(e){if(this.enter(e.id),e.type==="snippet"){this.beginSnippet(e);return}let t=e.selector??"run";if(t==="run"){this.stack.push({sceneId:this.currentSceneId,containerId:e.id,index:0});return}if(t==="choice"){this.setupChoice(e);return}let r=this.selectChild(e);r&&this.enterChild(r)}childrenOf(e){let t=this.host.blockById.get(e);if(t)return t.children;let r=this.host.nodeIndex.get(e);if(r&&r.type==="group")return r.children}beginSnippet(e){this.runEffects(e.onEnter),this.activeSnippet=e,this.beatIndex=0}setupChoice(e){let t=[],r=new Map,s=[];for(let o of e.children){if(o.fallback===!0){s.push(o);continue}if(o.sticky!==!0&&(this.visitCounts.get(o.id)??0)>=1)continue;let a=this.eligible(o),c=o.secretUntilEligible===!0;!a&&c||(t.push({id:o.id,prompt:this.promptFor(o),eligible:a,gameData:o.gameData}),r.set(o.id,o))}if(t.length>0){this.emit({type:"choice",group:e.id,options:t.map(o=>({id:o.id,eligible:o.eligible}))}),this.pendingChoice={groupId:e.id,options:t,byId:r};return}let i=s.find(o=>this.eligible(o));if(i){this.enterChild(i);return}this.emit({type:"dry",group:e.id}),this.host.onDryChoice?.(e.id)}resolveJump(e){e&&this.enterTarget(e.to,e.mode==="call"?"call":"jump")}enterTarget(e,t){if(this.emit({type:"jump",to:e,mode:t}),e==="END"){this.flowEnded=!0,this.stack=[];return}let r,s,i=this.host.bundle.scenes[e];if(i){this.enterSceneSetup(e);let a=i.blocks[0];if(!a){t==="jump"&&(this.stack=[]);return}r=e,s=a.id}else{let a=this.host.blockIndex.get(e);if(!a)throw new Error(`jump target not found: ${e}`);a.sceneId!==this.currentSceneId&&this.enterSceneSetup(a.sceneId),r=a.sceneId,s=e}this.enter(s);let o={sceneId:r,containerId:s,index:0};t==="call"?this.stack.push(o):this.stack=[o]}selectChild(e){let t=e.children.map(c=>({id:c.id,eligible:this.eligible(c)})),r=e.children.filter(c=>this.eligible(c)),s=e.options?.order??"sequential",i=e.options?.exhaust??"once",o=c=>(this.emit({type:"select",group:e.id,selector:e.selector??"default",...e.selector==="sequence"?{order:s,exhaust:i}:{},children:t,picked:c?.id??null}),c);if(r.length===0)return o(null);let a=this.selectorState(e);switch(e.selector){case"branch":return o(r[0]);case"sequence":return o(s==="shuffle"?this.pickShuffle(r,i,a):s==="specificity"?this.pickSpecificity(r,i,a):this.pickSequential(r,i,a));default:return null}}pickSequential(e,t,r){let s=e.length,i=r.seq??0;return r.seq=i+1,t==="repeat"?e[i%s]:i<s?e[i]:t==="stick"?e[s-1]:null}pickShuffle(e,t,r){let s=e.length,i=t==="stick",o=()=>(i?e.slice(0,s-1):e).map(u=>u.id);if(r.bag===void 0&&(r.bag=o()),r.bag.length===0){if(t==="once")return null;if(i){let u=e[s-1];return r.last=u.id,u}r.bag=o()}let a=r.bag,c=r.last!==void 0&&a.length>1?a.indexOf(r.last):-1,d=Math.floor(this.rng()*(c>=0?a.length-1:a.length));c>=0&&d>=c&&d++;let p=a[d];return a.splice(d,1),r.last=p,e.find(u=>u.id===p)}pickSpecificity(e,t,r){let s=e;if(t!=="repeat"){r.bag===void 0&&(r.bag=e.map(p=>p.id));let d=new Set(r.bag);if(s=e.filter(p=>d.has(p.id)),s.length===0)return t==="stick"&&r.last!==void 0?e.find(p=>p.id===r.last)??null:null}let i=-1,a=s.map(d=>{let p=this.specScore(d);return p>i&&(i=p),{c:d,s:p}}).filter(d=>d.s===i).map(d=>d.c),c;if(a.length===1)c=a[0];else{let d=r.last!==void 0?a.findIndex(u=>u.id===r.last):-1,p=Math.floor(this.rng()*(d>=0?a.length-1:a.length));d>=0&&p>=d&&p++,c=a[p]}return t!=="repeat"&&(r.bag=r.bag.filter(d=>d!==c.id)),r.last=c.id,c}specScore(e){return e.condition?this.matchedSpec(this.conditionAst(e.condition),!0):0}matchedSpec(e,t){return Q(e,s=>pe(B(s,this.evalCtx,q)),{want:t})}selectorState(e){let t=e.shared?this.host.sharedSelectors:this.selectors,r=t.get(e.id);return r||(r={},t.set(e.id,r)),r}runEffects(e){for(let t of e??[]){let r=this.evalExpr(t.value),s=this.host.logEnabled?this.getProperty(t.target):void 0;this.setProperty(t.target,r),this.emit({type:"write",target:t.target,value:r,...s!==void 0?{prev:s}:{}})}}eligible(e){return e.condition?pe(this.evalExpr(e.condition)):!0}evalExpr(e){return B(this.conditionAst(e),this.evalCtx,q)}conditionAst(e){let t=oe.get(e);return t||(t=w(e.ast),oe.set(e,t)),t}enter(e){this.visitCounts.set(e,(this.visitCounts.get(e)??0)+1),this.host.sharedVisits.set(e,(this.host.sharedVisits.get(e)??0)+1)}rng=()=>{if(this.host.customRng)return this.host.customRng();let e=j(this.rngState),t=e.next();return this.rngState=e.state(),t};beatResult(e){let t=this.host.tagIndex.get(e.id),r=t&&t.length?{tags:t}:{};switch(e.kind){case"gameEvent":return{type:"gameEvent",id:e.id,gameData:e.gameData,...r};case"text":return{type:"text",id:e.id,text:this.interpolate(this.resolveString(e.id)),gameData:e.gameData,...r};case"line":{let s=this.resolveString(e.id),i=!this.host.captionsOn,a=i&&e.character===this.host.captionCharacter?"":this.captionLine(this.host.bundle.voiced?s:this.interpolate(s)),c=i&&a.length===0;return{type:"line",id:e.id,text:a,character:c?void 0:e.character,characterName:c?void 0:this.resolveCharacterName(e.character),direction:c?void 0:e.direction,gameData:e.gameData,...r}}}}interpolate(e){return se(e,t=>this.getProperty(t))}stripCaptions(e){return ne(e,this.host.captionOpen,this.host.captionClose)}captionLine(e){return this.host.captionsOn?e:this.stripCaptions(e)}promptFor(e){let t=this.promptBeatOf(e);if(!t)return;let r=this.interpolate(this.resolveString(t.id));return t.kind==="line"?{kind:"line",text:this.captionLine(r),character:t.character,characterName:this.resolveCharacterName(t.character),direction:t.direction}:{kind:"text",text:r}}promptBeatOf(e){return e.type==="group"&&e.prompt?e.prompt:((e.type==="snippet"?e:this.firstTextSnippetIn(e.children))?.beats??[]).find(r=>r.kind==="line"||r.kind==="text")}firstTextSnippetIn(e){let t;return k(e,r=>{!t&&r.type==="snippet"&&(r.beats??[]).some(s=>s.kind==="line"||s.kind==="text")&&(t=r)}),t}resolveString(e){if(this.host.emitIds)return e;let t=this.host.strings[e];if(t!==void 0)return t;let r=this.host.defaultStrings[e];return r!==void 0?`<Untranslated: ${e}> ${r}`:e}resolveCharacterName(e){if(e===void 0||this.host.emitIds)return;let t=_(e);return this.host.strings[t]??this.host.defaultStrings[t]??this.host.castDisplay.get(e)}splitRef(e){let t=this.host.refSplitCache.get(e);return t||(t=H(e,r=>r==="scene"||this.host.shared.has(r)),this.host.refSplitCache.set(e,t)),t}freshLocal(){return new D().defineOwned("patter",this.host.patterLocalDecls,"@patter.")}seedScene(e){let t=this.host.sceneSharedNames.get(e.id)??new Set,r=e.sceneProps??[];this.sceneBags.has(e.id)||this.sceneBags.set(e.id,new b(r.filter(s=>!t.has(s.name.toLowerCase())))),this.host.stageBags.has(e.id)||this.host.stageBags.set(e.id,new b(r.filter(s=>t.has(s.name.toLowerCase()))));for(let s of e.sceneProps??[]){if(!s.temporary)continue;let i=s.name.toLowerCase(),o=t.has(i)?this.host.stageBags.get(e.id):this.sceneBags.get(e.id);o&&o.set(i,E(s))}}};function ae(n,e){k(n,t=>{if(t.type==="group"){t.prompt?.kind==="line"&&t.prompt.character&&e.add(t.prompt.character);return}for(let r of t.beats??[])r.kind==="line"&&r.character&&e.add(r.character)})}function de(n){let e={};for(let[t,r]of n){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e[t]=s}return e}function ge(n){let e=new Map;for(let[t,r]of Object.entries(n??{})){let s={};r.seq!==void 0&&(s.seq=r.seq),r.bag&&(s.bag=[...r.bag]),r.last!==void 0&&(s.last=r.last),e.set(t,s)}return e}function ce(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default}}function le(n){return{name:n.name,type:n.type,values:n.values,stages:n.stages,default:n.default,writable:n.writable}}function Te(n){let e=r=>r.toLowerCase(),t=new Map;for(let r of n)t.set(e(r.name),E(r));return{get:r=>t.get(e(r)),set:(r,s)=>{t.set(e(r),s)}}}function pe(n){return typeof n=="boolean"?n:typeof n=="number"?n!==0:typeof n=="string"?n!=="":n.length>0}var Ae=(n,e)=>n.shared??e;function W(n,e){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.default!==void 0?{default:n.default}:{},shared:Ae(n,e)}}function Fe(n){return{name:n.name,type:n.type,hasDefault:n.default!==void 0,...n.values?{values:[...n.values]}:{},...n.purpose?{purpose:n.purpose}:{}}}function Ge(n,e){e.blocks++;let t=[...n.children];for(;t.length;){let r=t.pop();if(r.type==="group"){e.groups++,r.prompt&&e.prompts++,t.push(...r.children);continue}e.snippets++;for(let s of r.beats??[])e.beats++,s.kind==="gameEvent"&&e.gameEvents++}}function ue(n){let e={scenes:0,blocks:0,groups:0,snippets:0,beats:0,prompts:0,gameEvents:0,cast:n.cast?.length??0},t=[],r=[];for(let o of Object.values(n.scenes)){e.scenes++;let a=h(o);t.push({gameId:a,name:o.name,blocks:o.blocks.map(c=>({gameId:h(c),name:c.name}))});for(let c of o.blocks)Ge(c,e);o.sceneProps?.length&&r.push({gameId:a,properties:o.sceneProps.map(c=>W(c,!1))})}let s=(n.scopeRegistry?.scopes??[]).map(o=>({token:o.token,writable:o.writable??!0,opaque:o.declarations===void 0,properties:(o.declarations??[]).map(a=>W(a,!0))})),i=Object.entries(n.gameDataFields??{}).filter(([,o])=>(o?.length??0)>0).map(([o,a])=>({kind:o,fields:(a??[]).map(Fe)}));return{identity:{schema:n.schema,project:n.content.project,...n.content.version!==void 0?{version:n.content.version}:{},...n.content.hash!==void 0?{hash:n.content.hash}:{},...n.content.structureHash!==void 0?{structureHash:n.content.structureHash}:{},voiced:n.voiced,defaultLocale:n.locales.default,locales:[...n.locales.included],localisation:n.localisation?.mode??"embedded",sourceDebug:n.localisation?.sourceDebug??!1},addresses:t,hostScopes:s,properties:{patter:(n.properties??[]).map(o=>W(o,!0)),scene:r},gameData:i,counts:e}}function he(n,e){return n.gameDataFields?.[e]??[]}function K(n,e,t){return e&&Object.prototype.hasOwnProperty.call(e,t)?e[t]:n.find(r=>r.name===t)?.default}function fe(n,e){let t={};for(let r of n){let s=K(n,e,r.name);s!==void 0&&(t[r.name]=s)}for(let[r,s]of Object.entries(e??{}))r in t||(t[r]=s);return t}return Ee(Ve);})();\n//# sourceMappingURL=patterplay.min.js.map';
194982
195013
 
194983
195014
  // ../ops/src/export-html.ts
194984
195015
  var esc = (s) => s.replace(/[&<>]/g, (c2) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;" })[c2]);
@@ -195227,8 +195258,12 @@ var PropertyBag = class _PropertyBag {
195227
195258
  * long-standing contract); a product whose names are case-significant
195228
195259
  * passes identity. */
195229
195260
  norm;
195261
+ /** The address prefix this bag's rows carry, separator included (`@`,
195262
+ * `@scene.`, `world.`, `deck.<id>.`). Empty means a row's path is its name. */
195263
+ pathPrefix;
195230
195264
  constructor(declarations = [], opts) {
195231
195265
  this.norm = opts?.normalise ?? ((n) => n.toLowerCase());
195266
+ this.pathPrefix = opts?.pathPrefix ?? "";
195232
195267
  this.seed(declarations);
195233
195268
  }
195234
195269
  seed(declarations) {
@@ -195272,7 +195307,7 @@ var PropertyBag = class _PropertyBag {
195272
195307
  /** Examiner rows: the declared surface only (stray values are storage,
195273
195308
  * not surface). */
195274
195309
  rows() {
195275
- return [...this.decls.entries()].map(([name, d]) => rowFor(d, this.get(name), void 0, name));
195310
+ return [...this.decls.entries()].map(([name, d]) => rowFor(d, this.get(name), void 0, name, this.pathPrefix));
195276
195311
  }
195277
195312
  declarations() {
195278
195313
  return [...this.decls.values()];
@@ -195281,7 +195316,7 @@ var PropertyBag = class _PropertyBag {
195281
195316
  * duplicated, the normalisation policy carried, subscriptions NOT
195282
195317
  * carried. */
195283
195318
  clone() {
195284
- const c2 = new _PropertyBag([], { normalise: this.norm });
195319
+ const c2 = new _PropertyBag([], { normalise: this.norm, pathPrefix: this.pathPrefix });
195285
195320
  c2.decls = new Map(this.decls);
195286
195321
  Object.assign(c2.values, structuredClone(this.values));
195287
195322
  return c2;
@@ -195304,13 +195339,19 @@ var PropertyBag = class _PropertyBag {
195304
195339
  for (const [k, v] of Object.entries(values)) this.values[this.norm(k)] = v;
195305
195340
  }
195306
195341
  };
195307
- function rowFor(d, value, writable, name) {
195342
+ function rowFor(d, value, writable, name, pathPrefix = "") {
195343
+ const rowName = name ?? d.name.toLowerCase();
195308
195344
  return {
195309
- name: name ?? d.name.toLowerCase(),
195345
+ name: rowName,
195346
+ path: pathPrefix + rowName,
195310
195347
  type: d.type,
195311
195348
  value,
195312
195349
  default: d.default ?? defaultFor(d),
195313
195350
  ...d.values !== void 0 ? { values: d.values } : {},
195351
+ // `stages` was added to the row so an examiner could offer a quality's ladder
195352
+ // instead of a free-text box, and then never populated here: every quality row
195353
+ // this function built came out without one. Fixed 2026-09-02.
195354
+ ...d.stages !== void 0 ? { stages: d.stages } : {},
195314
195355
  writable: writable ?? d.writable ?? true
195315
195356
  };
195316
195357
  }
@@ -195322,8 +195363,8 @@ var ScopeRegistry = class {
195322
195363
  * each declaration's `default` (or a type default). Owned scopes are
195323
195364
  * type-checked (declarations) and serialized by `save`/`load`.
195324
195365
  */
195325
- defineOwned(token2, declarations) {
195326
- return this.mountOwned(token2, new PropertyBag(declarations));
195366
+ defineOwned(token2, declarations, pathPrefix) {
195367
+ return this.mountOwned(token2, new PropertyBag(declarations, { pathPrefix: pathPrefix ?? `${token2}.` }));
195327
195368
  }
195328
195369
  /**
195329
195370
  * Attach an EXISTING bag as an owned scope - the shared-container move: a
@@ -195408,7 +195449,13 @@ var ScopeRegistry = class {
195408
195449
  for (const d of e.decls.values()) {
195409
195450
  out.push({
195410
195451
  scope: token2,
195411
- ...rowFor(d, e.resolver.get(d.name.toLowerCase()), this.foreignWritable(e, d.name.toLowerCase()))
195452
+ ...rowFor(
195453
+ d,
195454
+ e.resolver.get(d.name.toLowerCase()),
195455
+ this.foreignWritable(e, d.name.toLowerCase()),
195456
+ void 0,
195457
+ `${token2}.`
195458
+ )
195412
195459
  });
195413
195460
  }
195414
195461
  }
@@ -195519,6 +195566,13 @@ function defaultFor(d) {
195519
195566
  // A quality starts at the first rung of its ladder.
195520
195567
  case "quality":
195521
195568
  return d.stages?.[0] ?? "";
195569
+ // Unreachable for a well-typed declaration, and deliberately present anyway: a bundle
195570
+ // is DATA, and a hand-edited or newer-than-this-build one can carry a type string the
195571
+ // union does not have. Falling off the switch would seed `undefined`, which is not a
195572
+ // ScalarValue and travels a long way before it fails. Patterplay's copy of this had the
195573
+ // guard and this one did not, which is the drift you only find by removing a duplicate.
195574
+ default:
195575
+ return false;
195522
195576
  }
195523
195577
  }
195524
195578
 
@@ -195577,6 +195631,10 @@ var Engine = class _Engine {
195577
195631
  /** The options this engine was built with - reused verbatim by `hotSwap` so the replacement
195578
195632
  * engine keeps the same world resolver, custom RNG, and diagnostic hooks. */
195579
195633
  creationOptions;
195634
+ /** The run's ordered stream: every flow's events, each naming its flow. Empty and
195635
+ * unwritten unless `options.log` asked for it. */
195636
+ engineLog = [];
195637
+ engineTraceHandlers = /* @__PURE__ */ new Set();
195580
195638
  constructor(bundle, options = {}) {
195581
195639
  this.creationOptions = options;
195582
195640
  const locale = options.locale ?? bundle.locales.default;
@@ -195612,7 +195670,7 @@ var Engine = class _Engine {
195612
195670
  const patterSharedDecls = props.filter((p) => p.shared ?? true).map(toDecl);
195613
195671
  const patterLocalDecls = props.filter((p) => !(p.shared ?? true)).map(toDecl);
195614
195672
  const patterSharedNames = new Set(patterSharedDecls.map((d) => d.name.toLowerCase()));
195615
- const shared = new ScopeRegistry().defineOwned("patter", patterSharedDecls);
195673
+ const shared = new ScopeRegistry().defineOwned("patter", patterSharedDecls, "@patter.");
195616
195674
  const hostBound = /* @__PURE__ */ new Set();
195617
195675
  if (options.world) {
195618
195676
  const worldSpec = bundle.scopeRegistry?.scopes.find((s) => s.token === "world");
@@ -195631,6 +195689,8 @@ var Engine = class _Engine {
195631
195689
  sceneSharedNames.set(sceneId, names);
195632
195690
  }
195633
195691
  this.host = {
195692
+ logEnabled: options.log ?? false,
195693
+ emitEngine: (flow, event, scene) => this.emitEngine(flow, event, scene),
195634
195694
  bundle,
195635
195695
  emitIds,
195636
195696
  strings,
@@ -196005,14 +196065,44 @@ var Engine = class _Engine {
196005
196065
  }
196006
196066
  /** The shared `@patter` properties, for a live state inspector: each with its ref, type, current
196007
196067
  * value, declared default (for reset), and enum options. Mirrors the Unity / Godot ports. */
196068
+ /** The run's decisions, in order, each naming the flow it happened in. Empty unless the
196069
+ * run was opened with `log: true`. A flow's own log stays flow-local; this is the only
196070
+ * place a story spanning several flows reads as one sequence. */
196071
+ log() {
196072
+ return this.engineLog;
196073
+ }
196074
+ /** Drop the retained entries. `seq` does NOT restart: two reads of a log either side of a
196075
+ * clear still agree about what came first. */
196076
+ clearLog() {
196077
+ this.engineLog.length = 0;
196078
+ }
196079
+ /** Live tap on the run's decisions, for tooling that wants them as they happen rather than
196080
+ * retained. Returns its own unsubscribe. */
196081
+ onTrace(handler) {
196082
+ this.engineTraceHandlers.add(handler);
196083
+ return () => this.engineTraceHandlers.delete(handler);
196084
+ }
196085
+ emitEngine(flow, event, scene) {
196086
+ for (const h of this.engineTraceHandlers) h(flow, event);
196087
+ if (!this.host.logEnabled) return;
196088
+ this.engineLog.push({ ...event, flow, seq: this.engineLog.length, ...scene ? { scene } : {} });
196089
+ }
196008
196090
  listProperties() {
196009
196091
  return this.host.patterSharedDecls.map((d) => ({
196010
- ref: `@${d.name}`,
196092
+ name: d.name,
196093
+ // The qualified address, matching what the bag composes for every other scope.
196094
+ // `@gold` still resolves on input; it is the shorthand, not the address.
196095
+ path: `@patter.${d.name}`,
196011
196096
  type: d.type,
196012
196097
  values: d.values,
196013
196098
  stages: d.stages,
196014
196099
  value: this.getProperty(`@${d.name}`),
196015
- default: declDefault(d)
196100
+ default: defaultFor(d),
196101
+ // Part of the shared row. Always true here today: `toDecl` never sets it, because
196102
+ // Patter has no read-only shared property. The Storylet Engine does declare them
196103
+ // and its panels disable the editor accordingly, so the field is carried rather
196104
+ // than dropped - and the day a read-only @patter property exists, the row says so.
196105
+ writable: d.writable ?? true
196016
196106
  }));
196017
196107
  }
196018
196108
  // @scene is scene-namespaced and needs a flow's current scene - silently
@@ -196045,7 +196135,7 @@ var Engine = class _Engine {
196045
196135
  shared: this.host.shared.save(),
196046
196136
  sharedVisits: Object.fromEntries(this.host.sharedVisits),
196047
196137
  sharedSelectors: serialiseSelectors(this.host.sharedSelectors),
196048
- stageBags: Object.fromEntries([...this.host.stageBags].map(([s, bag]) => [s, { ...bag }])),
196138
+ stageBags: Object.fromEntries([...this.host.stageBags].map(([s, bag]) => [s, bag.save()])),
196049
196139
  flows
196050
196140
  };
196051
196141
  }
@@ -196058,7 +196148,13 @@ var Engine = class _Engine {
196058
196148
  this.host.sharedSelectors.clear();
196059
196149
  for (const [id, st] of deserialiseSelectors(save.sharedSelectors)) this.host.sharedSelectors.set(id, st);
196060
196150
  this.host.stageBags.clear();
196061
- for (const [s, bag] of Object.entries(save.stageBags ?? {})) this.host.stageBags.set(s, { ...bag });
196151
+ for (const [s, values] of Object.entries(save.stageBags ?? {})) {
196152
+ const shared = this.host.sceneSharedNames.get(s) ?? /* @__PURE__ */ new Set();
196153
+ const decls = (this.host.bundle.scenes[s]?.sceneProps ?? []).filter((d) => shared.has(d.name.toLowerCase()));
196154
+ const bag = new PropertyBag(decls);
196155
+ bag.load(values);
196156
+ this.host.stageBags.set(s, bag);
196157
+ }
196062
196158
  this.flowsById.clear();
196063
196159
  for (const [id, snap] of Object.entries(save.flows)) {
196064
196160
  const flow = new Flow(id, this.host, this.defaultSeed);
@@ -196101,6 +196197,7 @@ var Flow = class {
196101
196197
  // The SHARED halves live on the host (`host.shared` / `host.stageBags`). Each
196102
196198
  // resolver presents one merged scope, routing each property to its half by the
196103
196199
  // declared `shared` flag.
196200
+ /** This flow's per-scene LOCAL scene props; see FlowHost.stageBags. */
196104
196201
  sceneBags = /* @__PURE__ */ new Map();
196105
196202
  patterResolver = {
196106
196203
  get: (n) => this.host.patterSharedNames.has(n) ? this.host.shared.get("patter", n) : this.local.get("patter", n),
@@ -196114,13 +196211,13 @@ var Flow = class {
196114
196211
  const s = this.currentSceneId;
196115
196212
  if (s === null) return void 0;
196116
196213
  const bag = this.host.sceneSharedNames.get(s)?.has(n) ? this.host.stageBags.get(s) : this.sceneBags.get(s);
196117
- return bag?.[n];
196214
+ return bag?.get(n);
196118
196215
  },
196119
196216
  set: (n, v) => {
196120
196217
  const s = this.currentSceneId;
196121
196218
  if (s === null) return;
196122
196219
  const bag = this.host.sceneSharedNames.get(s)?.has(n) ? this.host.stageBags.get(s) : this.sceneBags.get(s);
196123
- if (bag) bag[n] = v;
196220
+ if (bag) bag.set(n, v);
196124
196221
  }
196125
196222
  };
196126
196223
  // The eval context is built ONCE: every constituent resolves live state at
@@ -196129,10 +196226,13 @@ var Flow = class {
196129
196226
  // `local`/`sceneBags`/`currentSceneId`; the host callbacks read current flow
196130
196227
  // fields). Rebuilding it per evaluation was the engine's hottest allocation.
196131
196228
  evalCtx;
196229
+ flowLog = [];
196230
+ /** Monotonic across the flow's life; survives clearLog so two reads agree on order. */
196231
+ flowSeq = 0;
196132
196232
  constructor(id, host2, seed) {
196133
196233
  this.id = id;
196134
196234
  this.host = host2;
196135
- this.rngState = seed >>> 0;
196235
+ this.rngState = toUint32(seed);
196136
196236
  this.local = this.freshLocal();
196137
196237
  const scopes = { ...host2.shared.toEvalContext().scopes };
196138
196238
  scopes["patter"] = this.patterResolver;
@@ -196354,7 +196454,17 @@ var Flow = class {
196354
196454
  this.stack.pop();
196355
196455
  continue;
196356
196456
  }
196457
+ const from = frame.index;
196357
196458
  while (frame.index < children.length && !this.eligible(children[frame.index])) frame.index++;
196459
+ if (this.host.logEnabled && frame.index !== from) {
196460
+ this.emit({
196461
+ type: "select",
196462
+ group: frame.containerId,
196463
+ selector: "run",
196464
+ children: children.slice(from, frame.index + 1).map((c2, i) => ({ id: c2.id, eligible: from + i === frame.index })),
196465
+ picked: children[frame.index]?.id ?? null
196466
+ });
196467
+ }
196358
196468
  if (frame.index >= children.length) {
196359
196469
  this.stack.pop();
196360
196470
  continue;
@@ -196363,6 +196473,24 @@ var Flow = class {
196363
196473
  }
196364
196474
  }
196365
196475
  /** The options of a pending choice (empty when not at a choice point). */
196476
+ /** This flow's decisions, in order. Empty unless the run was opened with `log: true`.
196477
+ * The engine's log carries the same events tagged with the flow; this one is what a
196478
+ * single conversation reads as. */
196479
+ log() {
196480
+ return this.flowLog;
196481
+ }
196482
+ /** Drop the retained entries. `seq` keeps counting, so order survives a clear. */
196483
+ clearLog() {
196484
+ this.flowLog.length = 0;
196485
+ }
196486
+ /** Record one decision, on this flow's log and the engine's. Cheap to call with logging
196487
+ * off: the entry is never built. */
196488
+ emit(event) {
196489
+ const scene = this.currentSceneId ?? void 0;
196490
+ this.host.emitEngine(this.id, event, scene);
196491
+ if (!this.host.logEnabled) return;
196492
+ this.flowLog.push({ ...event, seq: this.flowSeq++, ...scene ? { scene } : {} });
196493
+ }
196366
196494
  getChoices() {
196367
196495
  return this.pendingChoice?.options ?? [];
196368
196496
  }
@@ -196374,6 +196502,7 @@ var Flow = class {
196374
196502
  if (!option) throw new Error(`unknown choice option: ${id}`);
196375
196503
  if (!option.eligible) throw new Error(`choice option is not eligible: ${id}`);
196376
196504
  const node = choice.byId.get(id);
196505
+ this.emit({ type: "chose", group: choice.groupId, option: id });
196377
196506
  this.pendingChoice = null;
196378
196507
  this.pendingPromptBeat = this.host.replayPromptOnChoose ? this.promptBeatOf(node) ?? null : null;
196379
196508
  this.pendingPromptOwnerId = this.pendingPromptBeat ? node.id : null;
@@ -196407,7 +196536,7 @@ var Flow = class {
196407
196536
  return {
196408
196537
  scopes: this.local.save(),
196409
196538
  // owned scope "patter" = the NOT-shared globals (@scene saved separately)
196410
- sceneBags: Object.fromEntries([...this.sceneBags].map(([s, bag]) => [s, { ...bag }])),
196539
+ sceneBags: Object.fromEntries([...this.sceneBags].map(([s, bag]) => [s, bag.save()])),
196411
196540
  rngState: this.rngState,
196412
196541
  visits: Object.fromEntries(this.visitCounts),
196413
196542
  cursor: {
@@ -196430,7 +196559,7 @@ var Flow = class {
196430
196559
  }
196431
196560
  /** @internal Restore this flow from a snapshot. */
196432
196561
  restore(snap) {
196433
- this.rngState = snap.rngState >>> 0;
196562
+ this.rngState = toUint32(snap.rngState);
196434
196563
  this.visitCounts = new Map(Object.entries(snap.visits ?? {}));
196435
196564
  const c2 = snap.cursor;
196436
196565
  this.started = true;
@@ -196445,7 +196574,13 @@ var Flow = class {
196445
196574
  }
196446
196575
  return { ...frame };
196447
196576
  });
196448
- this.sceneBags = new Map(Object.entries(snap.sceneBags ?? {}).map(([s, bag]) => [s, { ...bag }]));
196577
+ this.sceneBags = new Map(Object.entries(snap.sceneBags ?? {}).map(([s, values]) => {
196578
+ const shared = this.host.sceneSharedNames.get(s) ?? /* @__PURE__ */ new Set();
196579
+ const decls = (this.host.bundle.scenes[s]?.sceneProps ?? []).filter((d) => !shared.has(d.name.toLowerCase()));
196580
+ const bag = new PropertyBag(decls);
196581
+ bag.load(values);
196582
+ return [s, bag];
196583
+ }));
196449
196584
  this.local = this.freshLocal();
196450
196585
  this.local.load(snap.scopes);
196451
196586
  this.activeSnippet = null;
@@ -196539,6 +196674,7 @@ var Flow = class {
196539
196674
  byId.set(child.id, child);
196540
196675
  }
196541
196676
  if (options.length > 0) {
196677
+ this.emit({ type: "choice", group: group.id, options: options.map((o) => ({ id: o.id, eligible: o.eligible })) });
196542
196678
  this.pendingChoice = { groupId: group.id, options, byId };
196543
196679
  return;
196544
196680
  }
@@ -196547,6 +196683,7 @@ var Flow = class {
196547
196683
  this.enterChild(fallback2);
196548
196684
  return;
196549
196685
  }
196686
+ this.emit({ type: "dry", group: group.id });
196550
196687
  this.host.onDryChoice?.(group.id);
196551
196688
  }
196552
196689
  // -- Jumps (jump / call-return) ----------------------------------------
@@ -196561,6 +196698,7 @@ var Flow = class {
196561
196698
  * hard-ends the flow regardless of the callstack.
196562
196699
  */
196563
196700
  enterTarget(to, mode) {
196701
+ this.emit({ type: "jump", to, mode });
196564
196702
  if (to === "END") {
196565
196703
  this.flowEnded = true;
196566
196704
  this.stack = [];
@@ -196592,17 +196730,28 @@ var Flow = class {
196592
196730
  }
196593
196731
  // -- Selectors ------------------------------------------------------------
196594
196732
  selectChild(group) {
196733
+ const verdicts = group.children.map((c2) => ({ id: c2.id, eligible: this.eligible(c2) }));
196595
196734
  const eligible = group.children.filter((c2) => this.eligible(c2));
196596
- if (eligible.length === 0) return null;
196735
+ const order = group.options?.order ?? "sequential";
196736
+ const exhaust = group.options?.exhaust ?? "once";
196737
+ const trace = (picked) => {
196738
+ this.emit({
196739
+ type: "select",
196740
+ group: group.id,
196741
+ selector: group.selector ?? "default",
196742
+ ...group.selector === "sequence" ? { order, exhaust } : {},
196743
+ children: verdicts,
196744
+ picked: picked?.id ?? null
196745
+ });
196746
+ return picked;
196747
+ };
196748
+ if (eligible.length === 0) return trace(null);
196597
196749
  const st = this.selectorState(group);
196598
196750
  switch (group.selector) {
196599
196751
  case "branch":
196600
- return eligible[0];
196601
- case "sequence": {
196602
- const order = group.options?.order ?? "sequential";
196603
- const exhaust = group.options?.exhaust ?? "once";
196604
- return order === "shuffle" ? this.pickShuffle(eligible, exhaust, st) : order === "specificity" ? this.pickSpecificity(eligible, exhaust, st) : this.pickSequential(eligible, exhaust, st);
196605
- }
196752
+ return trace(eligible[0]);
196753
+ case "sequence":
196754
+ return trace(order === "shuffle" ? this.pickShuffle(eligible, exhaust, st) : order === "specificity" ? this.pickSpecificity(eligible, exhaust, st) : this.pickSequential(eligible, exhaust, st));
196606
196755
  case "run":
196607
196756
  case "choice":
196608
196757
  default:
@@ -196720,7 +196869,10 @@ var Flow = class {
196720
196869
  // -- Effects + expressions ------------------------------------------------
196721
196870
  runEffects(effects) {
196722
196871
  for (const e of effects ?? []) {
196723
- this.setProperty(e.target, this.evalExpr(e.value));
196872
+ const value = this.evalExpr(e.value);
196873
+ const prev = this.host.logEnabled ? this.getProperty(e.target) : void 0;
196874
+ this.setProperty(e.target, value);
196875
+ this.emit({ type: "write", target: e.target, value, ...prev !== void 0 ? { prev } : {} });
196724
196876
  }
196725
196877
  }
196726
196878
  eligible(node) {
@@ -196745,14 +196897,19 @@ var Flow = class {
196745
196897
  this.visitCounts.set(id, (this.visitCounts.get(id) ?? 0) + 1);
196746
196898
  this.host.sharedVisits.set(id, (this.host.sharedVisits.get(id) ?? 0) + 1);
196747
196899
  }
196748
- /** Next float in [0, 1): the shared custom PRNG, or this flow's serialisable mulberry32. */
196900
+ /** Next float in [0, 1): the shared custom PRNG, or this flow's serialisable mulberry32.
196901
+ *
196902
+ * The mixing is @wildwinter/expr's makePrng, not a copy inline here. It is a
196903
+ * fixed published algorithm that both product families need and neither
196904
+ * owns, and it existed thirteen times across the two of them. `rngState` is
196905
+ * still the serialisable position, so saves are unaffected: a generator is
196906
+ * made from it, drawn once, and the new state written back. */
196749
196907
  rng = () => {
196750
196908
  if (this.host.customRng) return this.host.customRng();
196751
- const a = this.rngState + 1831565813 | 0;
196752
- this.rngState = a;
196753
- let t = Math.imul(a ^ a >>> 15, 1 | a);
196754
- t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
196755
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
196909
+ const prng = makePrng(this.rngState);
196910
+ const draw = prng.next();
196911
+ this.rngState = prng.state();
196912
+ return draw;
196756
196913
  };
196757
196914
  // -- Strings / beats ------------------------------------------------------
196758
196915
  beatResult(beat) {
@@ -196859,7 +197016,7 @@ var Flow = class {
196859
197016
  }
196860
197017
  /** The per-flow registry: the NOT-shared `@patter` globals (the shared ones live on the host). */
196861
197018
  freshLocal() {
196862
- return new ScopeRegistry().defineOwned("patter", this.host.patterLocalDecls);
197019
+ return new ScopeRegistry().defineOwned("patter", this.host.patterLocalDecls, "@patter.");
196863
197020
  }
196864
197021
  /**
196865
197022
  * Seed a scene's `@scene` props (spec §7). The not-shared props seed THIS flow's
@@ -196870,27 +197027,18 @@ var Flow = class {
196870
197027
  */
196871
197028
  seedScene(scene) {
196872
197029
  const shared = this.host.sceneSharedNames.get(scene.id) ?? /* @__PURE__ */ new Set();
197030
+ const props = scene.sceneProps ?? [];
196873
197031
  if (!this.sceneBags.has(scene.id)) {
196874
- const bag = {};
196875
- for (const decl of scene.sceneProps ?? []) {
196876
- const name = decl.name.toLowerCase();
196877
- if (!shared.has(name)) bag[name] = sceneDefault(decl);
196878
- }
196879
- this.sceneBags.set(scene.id, bag);
197032
+ this.sceneBags.set(scene.id, new PropertyBag(props.filter((d) => !shared.has(d.name.toLowerCase()))));
196880
197033
  }
196881
197034
  if (!this.host.stageBags.has(scene.id)) {
196882
- const bag = {};
196883
- for (const decl of scene.sceneProps ?? []) {
196884
- const name = decl.name.toLowerCase();
196885
- if (shared.has(name)) bag[name] = sceneDefault(decl);
196886
- }
196887
- this.host.stageBags.set(scene.id, bag);
197035
+ this.host.stageBags.set(scene.id, new PropertyBag(props.filter((d) => shared.has(d.name.toLowerCase()))));
196888
197036
  }
196889
197037
  for (const decl of scene.sceneProps ?? []) {
196890
197038
  if (!decl.temporary) continue;
196891
197039
  const name = decl.name.toLowerCase();
196892
197040
  const bag = shared.has(name) ? this.host.stageBags.get(scene.id) : this.sceneBags.get(scene.id);
196893
- if (bag) bag[name] = sceneDefault(decl);
197041
+ if (bag) bag.set(name, defaultFor(decl));
196894
197042
  }
196895
197043
  }
196896
197044
  };
@@ -196928,47 +197076,13 @@ function deserialiseSelectors(rec) {
196928
197076
  function toDecl(decl) {
196929
197077
  return { name: decl.name, type: decl.type, values: decl.values, stages: decl.stages, default: decl.default };
196930
197078
  }
196931
- function declDefault(d) {
196932
- if (d.default !== void 0) return d.default;
196933
- switch (d.type) {
196934
- case "number":
196935
- return 0;
196936
- case "string":
196937
- return "";
196938
- case "flags":
196939
- return [];
196940
- case "enum":
196941
- return d.values?.[0] ?? "";
196942
- case "quality":
196943
- return d.stages?.[0] ?? "";
196944
- default:
196945
- return false;
196946
- }
196947
- }
196948
197079
  function toForeignDecl(decl) {
196949
197080
  return { name: decl.name, type: decl.type, values: decl.values, stages: decl.stages, default: decl.default, writable: decl.writable };
196950
197081
  }
196951
- function hostScopeDefault(decl) {
196952
- if (decl.default !== void 0) return decl.default;
196953
- switch (decl.type) {
196954
- case "boolean":
196955
- return false;
196956
- case "number":
196957
- return 0;
196958
- case "string":
196959
- return "";
196960
- case "flags":
196961
- return [];
196962
- case "enum":
196963
- return decl.values?.[0] ?? "";
196964
- case "quality":
196965
- return decl.stages?.[0] ?? "";
196966
- }
196967
- }
196968
197082
  function selfBackedResolver(decls) {
196969
197083
  const key2 = (name) => name.toLowerCase();
196970
197084
  const bag = /* @__PURE__ */ new Map();
196971
- for (const d of decls) bag.set(key2(d.name), hostScopeDefault(d));
197085
+ for (const d of decls) bag.set(key2(d.name), defaultFor(d));
196972
197086
  return {
196973
197087
  get: (name) => bag.get(key2(name)),
196974
197088
  set: (name, value) => {
@@ -196976,23 +197090,6 @@ function selfBackedResolver(decls) {
196976
197090
  }
196977
197091
  };
196978
197092
  }
196979
- function sceneDefault(decl) {
196980
- if (decl.default !== void 0) return decl.default;
196981
- switch (decl.type) {
196982
- case "boolean":
196983
- return false;
196984
- case "number":
196985
- return 0;
196986
- case "string":
196987
- return "";
196988
- case "flags":
196989
- return [];
196990
- case "enum":
196991
- return decl.values?.[0] ?? "";
196992
- case "quality":
196993
- return decl.stages?.[0] ?? "";
196994
- }
196995
- }
196996
197093
  function truthy(v) {
196997
197094
  if (typeof v === "boolean") return v;
196998
197095
  if (typeof v === "number") return v !== 0;
@@ -197111,13 +197208,8 @@ var CADENCE_PROB = {
197111
197208
  often: 0.8
197112
197209
  };
197113
197210
  function mulberry32(seed) {
197114
- let a = seed >>> 0;
197115
- return () => {
197116
- a = a + 1831565813 | 0;
197117
- let t = Math.imul(a ^ a >>> 15, 1 | a);
197118
- t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
197119
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
197120
- };
197211
+ const prng = makePrng(seed);
197212
+ return () => prng.next();
197121
197213
  }
197122
197214
  function scanExpr(node, hostTokens, refs, proposals) {
197123
197215
  const refOf = (n) => n.kind === "scopedvar" && hostTokens.has(n.scope) ? `@${n.scope}.${n.name}` : void 0;
@@ -199086,14 +199178,14 @@ var require_events = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
199086
199178
  return ret2;
199087
199179
  }
199088
199180
  function once2(emitter, name) {
199089
- return new Promise(function(resolve6, reject2) {
199181
+ return new Promise(function(resolve7, reject2) {
199090
199182
  function errorListener(err) {
199091
199183
  emitter.removeListener(name, resolver);
199092
199184
  reject2(err);
199093
199185
  }
199094
199186
  function resolver() {
199095
199187
  if (typeof emitter.removeListener === "function") emitter.removeListener("error", errorListener);
199096
- resolve6([].slice.call(arguments));
199188
+ resolve7([].slice.call(arguments));
199097
199189
  }
199098
199190
  eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
199099
199191
  if (name !== "error") addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
@@ -201995,8 +202087,8 @@ var require_util5 = /* @__PURE__ */ __commonJSMin(((exports2) => {
201995
202087
  }
201996
202088
  function fn() {
201997
202089
  var promiseResolve, promiseReject;
201998
- var promise = new Promise(function(resolve6, reject2) {
201999
- promiseResolve = resolve6;
202090
+ var promise = new Promise(function(resolve7, reject2) {
202091
+ promiseResolve = resolve7;
202000
202092
  promiseReject = reject2;
202001
202093
  });
202002
202094
  var args = [];
@@ -202177,7 +202269,7 @@ var require_buffer_list2 = /* @__PURE__ */ __commonJSMin(((exports2, module2) =>
202177
202269
  },
202178
202270
  {
202179
202271
  key: "join",
202180
- value: function join7(s) {
202272
+ value: function join8(s) {
202181
202273
  if (this.length === 0) return "";
202182
202274
  var p = this.head;
202183
202275
  var ret2 = "" + p.data;
@@ -203362,14 +203454,14 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
203362
203454
  };
203363
203455
  }
203364
203456
  function readAndResolve(iter) {
203365
- var resolve6 = iter[kLastResolve];
203366
- if (resolve6 !== null) {
203457
+ var resolve7 = iter[kLastResolve];
203458
+ if (resolve7 !== null) {
203367
203459
  var data = iter[kStream].read();
203368
203460
  if (data !== null) {
203369
203461
  iter[kLastPromise] = null;
203370
203462
  iter[kLastResolve] = null;
203371
203463
  iter[kLastReject] = null;
203372
- resolve6(createIterResult(data, false));
203464
+ resolve7(createIterResult(data, false));
203373
203465
  }
203374
203466
  }
203375
203467
  }
@@ -203377,13 +203469,13 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
203377
203469
  process$1.nextTick(readAndResolve, iter);
203378
203470
  }
203379
203471
  function wrapForNext(lastPromise, iter) {
203380
- return function(resolve6, reject2) {
203472
+ return function(resolve7, reject2) {
203381
203473
  lastPromise.then(function() {
203382
203474
  if (iter[kEnded]) {
203383
- resolve6(createIterResult(void 0, true));
203475
+ resolve7(createIterResult(void 0, true));
203384
203476
  return;
203385
203477
  }
203386
- iter[kHandlePromise](resolve6, reject2);
203478
+ iter[kHandlePromise](resolve7, reject2);
203387
203479
  }, reject2);
203388
203480
  };
203389
203481
  }
@@ -203398,10 +203490,10 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
203398
203490
  var error = this[kError];
203399
203491
  if (error !== null) return Promise.reject(error);
203400
203492
  if (this[kEnded]) return Promise.resolve(createIterResult(void 0, true));
203401
- if (this[kStream].destroyed) return new Promise(function(resolve6, reject2) {
203493
+ if (this[kStream].destroyed) return new Promise(function(resolve7, reject2) {
203402
203494
  process$1.nextTick(function() {
203403
203495
  if (_this[kError]) reject2(_this[kError]);
203404
- else resolve6(createIterResult(void 0, true));
203496
+ else resolve7(createIterResult(void 0, true));
203405
203497
  });
203406
203498
  });
203407
203499
  var lastPromise = this[kLastPromise];
@@ -203419,13 +203511,13 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
203419
203511
  return this;
203420
203512
  }), _defineProperty2(_Object$setPrototypeO, "return", function _return() {
203421
203513
  var _this2 = this;
203422
- return new Promise(function(resolve6, reject2) {
203514
+ return new Promise(function(resolve7, reject2) {
203423
203515
  _this2[kStream].destroy(null, function(err) {
203424
203516
  if (err) {
203425
203517
  reject2(err);
203426
203518
  return;
203427
203519
  }
203428
- resolve6(createIterResult(void 0, true));
203520
+ resolve7(createIterResult(void 0, true));
203429
203521
  });
203430
203522
  });
203431
203523
  }), _Object$setPrototypeO), AsyncIteratorPrototype);
@@ -203447,15 +203539,15 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
203447
203539
  value: stream2._readableState.endEmitted,
203448
203540
  writable: true
203449
203541
  }), _defineProperty2(_Object$create, kHandlePromise, {
203450
- value: function value(resolve6, reject2) {
203542
+ value: function value(resolve7, reject2) {
203451
203543
  var data = iterator[kStream].read();
203452
203544
  if (data) {
203453
203545
  iterator[kLastPromise] = null;
203454
203546
  iterator[kLastResolve] = null;
203455
203547
  iterator[kLastReject] = null;
203456
- resolve6(createIterResult(data, false));
203548
+ resolve7(createIterResult(data, false));
203457
203549
  } else {
203458
- iterator[kLastResolve] = resolve6;
203550
+ iterator[kLastResolve] = resolve7;
203459
203551
  iterator[kLastReject] = reject2;
203460
203552
  }
203461
203553
  },
@@ -203474,12 +203566,12 @@ var require_async_iterator2 = /* @__PURE__ */ __commonJSMin(((exports2, module2)
203474
203566
  iterator[kError] = err;
203475
203567
  return;
203476
203568
  }
203477
- var resolve6 = iterator[kLastResolve];
203478
- if (resolve6 !== null) {
203569
+ var resolve7 = iterator[kLastResolve];
203570
+ if (resolve7 !== null) {
203479
203571
  iterator[kLastPromise] = null;
203480
203572
  iterator[kLastResolve] = null;
203481
203573
  iterator[kLastReject] = null;
203482
- resolve6(createIterResult(void 0, true));
203574
+ resolve7(createIterResult(void 0, true));
203483
203575
  }
203484
203576
  iterator[kEnded] = true;
203485
203577
  });
@@ -214845,7 +214937,7 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
214845
214937
  }
214846
214938
  }
214847
214939
  function add(value, last2) {
214848
- format(append, resolve6(value, indent, indent ? 1 : 0), last2);
214940
+ format(append, resolve7(value, indent, indent ? 1 : 0), last2);
214849
214941
  }
214850
214942
  function end() {
214851
214943
  if (stream2) {
@@ -214884,12 +214976,12 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
214884
214976
  return output;
214885
214977
  }
214886
214978
  function element() {
214887
- var self2 = { _elem: resolve6(Array.prototype.slice.call(arguments)) };
214979
+ var self2 = { _elem: resolve7(Array.prototype.slice.call(arguments)) };
214888
214980
  self2.push = function(input) {
214889
214981
  if (!this.append) throw new Error("not assigned to a parent!");
214890
214982
  var that = this;
214891
214983
  var indent = this._elem.indent;
214892
- format(this.append, resolve6(input, indent, this._elem.icount + (indent ? 1 : 0)), function() {
214984
+ format(this.append, resolve7(input, indent, this._elem.icount + (indent ? 1 : 0)), function() {
214893
214985
  that.append(true);
214894
214986
  });
214895
214987
  };
@@ -214902,7 +214994,7 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
214902
214994
  function create_indent(character, count) {
214903
214995
  return new Array(count || 0).join(character || "");
214904
214996
  }
214905
- function resolve6(data, indent, indent_count) {
214997
+ function resolve7(data, indent, indent_count) {
214906
214998
  indent_count = indent_count || 0;
214907
214999
  var indent_spaces = create_indent(indent, indent_count);
214908
215000
  var name;
@@ -214937,7 +215029,7 @@ var require_xml = /* @__PURE__ */ __commonJSMin(((exports2, module2) => {
214937
215029
  content.push("");
214938
215030
  values.forEach(function(value) {
214939
215031
  if (typeof value == "object") if (Object.keys(value)[0] == "_attr") get_attributes(value._attr);
214940
- else content.push(resolve6(value, indent, indent_count + 1));
215032
+ else content.push(resolve7(value, indent, indent_count + 1));
214941
215033
  else {
214942
215034
  content.pop();
214943
215035
  isStringContent = true;
@@ -217789,28 +217881,28 @@ var Pointer = class extends Base {
217789
217881
  if (offset === this.options.nullValue && this.options.allowNull) {
217790
217882
  return null;
217791
217883
  }
217792
- let relative2;
217884
+ let relative3;
217793
217885
  switch (this.options.type) {
217794
217886
  case "local":
217795
- relative2 = ctx._startOffset;
217887
+ relative3 = ctx._startOffset;
217796
217888
  break;
217797
217889
  case "immediate":
217798
- relative2 = stream2.pos - this.offsetType.size();
217890
+ relative3 = stream2.pos - this.offsetType.size();
217799
217891
  break;
217800
217892
  case "parent":
217801
- relative2 = ctx.parent._startOffset;
217893
+ relative3 = ctx.parent._startOffset;
217802
217894
  break;
217803
217895
  default:
217804
217896
  var c2 = ctx;
217805
217897
  while (c2.parent) {
217806
217898
  c2 = c2.parent;
217807
217899
  }
217808
- relative2 = c2._startOffset || 0;
217900
+ relative3 = c2._startOffset || 0;
217809
217901
  }
217810
217902
  if (this.options.relativeTo) {
217811
- relative2 += this.relativeToGetter(ctx);
217903
+ relative3 += this.relativeToGetter(ctx);
217812
217904
  }
217813
- const ptr = offset + relative2;
217905
+ const ptr = offset + relative3;
217814
217906
  if (this.type != null) {
217815
217907
  let val = null;
217816
217908
  const decodeValue = () => {
@@ -217862,7 +217954,7 @@ var Pointer = class extends Base {
217862
217954
  return this.offsetType.size();
217863
217955
  }
217864
217956
  encode(stream2, val, ctx) {
217865
- let relative2;
217957
+ let relative3;
217866
217958
  const parent2 = ctx;
217867
217959
  if (val == null) {
217868
217960
  this.offsetType.encode(stream2, this.options.nullValue);
@@ -217870,25 +217962,25 @@ var Pointer = class extends Base {
217870
217962
  }
217871
217963
  switch (this.options.type) {
217872
217964
  case "local":
217873
- relative2 = ctx.startOffset;
217965
+ relative3 = ctx.startOffset;
217874
217966
  break;
217875
217967
  case "immediate":
217876
- relative2 = stream2.pos + this.offsetType.size(val, parent2);
217968
+ relative3 = stream2.pos + this.offsetType.size(val, parent2);
217877
217969
  break;
217878
217970
  case "parent":
217879
217971
  ctx = ctx.parent;
217880
- relative2 = ctx.startOffset;
217972
+ relative3 = ctx.startOffset;
217881
217973
  break;
217882
217974
  default:
217883
- relative2 = 0;
217975
+ relative3 = 0;
217884
217976
  while (ctx.parent) {
217885
217977
  ctx = ctx.parent;
217886
217978
  }
217887
217979
  }
217888
217980
  if (this.options.relativeTo) {
217889
- relative2 += this.relativeToGetter(parent2.val);
217981
+ relative3 += this.relativeToGetter(parent2.val);
217890
217982
  }
217891
- this.offsetType.encode(stream2, ctx.pointerOffset - relative2);
217983
+ this.offsetType.encode(stream2, ctx.pointerOffset - relative3);
217892
217984
  let { type } = this;
217893
217985
  if (type == null) {
217894
217986
  if (!(val instanceof VoidPointer)) {
@@ -238227,7 +238319,7 @@ var SERIF2 = (bold, italic) => bold && italic ? "Serif-BoldItalic" : bold ? "Ser
238227
238319
  var isEmoji = (cp) => cp >= 126976 || cp >= 9728 && cp <= 10175;
238228
238320
  async function scriptToPdf(doc) {
238229
238321
  const { scriptFont: scriptFont2 } = await Promise.resolve().then(() => (init_script_fonts(), script_fonts_exports));
238230
- return new Promise((resolve6, reject2) => {
238322
+ return new Promise((resolve7, reject2) => {
238231
238323
  const pdf = new PDFDocument({ size: "A4", margins: { top: MARGIN, bottom: MARGIN, left: MARGIN, right: MARGIN }, info: { Title: doc.project, Author: "Patter" }, font: null });
238232
238324
  pdf.registerFont("Serif", scriptFont2("serif"));
238233
238325
  pdf.registerFont("Serif-Bold", scriptFont2("serifBold"));
@@ -238268,7 +238360,7 @@ async function scriptToPdf(doc) {
238268
238360
  const bodyPieces = (runs, color, base = {}) => runs.flatMap((r) => r.code ? split(r.text, "Mono", ACCENT) : split(r.text, SERIF2(base.bold || r.bold, base.italic || r.italic), color));
238269
238361
  const chunks = [];
238270
238362
  pdf.on("data", (c2) => chunks.push(c2));
238271
- pdf.on("end", () => resolve6(Buffer.concat(chunks)));
238363
+ pdf.on("end", () => resolve7(Buffer.concat(chunks)));
238272
238364
  pdf.on("error", reject2);
238273
238365
  const pageRight = pdf.page.width - MARGIN;
238274
238366
  const pageBottom = pdf.page.height - MARGIN;
@@ -238811,10 +238903,21 @@ function buildIndex(loaded) {
238811
238903
  // ../ops/src/pack.ts
238812
238904
  var import_jszip = __toESM(require_lib3(), 1);
238813
238905
  import { readFileSync as readFileSync4 } from "fs";
238814
- import { dirname as dirname4, relative, sep as sep2 } from "path";
238906
+ import { dirname as dirname4, relative as relative2, sep as sep3 } from "path";
238907
+
238908
+ // ../../node_modules/@wildwinter/toolkit/dist/archive.js
238909
+ import { isAbsolute as isAbsolute2, normalize, sep as sep2, resolve as resolve4, join as join5, relative } from "path";
238910
+ function isUnsafeEntry(name) {
238911
+ if (isAbsolute2(name) || /^[a-zA-Z]:/.test(name)) return true;
238912
+ const norm = normalize(name);
238913
+ return norm === ".." || norm.startsWith(`..${sep2}`) || norm.startsWith("../");
238914
+ }
238915
+ var ARCHIVE_ENTRY_DATE = /* @__PURE__ */ new Date("2000-01-01T00:00:00Z");
238916
+ var ARCHIVE_ENTRY_OPTS = { date: ARCHIVE_ENTRY_DATE, createFolders: false };
238917
+
238918
+ // ../ops/src/pack.ts
238815
238919
  var SHARD_EXTENSIONS = [".patterflow", ".patterloc", ".patterx", ".patterproj"];
238816
- var FIXED_DATE = /* @__PURE__ */ new Date("2000-01-01T00:00:00Z");
238817
- var ENTRY_OPTS = { date: FIXED_DATE, createFolders: false };
238920
+ var ENTRY_OPTS = ARCHIVE_ENTRY_OPTS;
238818
238921
  async function runPack(startPath) {
238819
238922
  const projectFile = findProjectFile(startPath);
238820
238923
  const root2 = dirname4(projectFile);
@@ -238826,7 +238929,7 @@ async function runPack(startPath) {
238826
238929
  ` + unresolved.map((i) => ` ${i.file}`).join("\n")
238827
238930
  );
238828
238931
  }
238829
- const files = SHARD_EXTENSIONS.flatMap((ext) => walkFiles(root2, ext)).map((abs) => ({ abs, rel: relative(root2, abs).split(sep2).join("/") })).sort((a, b) => a.rel.localeCompare(b.rel));
238932
+ const files = SHARD_EXTENSIONS.flatMap((ext) => walkFiles(root2, ext)).map((abs) => ({ abs, rel: relative2(root2, abs).split(sep3).join("/") })).sort((a, b) => a.rel.localeCompare(b.rel));
238830
238933
  const manifest = {
238831
238934
  schema: "patter/document@0",
238832
238935
  project: { id: project.project.id, name: project.project.name },
@@ -238840,7 +238943,7 @@ async function runPack(startPath) {
238840
238943
 
238841
238944
  // ../ops/src/unpack.ts
238842
238945
  var import_jszip2 = __toESM(require_lib3(), 1);
238843
- import { join as join5, normalize, isAbsolute as isAbsolute2, resolve as resolve4, sep as sep3 } from "path";
238946
+ import { join as join6, resolve as resolve5, sep as sep4 } from "path";
238844
238947
  import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
238845
238948
  var MANIFEST = "patter.manifest.json";
238846
238949
  var UnsafeEntryError = class extends Error {
@@ -238926,22 +239029,17 @@ async function runUnpackMerge(returnedBytes, baseBytes, projectDir) {
238926
239029
  }
238927
239030
  return { shards, writes, sidecars, conflicts, warnings, provenance };
238928
239031
  }
238929
- function isUnsafeEntry(name) {
238930
- if (isAbsolute2(name) || /^[a-zA-Z]:/.test(name)) return true;
238931
- const norm = normalize(name);
238932
- return norm === ".." || norm.startsWith(".." + sep3) || norm.startsWith("../");
238933
- }
238934
239032
  function containedWrite(dir2, name) {
238935
- const root2 = resolve4(dir2);
238936
- const full = resolve4(join5(dir2, name));
238937
- if (full !== root2 && !full.startsWith(root2 + sep3)) {
239033
+ const root2 = resolve5(dir2);
239034
+ const full = resolve5(join6(dir2, name));
239035
+ if (full !== root2 && !full.startsWith(root2 + sep4)) {
238938
239036
  throw new UnsafeEntryError(`document entry escapes the target directory: ${name}`);
238939
239037
  }
238940
239038
  return full;
238941
239039
  }
238942
239040
 
238943
239041
  // ../../node_modules/@wildwinter/simple-vc-lib/dist/simpleVcLib.js
238944
- import { join as join6, dirname as dirname5, resolve as resolve5, sep as sep4, basename as basename6 } from "path";
239042
+ import { join as join7, dirname as dirname5, resolve as resolve6, sep as sep5, basename as basename6 } from "path";
238945
239043
  import { existsSync as existsSync4, readFileSync as readFileSync6, statSync as statSync3, unlinkSync, rmSync, renameSync, accessSync, constants, chmodSync, mkdirSync as mkdirSync2, cpSync, readdirSync as readdirSync4, writeFileSync as writeFileSync2 } from "fs";
238946
239044
  import { spawnSync, spawn } from "child_process";
238947
239045
  var VALID_SYSTEMS = ["git", "perforce", "plastic", "svn", "filesystem"];
@@ -238952,7 +239050,7 @@ function loadConfig(startDir) {
238952
239050
  }
238953
239051
  let dir2 = startDir;
238954
239052
  while (true) {
238955
- const configPath = join6(dir2, ".vcconfig");
239053
+ const configPath = join7(dir2, ".vcconfig");
238956
239054
  if (existsSync4(configPath)) {
238957
239055
  try {
238958
239056
  const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
@@ -238996,7 +239094,7 @@ async function runCommandAsync(command, args, options = {}) {
238996
239094
  const overridden = await _overrideRunner(command, args, options);
238997
239095
  return { timedOut: false, ...overridden };
238998
239096
  }
238999
- return new Promise((resolve6) => {
239097
+ return new Promise((resolve7) => {
239000
239098
  const child = spawn(command, args, { cwd: options.cwd, windowsHide: true });
239001
239099
  let stdout = "";
239002
239100
  let stderr = "";
@@ -239018,7 +239116,7 @@ async function runCommandAsync(command, args, options = {}) {
239018
239116
  if (settled) return;
239019
239117
  settled = true;
239020
239118
  clearTimeout(timer);
239021
- resolve6(result);
239119
+ resolve7(result);
239022
239120
  };
239023
239121
  child.on("error", (err) => {
239024
239122
  finish({ exitCode: -1, output: "", error: stderr.trim() || err.message, timedOut });
@@ -239053,15 +239151,15 @@ function detectProvider(absPath) {
239053
239151
  }
239054
239152
  current = dir2;
239055
239153
  while (true) {
239056
- if (existsSync4(join6(current, ".git"))) {
239154
+ if (existsSync4(join7(current, ".git"))) {
239057
239155
  _rootCache.set(current, "git");
239058
239156
  return "git";
239059
239157
  }
239060
- if (existsSync4(join6(current, ".plastic"))) {
239158
+ if (existsSync4(join7(current, ".plastic"))) {
239061
239159
  _rootCache.set(current, "plastic");
239062
239160
  return "plastic";
239063
239161
  }
239064
- if (existsSync4(join6(current, ".svn"))) {
239162
+ if (existsSync4(join7(current, ".svn"))) {
239065
239163
  _rootCache.set(current, "svn");
239066
239164
  return "svn";
239067
239165
  }
@@ -239191,7 +239289,7 @@ var FilesystemProvider = class {
239191
239289
  */
239192
239290
  status(filePaths) {
239193
239291
  return filePaths.map((filePath) => {
239194
- const abs = resolve5(filePath);
239292
+ const abs = resolve6(filePath);
239195
239293
  return { filePath: abs, system: "filesystem", writable: writableBit(abs) };
239196
239294
  });
239197
239295
  }
@@ -239242,29 +239340,29 @@ function gitArgv(args, cwd) {
239242
239340
  }
239243
239341
  var _trackedCache = /* @__PURE__ */ new Set();
239244
239342
  function isTracked$2(filePath) {
239245
- const key2 = resolve5(filePath);
239343
+ const key2 = resolve6(filePath);
239246
239344
  if (_trackedCache.has(key2)) return true;
239247
239345
  const result = git(["ls-files", "--error-unmatch", filePath], dirname5(filePath));
239248
239346
  if (result.exitCode === 0) _trackedCache.add(key2);
239249
239347
  return result.exitCode === 0;
239250
239348
  }
239251
239349
  async function isTrackedAsync$2(filePath) {
239252
- const key2 = resolve5(filePath);
239350
+ const key2 = resolve6(filePath);
239253
239351
  if (_trackedCache.has(key2)) return true;
239254
239352
  const result = await gitAsync(["ls-files", "--error-unmatch", filePath], dirname5(filePath));
239255
239353
  if (result.exitCode === 0) _trackedCache.add(key2);
239256
239354
  return result.exitCode === 0;
239257
239355
  }
239258
239356
  function markTracked(filePath) {
239259
- _trackedCache.add(resolve5(filePath));
239357
+ _trackedCache.add(resolve6(filePath));
239260
239358
  }
239261
239359
  function unmarkTracked(filePath) {
239262
- _trackedCache.delete(resolve5(filePath));
239360
+ _trackedCache.delete(resolve6(filePath));
239263
239361
  }
239264
239362
  function unmarkTrackedUnder(folderPath) {
239265
- const prefix = resolve5(folderPath) + sep4;
239363
+ const prefix = resolve6(folderPath) + sep5;
239266
239364
  for (const path of _trackedCache) if (path.startsWith(prefix)) _trackedCache.delete(path);
239267
- _trackedCache.delete(resolve5(folderPath));
239365
+ _trackedCache.delete(resolve6(folderPath));
239268
239366
  }
239269
239367
  function isInRepo(dir2) {
239270
239368
  return git(["rev-parse", "--git-dir"], dir2).exitCode === 0;
@@ -239488,7 +239586,7 @@ var GitProvider = class {
239488
239586
  const infoByDir = /* @__PURE__ */ new Map();
239489
239587
  const groups = /* @__PURE__ */ new Map();
239490
239588
  for (const filePath of filePaths) {
239491
- const abs = resolve5(filePath);
239589
+ const abs = resolve6(filePath);
239492
239590
  const dir2 = dirname5(abs);
239493
239591
  let info = infoByDir.get(dir2);
239494
239592
  if (info === void 0) {
@@ -239518,7 +239616,7 @@ var GitProvider = class {
239518
239616
  const infoByDir = /* @__PURE__ */ new Map();
239519
239617
  const groups = /* @__PURE__ */ new Map();
239520
239618
  for (const filePath of filePaths) {
239521
- const abs = resolve5(filePath);
239619
+ const abs = resolve6(filePath);
239522
239620
  const dir2 = dirname5(abs);
239523
239621
  let info = infoByDir.get(dir2);
239524
239622
  if (info === void 0) {
@@ -239548,7 +239646,7 @@ function shouldQueryLfsLocks(root2, options) {
239548
239646
  }
239549
239647
  function repoUsesLfsLocks(root2) {
239550
239648
  try {
239551
- return /(^|\s)lockable(\s|$)/m.test(readFileSync6(join6(root2, ".gitattributes"), "utf8"));
239649
+ return /(^|\s)lockable(\s|$)/m.test(readFileSync6(join7(root2, ".gitattributes"), "utf8"));
239552
239650
  } catch {
239553
239651
  return false;
239554
239652
  }
@@ -240033,10 +240131,10 @@ function buildPerforceStatuses(output, filePaths) {
240033
240131
  const byClientFile = /* @__PURE__ */ new Map();
240034
240132
  for (const record of records) {
240035
240133
  const clientFile = record.fields.get("clientFile");
240036
- if (clientFile) byClientFile.set(resolve5(clientFile), record);
240134
+ if (clientFile) byClientFile.set(resolve6(clientFile), record);
240037
240135
  }
240038
240136
  return filePaths.map((filePath) => {
240039
- const abs = resolve5(filePath);
240137
+ const abs = resolve6(filePath);
240040
240138
  const status = { filePath: abs, system: "perforce", writable: writableBit(abs) };
240041
240139
  const record = byClientFile.get(abs);
240042
240140
  if (!record) {
@@ -240322,7 +240420,7 @@ var PlasticProvider = class {
240322
240420
  }
240323
240421
  };
240324
240422
  function plasticStatusArgs(filePaths) {
240325
- return ["status", "--machinereadable", "--all", "--ignored", ...filePaths.map((p) => resolve5(p))];
240423
+ return ["status", "--machinereadable", "--all", "--ignored", ...filePaths.map((p) => resolve6(p))];
240326
240424
  }
240327
240425
  function buildPlasticBase(result, filePaths) {
240328
240426
  const byPath = /* @__PURE__ */ new Map();
@@ -240332,7 +240430,7 @@ function buildPlasticBase(result, filePaths) {
240332
240430
  const parsed = parseCmStatusLine(line2);
240333
240431
  if (!parsed) continue;
240334
240432
  for (const p of parsed.paths) {
240335
- const abs = resolve5(p);
240433
+ const abs = resolve6(p);
240336
240434
  byPath.set(abs, parsed.info);
240337
240435
  const base = basename6(abs);
240338
240436
  if (!byBase.has(base)) byBase.set(base, []);
@@ -240341,7 +240439,7 @@ function buildPlasticBase(result, filePaths) {
240341
240439
  }
240342
240440
  }
240343
240441
  return filePaths.map((filePath) => {
240344
- const abs = resolve5(filePath);
240442
+ const abs = resolve6(filePath);
240345
240443
  const status = { filePath: abs, system: "plastic", writable: writableBit(abs) };
240346
240444
  let info = byPath.get(abs);
240347
240445
  if (!info) {
@@ -240651,7 +240749,7 @@ var SvnProvider = class {
240651
240749
  }
240652
240750
  };
240653
240751
  function svnStatusArgs(filePaths, options) {
240654
- const targets = filePaths.map((p) => resolve5(p));
240752
+ const targets = filePaths.map((p) => resolve6(p));
240655
240753
  return ["status", "--xml", "-v", ...options.remote ? ["-u"] : [], ...targets];
240656
240754
  }
240657
240755
  function buildSvnStatuses(output, filePaths) {
@@ -240661,7 +240759,7 @@ function buildSvnStatuses(output, filePaths) {
240661
240759
  const entryRe = /<entry\b[^>]*\bpath="([^"]*)"[^>]*>([\s\S]*?)<\/entry>/g;
240662
240760
  let m;
240663
240761
  while ((m = entryRe.exec(output)) !== null) {
240664
- const entryPath = resolve5(decodeXmlAttr(m[1]));
240762
+ const entryPath = resolve6(decodeXmlAttr(m[1]));
240665
240763
  const info = parseSvnEntry(m[2]);
240666
240764
  if (!info) continue;
240667
240765
  byPath.set(entryPath, info);
@@ -240671,7 +240769,7 @@ function buildSvnStatuses(output, filePaths) {
240671
240769
  }
240672
240770
  }
240673
240771
  return filePaths.map((filePath) => {
240674
- const abs = resolve5(filePath);
240772
+ const abs = resolve6(filePath);
240675
240773
  const status = { filePath: abs, system: "svn", writable: writableBit(abs) };
240676
240774
  let info = byPath.get(abs);
240677
240775
  if (!info) {
@@ -240745,7 +240843,7 @@ var PROVIDER_MAP = {
240745
240843
  };
240746
240844
  var _overrideProvider = null;
240747
240845
  function dirOf(p) {
240748
- const abs = resolve5(p);
240846
+ const abs = resolve6(p);
240749
240847
  try {
240750
240848
  return statSync3(abs).isDirectory() ? abs : dirname5(abs);
240751
240849
  } catch {
@@ -240760,7 +240858,7 @@ function resolveProvider(filePath) {
240760
240858
  const factory = PROVIDER_MAP[config.system];
240761
240859
  if (factory) return factory();
240762
240860
  }
240763
- const detected = detectProvider(resolve5(filePath));
240861
+ const detected = detectProvider(resolve6(filePath));
240764
240862
  return (PROVIDER_MAP[detected] ?? PROVIDER_MAP.filesystem)();
240765
240863
  }
240766
240864
  function deleteFile(filePath) {
@@ -240806,7 +240904,7 @@ function writeBinaryFile(filePath, data, forceWrite = false) {
240806
240904
  function writeTextFiles(files, encoding = "utf8") {
240807
240905
  const results = files.map(({ filePath, content }) => {
240808
240906
  try {
240809
- mkdirSync2(dirname5(resolve5(filePath)), { recursive: true });
240907
+ mkdirSync2(dirname5(resolve6(filePath)), { recursive: true });
240810
240908
  } catch (e) {
240811
240909
  return { filePath, success: false, status: "error", message: e.message };
240812
240910
  }
@@ -240819,7 +240917,7 @@ function writeTextFiles(files, encoding = "utf8") {
240819
240917
  // package.json
240820
240918
  var package_default = {
240821
240919
  name: "@patterkit/cli",
240822
- version: "0.3.0",
240920
+ version: "0.3.2",
240823
240921
  description: "The `patter` CLI: validate, format, export, and play a Patter project.",
240824
240922
  type: "module",
240825
240923
  license: "MIT",
@@ -240848,8 +240946,8 @@ var package_default = {
240848
240946
  "build:standalone:others": "node scripts/build-standalone.mjs --targets=linux-x64,linux-arm64,windows-x64"
240849
240947
  },
240850
240948
  dependencies: {
240851
- "@patterkit/core": "0.2.1",
240852
- "@patterkit/ops": "0.5.0",
240949
+ "@patterkit/core": "0.2.2",
240950
+ "@patterkit/ops": "0.7.0",
240853
240951
  "@wildwinter/simple-vc-lib": "^0.4.1"
240854
240952
  }
240855
240953
  };