proschi 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -242,8 +242,8 @@ var require_scope = __commonJS({
242
242
  super(nameStr);
243
243
  this.prefix = prefix;
244
244
  }
245
- setValue(value, { property, itemIndex }) {
246
- this.value = value;
245
+ setValue(value2, { property, itemIndex }) {
246
+ this.value = value2;
247
247
  this.scopePath = (0, code_1._)`.${new code_1.Name(property)}[${itemIndex}]`;
248
248
  }
249
249
  };
@@ -262,13 +262,13 @@ var require_scope = __commonJS({
262
262
  name(prefix) {
263
263
  return new ValueScopeName(prefix, this._newName(prefix));
264
264
  }
265
- value(nameOrPrefix, value) {
265
+ value(nameOrPrefix, value2) {
266
266
  var _a;
267
- if (value.ref === void 0)
267
+ if (value2.ref === void 0)
268
268
  throw new Error("CodeGen: ref must be passed in value");
269
269
  const name = this.toName(nameOrPrefix);
270
270
  const { prefix } = name;
271
- const valueKey = (_a = value.key) !== null && _a !== void 0 ? _a : value.ref;
271
+ const valueKey = (_a = value2.key) !== null && _a !== void 0 ? _a : value2.ref;
272
272
  let vs = this._values[prefix];
273
273
  if (vs) {
274
274
  const _name = vs.get(valueKey);
@@ -280,8 +280,8 @@ var require_scope = __commonJS({
280
280
  vs.set(valueKey, name);
281
281
  const s = this._scope[prefix] || (this._scope[prefix] = []);
282
282
  const itemIndex = s.length;
283
- s[itemIndex] = value.ref;
284
- name.setValue(value, { property: prefix, itemIndex });
283
+ s[itemIndex] = value2.ref;
284
+ name.setValue(value2, { property: prefix, itemIndex });
285
285
  return name;
286
286
  }
287
287
  getValue(prefix, keyOrRef) {
@@ -751,8 +751,8 @@ var require_codegen = __commonJS({
751
751
  return this._extScope.name(prefix);
752
752
  }
753
753
  // reserves unique name in the external scope and assigns value to it
754
- scopeValue(prefixOrName, value) {
755
- const name = this._extScope.value(prefixOrName, value);
754
+ scopeValue(prefixOrName, value2) {
755
+ const name = this._extScope.value(prefixOrName, value2);
756
756
  const vs = this._values[name.prefix] || (this._values[name.prefix] = /* @__PURE__ */ new Set());
757
757
  vs.add(name);
758
758
  return name;
@@ -806,13 +806,13 @@ var require_codegen = __commonJS({
806
806
  // returns code for object literal for the passed argument list of key-value pairs
807
807
  object(...keyValues) {
808
808
  const code = ["{"];
809
- for (const [key, value] of keyValues) {
809
+ for (const [key, value2] of keyValues) {
810
810
  if (code.length > 1)
811
811
  code.push(",");
812
812
  code.push(key);
813
- if (key !== value || this.opts.es5) {
813
+ if (key !== value2 || this.opts.es5) {
814
814
  code.push(":");
815
- (0, code_1.addCodeArg)(code, value);
815
+ (0, code_1.addCodeArg)(code, value2);
816
816
  }
817
817
  }
818
818
  code.push("}");
@@ -891,10 +891,10 @@ var require_codegen = __commonJS({
891
891
  return this._leafNode(new Break(label));
892
892
  }
893
893
  // `return` statement
894
- return(value) {
894
+ return(value2) {
895
895
  const node = new Return();
896
896
  this._blockNode(node);
897
- this.code(value);
897
+ this.code(value2);
898
898
  if (node.nodes.length !== 1)
899
899
  throw new Error('CodeGen: "return" should have one node');
900
900
  return this._endBlockNode(Return);
@@ -4200,13 +4200,13 @@ var require_fast_uri = __commonJS({
4200
4200
  if (typeof uri !== "string" && typeof uri !== "object") {
4201
4201
  return void 0;
4202
4202
  }
4203
- let value;
4203
+ let value2;
4204
4204
  try {
4205
- value = typeof uri === "string" ? uri : serialize(uri, opts);
4205
+ value2 = typeof uri === "string" ? uri : serialize(uri, opts);
4206
4206
  } catch {
4207
4207
  return void 0;
4208
4208
  }
4209
- const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
4209
+ const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value2, opts);
4210
4210
  return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
4211
4211
  }
4212
4212
  var fastUri = {
@@ -5073,13 +5073,13 @@ var require_ucs2length = __commonJS({
5073
5073
  const len2 = str.length;
5074
5074
  let length = 0;
5075
5075
  let pos = 0;
5076
- let value;
5076
+ let value2;
5077
5077
  while (pos < len2) {
5078
5078
  length++;
5079
- value = str.charCodeAt(pos++);
5080
- if (value >= 55296 && value <= 56319 && pos < len2) {
5081
- value = str.charCodeAt(pos);
5082
- if ((value & 64512) === 56320)
5079
+ value2 = str.charCodeAt(pos++);
5080
+ if (value2 >= 55296 && value2 <= 56319 && pos < len2) {
5081
+ value2 = str.charCodeAt(pos);
5082
+ if ((value2 & 64512) === 56320)
5083
5083
  pos++;
5084
5084
  }
5085
5085
  }
@@ -7970,26 +7970,26 @@ var require_toJS = __commonJS({
7970
7970
  "node_modules/yaml/dist/nodes/toJS.js"(exports2) {
7971
7971
  "use strict";
7972
7972
  var identity = require_identity();
7973
- function toJS(value, arg, ctx) {
7974
- if (Array.isArray(value))
7975
- return value.map((v, i) => toJS(v, String(i), ctx));
7976
- if (value && typeof value.toJSON === "function") {
7977
- if (!ctx || !identity.hasAnchor(value))
7978
- return value.toJSON(arg, ctx);
7973
+ function toJS(value2, arg, ctx) {
7974
+ if (Array.isArray(value2))
7975
+ return value2.map((v, i) => toJS(v, String(i), ctx));
7976
+ if (value2 && typeof value2.toJSON === "function") {
7977
+ if (!ctx || !identity.hasAnchor(value2))
7978
+ return value2.toJSON(arg, ctx);
7979
7979
  const data = { aliasCount: 0, count: 1, res: void 0 };
7980
- ctx.anchors.set(value, data);
7980
+ ctx.anchors.set(value2, data);
7981
7981
  ctx.onCreate = (res2) => {
7982
7982
  data.res = res2;
7983
7983
  delete ctx.onCreate;
7984
7984
  };
7985
- const res = value.toJSON(arg, ctx);
7985
+ const res = value2.toJSON(arg, ctx);
7986
7986
  if (ctx.onCreate)
7987
7987
  ctx.onCreate(res);
7988
7988
  return res;
7989
7989
  }
7990
- if (typeof value === "bigint" && !ctx?.keep)
7991
- return Number(value);
7992
- return value;
7990
+ if (typeof value2 === "bigint" && !ctx?.keep)
7991
+ return Number(value2);
7992
+ return value2;
7993
7993
  }
7994
7994
  exports2.toJS = toJS;
7995
7995
  }
@@ -8161,11 +8161,11 @@ var require_Scalar = __commonJS({
8161
8161
  var identity = require_identity();
8162
8162
  var Node = require_Node();
8163
8163
  var toJS = require_toJS();
8164
- var isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object";
8164
+ var isScalarValue = (value2) => !value2 || typeof value2 !== "function" && typeof value2 !== "object";
8165
8165
  var Scalar = class extends Node.NodeBase {
8166
- constructor(value) {
8166
+ constructor(value2) {
8167
8167
  super(identity.SCALAR);
8168
- this.value = value;
8168
+ this.value = value2;
8169
8169
  }
8170
8170
  toJSON(arg, ctx) {
8171
8171
  return ctx?.keep ? this.value : toJS.toJS(this.value, arg, ctx);
@@ -8192,7 +8192,7 @@ var require_createNode = __commonJS({
8192
8192
  var identity = require_identity();
8193
8193
  var Scalar = require_Scalar();
8194
8194
  var defaultTagPrefix = "tag:yaml.org,2002:";
8195
- function findTagObject(value, tagName, tags) {
8195
+ function findTagObject(value2, tagName, tags) {
8196
8196
  if (tagName) {
8197
8197
  const match = tags.filter((t) => t.tag === tagName);
8198
8198
  const tagObj = match.find((t) => !t.format) ?? match[0];
@@ -8200,53 +8200,53 @@ var require_createNode = __commonJS({
8200
8200
  throw new Error(`Tag ${tagName} not found`);
8201
8201
  return tagObj;
8202
8202
  }
8203
- return tags.find((t) => t.identify?.(value) && !t.format);
8203
+ return tags.find((t) => t.identify?.(value2) && !t.format);
8204
8204
  }
8205
- function createNode(value, tagName, ctx) {
8206
- if (identity.isDocument(value))
8207
- value = value.contents;
8208
- if (identity.isNode(value))
8209
- return value;
8210
- if (identity.isPair(value)) {
8205
+ function createNode(value2, tagName, ctx) {
8206
+ if (identity.isDocument(value2))
8207
+ value2 = value2.contents;
8208
+ if (identity.isNode(value2))
8209
+ return value2;
8210
+ if (identity.isPair(value2)) {
8211
8211
  const map = ctx.schema[identity.MAP].createNode?.(ctx.schema, null, ctx);
8212
- map.items.push(value);
8212
+ map.items.push(value2);
8213
8213
  return map;
8214
8214
  }
8215
- if (value instanceof String || value instanceof Number || value instanceof Boolean || typeof BigInt !== "undefined" && value instanceof BigInt) {
8216
- value = value.valueOf();
8215
+ if (value2 instanceof String || value2 instanceof Number || value2 instanceof Boolean || typeof BigInt !== "undefined" && value2 instanceof BigInt) {
8216
+ value2 = value2.valueOf();
8217
8217
  }
8218
8218
  const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
8219
8219
  let ref = void 0;
8220
- if (aliasDuplicateObjects && value && typeof value === "object") {
8221
- ref = sourceObjects.get(value);
8220
+ if (aliasDuplicateObjects && value2 && typeof value2 === "object") {
8221
+ ref = sourceObjects.get(value2);
8222
8222
  if (ref) {
8223
- ref.anchor ?? (ref.anchor = onAnchor(value));
8223
+ ref.anchor ?? (ref.anchor = onAnchor(value2));
8224
8224
  return new Alias.Alias(ref.anchor);
8225
8225
  } else {
8226
8226
  ref = { anchor: null, node: null };
8227
- sourceObjects.set(value, ref);
8227
+ sourceObjects.set(value2, ref);
8228
8228
  }
8229
8229
  }
8230
8230
  if (tagName?.startsWith("!!"))
8231
8231
  tagName = defaultTagPrefix + tagName.slice(2);
8232
- let tagObj = findTagObject(value, tagName, schema.tags);
8232
+ let tagObj = findTagObject(value2, tagName, schema.tags);
8233
8233
  if (!tagObj) {
8234
- if (value && typeof value.toJSON === "function") {
8235
- value = value.toJSON();
8234
+ if (value2 && typeof value2.toJSON === "function") {
8235
+ value2 = value2.toJSON();
8236
8236
  }
8237
- if (!value || typeof value !== "object") {
8238
- const node2 = new Scalar.Scalar(value);
8237
+ if (!value2 || typeof value2 !== "object") {
8238
+ const node2 = new Scalar.Scalar(value2);
8239
8239
  if (ref)
8240
8240
  ref.node = node2;
8241
8241
  return node2;
8242
8242
  }
8243
- tagObj = value instanceof Map ? schema[identity.MAP] : Symbol.iterator in Object(value) ? schema[identity.SEQ] : schema[identity.MAP];
8243
+ tagObj = value2 instanceof Map ? schema[identity.MAP] : Symbol.iterator in Object(value2) ? schema[identity.SEQ] : schema[identity.MAP];
8244
8244
  }
8245
8245
  if (onTagObj) {
8246
8246
  onTagObj(tagObj);
8247
8247
  delete ctx.onTagObj;
8248
8248
  }
8249
- const node = tagObj?.createNode ? tagObj.createNode(ctx.schema, value, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value, ctx) : new Scalar.Scalar(value);
8249
+ const node = tagObj?.createNode ? tagObj.createNode(ctx.schema, value2, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value2, ctx) : new Scalar.Scalar(value2);
8250
8250
  if (tagName)
8251
8251
  node.tag = tagName;
8252
8252
  else if (!tagObj.default)
@@ -8266,8 +8266,8 @@ var require_Collection = __commonJS({
8266
8266
  var createNode = require_createNode();
8267
8267
  var identity = require_identity();
8268
8268
  var Node = require_Node();
8269
- function collectionFromPath(schema, path, value) {
8270
- let v = value;
8269
+ function collectionFromPath(schema, path, value2) {
8270
+ let v = value2;
8271
8271
  for (let i = path.length - 1; i >= 0; --i) {
8272
8272
  const k = path[i];
8273
8273
  if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
@@ -8318,16 +8318,16 @@ var require_Collection = __commonJS({
8318
8318
  * be a Pair instance or a `{ key, value }` object, which may not have a key
8319
8319
  * that already exists in the map.
8320
8320
  */
8321
- addIn(path, value) {
8321
+ addIn(path, value2) {
8322
8322
  if (isEmptyPath(path))
8323
- this.add(value);
8323
+ this.add(value2);
8324
8324
  else {
8325
8325
  const [key, ...rest] = path;
8326
8326
  const node = this.get(key, true);
8327
8327
  if (identity.isCollection(node))
8328
- node.addIn(rest, value);
8328
+ node.addIn(rest, value2);
8329
8329
  else if (node === void 0 && this.schema)
8330
- this.set(key, collectionFromPath(this.schema, rest, value));
8330
+ this.set(key, collectionFromPath(this.schema, rest, value2));
8331
8331
  else
8332
8332
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
8333
8333
  }
@@ -8381,16 +8381,16 @@ var require_Collection = __commonJS({
8381
8381
  * Sets a value in this collection. For `!!set`, `value` needs to be a
8382
8382
  * boolean to add/remove the item from the set.
8383
8383
  */
8384
- setIn(path, value) {
8384
+ setIn(path, value2) {
8385
8385
  const [key, ...rest] = path;
8386
8386
  if (rest.length === 0) {
8387
- this.set(key, value);
8387
+ this.set(key, value2);
8388
8388
  } else {
8389
8389
  const node = this.get(key, true);
8390
8390
  if (identity.isCollection(node))
8391
- node.setIn(rest, value);
8391
+ node.setIn(rest, value2);
8392
8392
  else if (node === void 0 && this.schema)
8393
- this.set(key, collectionFromPath(this.schema, rest, value));
8393
+ this.set(key, collectionFromPath(this.schema, rest, value2));
8394
8394
  else
8395
8395
  throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
8396
8396
  }
@@ -8585,13 +8585,13 @@ var require_stringifyString = __commonJS({
8585
8585
  }
8586
8586
  return true;
8587
8587
  }
8588
- function doubleQuotedString(value, ctx) {
8589
- const json2 = JSON.stringify(value);
8588
+ function doubleQuotedString(value2, ctx) {
8589
+ const json2 = JSON.stringify(value2);
8590
8590
  if (ctx.options.doubleQuotedAsJSON)
8591
8591
  return json2;
8592
8592
  const { implicitKey } = ctx;
8593
8593
  const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
8594
- const indent2 = ctx.indent || (containsDocumentMarker(value) ? " " : "");
8594
+ const indent2 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
8595
8595
  let str = "";
8596
8596
  let start = 0;
8597
8597
  for (let i = 0, ch = json2[i]; ch; ch = json2[++i]) {
@@ -8665,22 +8665,22 @@ var require_stringifyString = __commonJS({
8665
8665
  str = start ? str + json2.slice(start) : json2;
8666
8666
  return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent2, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
8667
8667
  }
8668
- function singleQuotedString(value, ctx) {
8669
- if (ctx.options.singleQuote === false || ctx.implicitKey && value.includes("\n") || /[ \t]\n|\n[ \t]/.test(value))
8670
- return doubleQuotedString(value, ctx);
8671
- const indent2 = ctx.indent || (containsDocumentMarker(value) ? " " : "");
8672
- const res = "'" + value.replace(/'/g, "''").replace(/\n+/g, `$&
8668
+ function singleQuotedString(value2, ctx) {
8669
+ if (ctx.options.singleQuote === false || ctx.implicitKey && value2.includes("\n") || /[ \t]\n|\n[ \t]/.test(value2))
8670
+ return doubleQuotedString(value2, ctx);
8671
+ const indent2 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
8672
+ const res = "'" + value2.replace(/'/g, "''").replace(/\n+/g, `$&
8673
8673
  ${indent2}`) + "'";
8674
8674
  return ctx.implicitKey ? res : foldFlowLines.foldFlowLines(res, indent2, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
8675
8675
  }
8676
- function quotedString(value, ctx) {
8676
+ function quotedString(value2, ctx) {
8677
8677
  const { singleQuote } = ctx.options;
8678
8678
  let qs;
8679
8679
  if (singleQuote === false)
8680
8680
  qs = doubleQuotedString;
8681
8681
  else {
8682
- const hasDouble = value.includes('"');
8683
- const hasSingle = value.includes("'");
8682
+ const hasDouble = value2.includes('"');
8683
+ const hasSingle = value2.includes("'");
8684
8684
  if (hasDouble && !hasSingle)
8685
8685
  qs = singleQuotedString;
8686
8686
  else if (hasSingle && !hasDouble)
@@ -8688,7 +8688,7 @@ ${indent2}`) + "'";
8688
8688
  else
8689
8689
  qs = singleQuote ? singleQuotedString : doubleQuotedString;
8690
8690
  }
8691
- return qs(value, ctx);
8691
+ return qs(value2, ctx);
8692
8692
  }
8693
8693
  var blockEndNewlines;
8694
8694
  try {
@@ -8696,27 +8696,27 @@ ${indent2}`) + "'";
8696
8696
  } catch {
8697
8697
  blockEndNewlines = /\n+(?!\n|$)/g;
8698
8698
  }
8699
- function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
8699
+ function blockString({ comment, type, value: value2 }, ctx, onComment, onChompKeep) {
8700
8700
  const { blockQuote, commentString, lineWidth } = ctx.options;
8701
- if (!blockQuote || /\n[\t ]+$/.test(value)) {
8702
- return quotedString(value, ctx);
8701
+ if (!blockQuote || /\n[\t ]+$/.test(value2)) {
8702
+ return quotedString(value2, ctx);
8703
8703
  }
8704
- const indent2 = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value) ? " " : "");
8705
- const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value, lineWidth, indent2.length);
8706
- if (!value)
8704
+ const indent2 = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value2) ? " " : "");
8705
+ const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value2, lineWidth, indent2.length);
8706
+ if (!value2)
8707
8707
  return literal ? "|\n" : ">\n";
8708
8708
  let chomp;
8709
8709
  let endStart;
8710
- for (endStart = value.length; endStart > 0; --endStart) {
8711
- const ch = value[endStart - 1];
8710
+ for (endStart = value2.length; endStart > 0; --endStart) {
8711
+ const ch = value2[endStart - 1];
8712
8712
  if (ch !== "\n" && ch !== " " && ch !== " ")
8713
8713
  break;
8714
8714
  }
8715
- let end = value.substring(endStart);
8715
+ let end = value2.substring(endStart);
8716
8716
  const endNlPos = end.indexOf("\n");
8717
8717
  if (endNlPos === -1) {
8718
8718
  chomp = "-";
8719
- } else if (value === end || endNlPos !== end.length - 1) {
8719
+ } else if (value2 === end || endNlPos !== end.length - 1) {
8720
8720
  chomp = "+";
8721
8721
  if (onChompKeep)
8722
8722
  onChompKeep();
@@ -8724,7 +8724,7 @@ ${indent2}`) + "'";
8724
8724
  chomp = "";
8725
8725
  }
8726
8726
  if (end) {
8727
- value = value.slice(0, -end.length);
8727
+ value2 = value2.slice(0, -end.length);
8728
8728
  if (end[end.length - 1] === "\n")
8729
8729
  end = end.slice(0, -1);
8730
8730
  end = end.replace(blockEndNewlines, `$&${indent2}`);
@@ -8732,8 +8732,8 @@ ${indent2}`) + "'";
8732
8732
  let startWithSpace = false;
8733
8733
  let startEnd;
8734
8734
  let startNlPos = -1;
8735
- for (startEnd = 0; startEnd < value.length; ++startEnd) {
8736
- const ch = value[startEnd];
8735
+ for (startEnd = 0; startEnd < value2.length; ++startEnd) {
8736
+ const ch = value2[startEnd];
8737
8737
  if (ch === " ")
8738
8738
  startWithSpace = true;
8739
8739
  else if (ch === "\n")
@@ -8741,9 +8741,9 @@ ${indent2}`) + "'";
8741
8741
  else
8742
8742
  break;
8743
8743
  }
8744
- let start = value.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
8744
+ let start = value2.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
8745
8745
  if (start) {
8746
- value = value.substring(start.length);
8746
+ value2 = value2.substring(start.length);
8747
8747
  start = start.replace(/\n+/g, `$&${indent2}`);
8748
8748
  }
8749
8749
  const indentSize = indent2 ? "2" : "1";
@@ -8754,7 +8754,7 @@ ${indent2}`) + "'";
8754
8754
  onComment();
8755
8755
  }
8756
8756
  if (!literal) {
8757
- const foldedValue = value.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent2}`);
8757
+ const foldedValue = value2.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent2}`);
8758
8758
  let literalFallback = false;
8759
8759
  const foldOptions = getFoldOptions(ctx, true);
8760
8760
  if (blockQuote !== "folded" && type !== Scalar.Scalar.BLOCK_FOLDED) {
@@ -8767,37 +8767,37 @@ ${indent2}`) + "'";
8767
8767
  return `>${header}
8768
8768
  ${indent2}${body}`;
8769
8769
  }
8770
- value = value.replace(/\n+/g, `$&${indent2}`);
8770
+ value2 = value2.replace(/\n+/g, `$&${indent2}`);
8771
8771
  return `|${header}
8772
- ${indent2}${start}${value}${end}`;
8772
+ ${indent2}${start}${value2}${end}`;
8773
8773
  }
8774
8774
  function plainString(item, ctx, onComment, onChompKeep) {
8775
- const { type, value } = item;
8775
+ const { type, value: value2 } = item;
8776
8776
  const { actualString, implicitKey, indent: indent2, indentStep, inFlow } = ctx;
8777
- if (implicitKey && value.includes("\n") || inFlow && /[[\]{},]/.test(value)) {
8778
- return quotedString(value, ctx);
8777
+ if (implicitKey && value2.includes("\n") || inFlow && /[[\]{},]/.test(value2)) {
8778
+ return quotedString(value2, ctx);
8779
8779
  }
8780
- if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value)) {
8781
- return implicitKey || inFlow || !value.includes("\n") ? quotedString(value, ctx) : blockString(item, ctx, onComment, onChompKeep);
8780
+ if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value2)) {
8781
+ return implicitKey || inFlow || !value2.includes("\n") ? quotedString(value2, ctx) : blockString(item, ctx, onComment, onChompKeep);
8782
8782
  }
8783
- if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN && value.includes("\n")) {
8783
+ if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN && value2.includes("\n")) {
8784
8784
  return blockString(item, ctx, onComment, onChompKeep);
8785
8785
  }
8786
- if (containsDocumentMarker(value)) {
8786
+ if (containsDocumentMarker(value2)) {
8787
8787
  if (indent2 === "") {
8788
8788
  ctx.forceBlockIndent = true;
8789
8789
  return blockString(item, ctx, onComment, onChompKeep);
8790
8790
  } else if (implicitKey && indent2 === indentStep) {
8791
- return quotedString(value, ctx);
8791
+ return quotedString(value2, ctx);
8792
8792
  }
8793
8793
  }
8794
- const str = value.replace(/\n+/g, `$&
8794
+ const str = value2.replace(/\n+/g, `$&
8795
8795
  ${indent2}`);
8796
8796
  if (actualString) {
8797
8797
  const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
8798
8798
  const { compat, tags } = ctx.doc.schema;
8799
8799
  if (tags.some(test) || compat?.some(test))
8800
- return quotedString(value, ctx);
8800
+ return quotedString(value2, ctx);
8801
8801
  }
8802
8802
  return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent2, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
8803
8803
  }
@@ -8970,7 +8970,7 @@ var require_stringifyPair = __commonJS({
8970
8970
  var Scalar = require_Scalar();
8971
8971
  var stringify = require_stringify();
8972
8972
  var stringifyComment = require_stringifyComment();
8973
- function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
8973
+ function stringifyPair({ key, value: value2 }, ctx, onComment, onChompKeep) {
8974
8974
  const { allNullValues, doc, indent: indent2, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
8975
8975
  let keyComment = identity.isNode(key) && key.comment || null;
8976
8976
  if (simpleKeys) {
@@ -8982,7 +8982,7 @@ var require_stringifyPair = __commonJS({
8982
8982
  throw new Error(msg);
8983
8983
  }
8984
8984
  }
8985
- let explicitKey = !simpleKeys && (!key || keyComment && value == null && !ctx.inFlow || identity.isCollection(key) || (identity.isScalar(key) ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL : typeof key === "object"));
8985
+ let explicitKey = !simpleKeys && (!key || keyComment && value2 == null && !ctx.inFlow || identity.isCollection(key) || (identity.isScalar(key) ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL : typeof key === "object"));
8986
8986
  ctx = Object.assign({}, ctx, {
8987
8987
  allNullValues: false,
8988
8988
  implicitKey: !explicitKey && (simpleKeys || !allNullValues),
@@ -8997,12 +8997,12 @@ var require_stringifyPair = __commonJS({
8997
8997
  explicitKey = true;
8998
8998
  }
8999
8999
  if (ctx.inFlow) {
9000
- if (allNullValues || value == null) {
9000
+ if (allNullValues || value2 == null) {
9001
9001
  if (keyCommentDone && onComment)
9002
9002
  onComment();
9003
9003
  return str === "" ? "?" : explicitKey ? `? ${str}` : str;
9004
9004
  }
9005
- } else if (allNullValues && !simpleKeys || value == null && explicitKey) {
9005
+ } else if (allNullValues && !simpleKeys || value2 == null && explicitKey) {
9006
9006
  str = `? ${str}`;
9007
9007
  if (keyComment && !keyCommentDone) {
9008
9008
  str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
@@ -9023,26 +9023,26 @@ ${indent2}:`;
9023
9023
  str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
9024
9024
  }
9025
9025
  let vsb, vcb, valueComment;
9026
- if (identity.isNode(value)) {
9027
- vsb = !!value.spaceBefore;
9028
- vcb = value.commentBefore;
9029
- valueComment = value.comment;
9026
+ if (identity.isNode(value2)) {
9027
+ vsb = !!value2.spaceBefore;
9028
+ vcb = value2.commentBefore;
9029
+ valueComment = value2.comment;
9030
9030
  } else {
9031
9031
  vsb = false;
9032
9032
  vcb = null;
9033
9033
  valueComment = null;
9034
- if (value && typeof value === "object")
9035
- value = doc.createNode(value);
9034
+ if (value2 && typeof value2 === "object")
9035
+ value2 = doc.createNode(value2);
9036
9036
  }
9037
9037
  ctx.implicitKey = false;
9038
- if (!explicitKey && !keyComment && identity.isScalar(value))
9038
+ if (!explicitKey && !keyComment && identity.isScalar(value2))
9039
9039
  ctx.indentAtStart = str.length + 1;
9040
9040
  chompKeep = false;
9041
- if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value) && !value.flow && !value.tag && !value.anchor) {
9041
+ if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value2) && !value2.flow && !value2.tag && !value2.anchor) {
9042
9042
  ctx.indent = ctx.indent.substring(2);
9043
9043
  }
9044
9044
  let valueCommentDone = false;
9045
- const valueStr = stringify.stringify(value, ctx, () => valueCommentDone = true, () => chompKeep = true);
9045
+ const valueStr = stringify.stringify(value2, ctx, () => valueCommentDone = true, () => chompKeep = true);
9046
9046
  let ws = " ";
9047
9047
  if (keyComment || vsb || vcb) {
9048
9048
  ws = vsb ? "\n" : "";
@@ -9058,11 +9058,11 @@ ${stringifyComment.indentComment(cs, ctx.indent)}`;
9058
9058
  ws += `
9059
9059
  ${ctx.indent}`;
9060
9060
  }
9061
- } else if (!explicitKey && identity.isCollection(value)) {
9061
+ } else if (!explicitKey && identity.isCollection(value2)) {
9062
9062
  const vs0 = valueStr[0];
9063
9063
  const nl0 = valueStr.indexOf("\n");
9064
9064
  const hasNewline = nl0 !== -1;
9065
- const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
9065
+ const flow = ctx.inFlow ?? value2.flow ?? value2.items.length === 0;
9066
9066
  if (hasNewline || !flow) {
9067
9067
  let hasPropsLine = false;
9068
9068
  if (hasNewline && (vs0 === "&" || vs0 === "!")) {
@@ -9125,7 +9125,7 @@ var require_merge = __commonJS({
9125
9125
  var Scalar = require_Scalar();
9126
9126
  var MERGE_KEY = "<<";
9127
9127
  var merge = {
9128
- identify: (value) => value === MERGE_KEY || typeof value === "symbol" && value.description === MERGE_KEY,
9128
+ identify: (value2) => value2 === MERGE_KEY || typeof value2 === "symbol" && value2.description === MERGE_KEY,
9129
9129
  default: "key",
9130
9130
  tag: "tag:yaml.org,2002:merge",
9131
9131
  test: /^<<$/,
@@ -9135,8 +9135,8 @@ var require_merge = __commonJS({
9135
9135
  stringify: () => MERGE_KEY
9136
9136
  };
9137
9137
  var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
9138
- function addMergeToJSMap(ctx, map, value) {
9139
- const source2 = resolveAliasValue(ctx, value);
9138
+ function addMergeToJSMap(ctx, map, value2) {
9139
+ const source2 = resolveAliasValue(ctx, value2);
9140
9140
  if (identity.isSeq(source2))
9141
9141
  for (const it of source2.items)
9142
9142
  mergeValue(ctx, map, it);
@@ -9146,20 +9146,20 @@ var require_merge = __commonJS({
9146
9146
  else
9147
9147
  mergeValue(ctx, map, source2);
9148
9148
  }
9149
- function mergeValue(ctx, map, value) {
9150
- const source2 = resolveAliasValue(ctx, value);
9149
+ function mergeValue(ctx, map, value2) {
9150
+ const source2 = resolveAliasValue(ctx, value2);
9151
9151
  if (!identity.isMap(source2))
9152
9152
  throw new Error("Merge sources must be maps or map aliases");
9153
9153
  const srcMap = source2.toJSON(null, ctx, Map);
9154
- for (const [key, value2] of srcMap) {
9154
+ for (const [key, value3] of srcMap) {
9155
9155
  if (map instanceof Map) {
9156
9156
  if (!map.has(key))
9157
- map.set(key, value2);
9157
+ map.set(key, value3);
9158
9158
  } else if (map instanceof Set) {
9159
9159
  map.add(key);
9160
9160
  } else if (!Object.prototype.hasOwnProperty.call(map, key)) {
9161
9161
  Object.defineProperty(map, key, {
9162
- value: value2,
9162
+ value: value3,
9163
9163
  writable: true,
9164
9164
  enumerable: true,
9165
9165
  configurable: true
@@ -9168,8 +9168,8 @@ var require_merge = __commonJS({
9168
9168
  }
9169
9169
  return map;
9170
9170
  }
9171
- function resolveAliasValue(ctx, value) {
9172
- return ctx && identity.isAlias(value) ? value.resolve(ctx.doc, ctx) : value;
9171
+ function resolveAliasValue(ctx, value2) {
9172
+ return ctx && identity.isAlias(value2) ? value2.resolve(ctx.doc, ctx) : value2;
9173
9173
  }
9174
9174
  exports2.addMergeToJSMap = addMergeToJSMap;
9175
9175
  exports2.isMergeKey = isMergeKey;
@@ -9186,20 +9186,20 @@ var require_addPairToJSMap = __commonJS({
9186
9186
  var stringify = require_stringify();
9187
9187
  var identity = require_identity();
9188
9188
  var toJS = require_toJS();
9189
- function addPairToJSMap(ctx, map, { key, value }) {
9189
+ function addPairToJSMap(ctx, map, { key, value: value2 }) {
9190
9190
  if (identity.isNode(key) && key.addToJSMap)
9191
- key.addToJSMap(ctx, map, value);
9191
+ key.addToJSMap(ctx, map, value2);
9192
9192
  else if (merge.isMergeKey(ctx, key))
9193
- merge.addMergeToJSMap(ctx, map, value);
9193
+ merge.addMergeToJSMap(ctx, map, value2);
9194
9194
  else {
9195
9195
  const jsKey = toJS.toJS(key, "", ctx);
9196
9196
  if (map instanceof Map) {
9197
- map.set(jsKey, toJS.toJS(value, jsKey, ctx));
9197
+ map.set(jsKey, toJS.toJS(value2, jsKey, ctx));
9198
9198
  } else if (map instanceof Set) {
9199
9199
  map.add(jsKey);
9200
9200
  } else {
9201
9201
  const stringKey = stringifyKey(key, jsKey, ctx);
9202
- const jsValue = toJS.toJS(value, stringKey, ctx);
9202
+ const jsValue = toJS.toJS(value2, stringKey, ctx);
9203
9203
  if (stringKey in map)
9204
9204
  Object.defineProperty(map, stringKey, {
9205
9205
  value: jsValue,
@@ -9249,24 +9249,24 @@ var require_Pair = __commonJS({
9249
9249
  var stringifyPair = require_stringifyPair();
9250
9250
  var addPairToJSMap = require_addPairToJSMap();
9251
9251
  var identity = require_identity();
9252
- function createPair(key, value, ctx) {
9252
+ function createPair(key, value2, ctx) {
9253
9253
  const k = createNode.createNode(key, void 0, ctx);
9254
- const v = createNode.createNode(value, void 0, ctx);
9254
+ const v = createNode.createNode(value2, void 0, ctx);
9255
9255
  return new Pair(k, v);
9256
9256
  }
9257
9257
  var Pair = class _Pair {
9258
- constructor(key, value = null) {
9258
+ constructor(key, value2 = null) {
9259
9259
  Object.defineProperty(this, identity.NODE_TYPE, { value: identity.PAIR });
9260
9260
  this.key = key;
9261
- this.value = value;
9261
+ this.value = value2;
9262
9262
  }
9263
9263
  clone(schema) {
9264
- let { key, value } = this;
9264
+ let { key, value: value2 } = this;
9265
9265
  if (identity.isNode(key))
9266
9266
  key = key.clone(schema);
9267
- if (identity.isNode(value))
9268
- value = value.clone(schema);
9269
- return new _Pair(key, value);
9267
+ if (identity.isNode(value2))
9268
+ value2 = value2.clone(schema);
9269
+ return new _Pair(key, value2);
9270
9270
  }
9271
9271
  toJSON(_, ctx) {
9272
9272
  const pair = ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
@@ -9469,17 +9469,17 @@ var require_YAMLMap = __commonJS({
9469
9469
  static from(schema, obj, ctx) {
9470
9470
  const { keepUndefined, replacer } = ctx;
9471
9471
  const map = new this(schema);
9472
- const add = (key, value) => {
9472
+ const add = (key, value2) => {
9473
9473
  if (typeof replacer === "function")
9474
- value = replacer.call(obj, key, value);
9474
+ value2 = replacer.call(obj, key, value2);
9475
9475
  else if (Array.isArray(replacer) && !replacer.includes(key))
9476
9476
  return;
9477
- if (value !== void 0 || keepUndefined)
9478
- map.items.push(Pair.createPair(key, value, ctx));
9477
+ if (value2 !== void 0 || keepUndefined)
9478
+ map.items.push(Pair.createPair(key, value2, ctx));
9479
9479
  };
9480
9480
  if (obj instanceof Map) {
9481
- for (const [key, value] of obj)
9482
- add(key, value);
9481
+ for (const [key, value2] of obj)
9482
+ add(key, value2);
9483
9483
  } else if (obj && typeof obj === "object") {
9484
9484
  for (const key of Object.keys(obj))
9485
9485
  add(key, obj[key]);
@@ -9537,8 +9537,8 @@ var require_YAMLMap = __commonJS({
9537
9537
  has(key) {
9538
9538
  return !!findPair(this.items, key);
9539
9539
  }
9540
- set(key, value) {
9541
- this.add(new Pair.Pair(key, value), true);
9540
+ set(key, value2) {
9541
+ this.add(new Pair.Pair(key, value2), true);
9542
9542
  }
9543
9543
  /**
9544
9544
  * @param ctx - Conversion context, originally set in Document#toJS()
@@ -9616,8 +9616,8 @@ var require_YAMLSeq = __commonJS({
9616
9616
  super(identity.SEQ, schema);
9617
9617
  this.items = [];
9618
9618
  }
9619
- add(value) {
9620
- this.items.push(value);
9619
+ add(value2) {
9620
+ this.items.push(value2);
9621
9621
  }
9622
9622
  /**
9623
9623
  * Removes a value from the collection.
@@ -9658,15 +9658,15 @@ var require_YAMLSeq = __commonJS({
9658
9658
  * If `key` does not contain a representation of an integer, this will throw.
9659
9659
  * It may be wrapped in a `Scalar`.
9660
9660
  */
9661
- set(key, value) {
9661
+ set(key, value2) {
9662
9662
  const idx = asItemIndex(key);
9663
9663
  if (typeof idx !== "number")
9664
9664
  throw new Error(`Expected a valid index, not ${key}.`);
9665
9665
  const prev = this.items[idx];
9666
- if (identity.isScalar(prev) && Scalar.isScalarValue(value))
9667
- prev.value = value;
9666
+ if (identity.isScalar(prev) && Scalar.isScalarValue(value2))
9667
+ prev.value = value2;
9668
9668
  else
9669
- this.items[idx] = value;
9669
+ this.items[idx] = value2;
9670
9670
  }
9671
9671
  toJSON(_, ctx) {
9672
9672
  const seq = [];
@@ -9742,7 +9742,7 @@ var require_string = __commonJS({
9742
9742
  "use strict";
9743
9743
  var stringifyString = require_stringifyString();
9744
9744
  var string = {
9745
- identify: (value) => typeof value === "string",
9745
+ identify: (value2) => typeof value2 === "string",
9746
9746
  default: true,
9747
9747
  tag: "tag:yaml.org,2002:str",
9748
9748
  resolve: (str) => str,
@@ -9761,7 +9761,7 @@ var require_null = __commonJS({
9761
9761
  "use strict";
9762
9762
  var Scalar = require_Scalar();
9763
9763
  var nullTag = {
9764
- identify: (value) => value == null,
9764
+ identify: (value2) => value2 == null,
9765
9765
  createNode: () => new Scalar.Scalar(null),
9766
9766
  default: true,
9767
9767
  tag: "tag:yaml.org,2002:null",
@@ -9779,18 +9779,18 @@ var require_bool = __commonJS({
9779
9779
  "use strict";
9780
9780
  var Scalar = require_Scalar();
9781
9781
  var boolTag = {
9782
- identify: (value) => typeof value === "boolean",
9782
+ identify: (value2) => typeof value2 === "boolean",
9783
9783
  default: true,
9784
9784
  tag: "tag:yaml.org,2002:bool",
9785
9785
  test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
9786
9786
  resolve: (str) => new Scalar.Scalar(str[0] === "t" || str[0] === "T"),
9787
- stringify({ source: source2, value }, ctx) {
9787
+ stringify({ source: source2, value: value2 }, ctx) {
9788
9788
  if (source2 && boolTag.test.test(source2)) {
9789
9789
  const sv = source2[0] === "t" || source2[0] === "T";
9790
- if (value === sv)
9790
+ if (value2 === sv)
9791
9791
  return source2;
9792
9792
  }
9793
- return value ? ctx.options.trueStr : ctx.options.falseStr;
9793
+ return value2 ? ctx.options.trueStr : ctx.options.falseStr;
9794
9794
  }
9795
9795
  };
9796
9796
  exports2.boolTag = boolTag;
@@ -9801,13 +9801,13 @@ var require_bool = __commonJS({
9801
9801
  var require_stringifyNumber = __commonJS({
9802
9802
  "node_modules/yaml/dist/stringify/stringifyNumber.js"(exports2) {
9803
9803
  "use strict";
9804
- function stringifyNumber({ format: format3, minFractionDigits, tag, value }) {
9805
- if (typeof value === "bigint")
9806
- return String(value);
9807
- const num = typeof value === "number" ? value : Number(value);
9804
+ function stringifyNumber({ format: format3, minFractionDigits, tag, value: value2 }) {
9805
+ if (typeof value2 === "bigint")
9806
+ return String(value2);
9807
+ const num = typeof value2 === "number" ? value2 : Number(value2);
9808
9808
  if (!isFinite(num))
9809
9809
  return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
9810
- let n = Object.is(value, -0) ? "-0" : JSON.stringify(value);
9810
+ let n = Object.is(value2, -0) ? "-0" : JSON.stringify(value2);
9811
9811
  if (!format3 && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
9812
9812
  let i = n.indexOf(".");
9813
9813
  if (i < 0) {
@@ -9831,7 +9831,7 @@ var require_float = __commonJS({
9831
9831
  var Scalar = require_Scalar();
9832
9832
  var stringifyNumber = require_stringifyNumber();
9833
9833
  var floatNaN = {
9834
- identify: (value) => typeof value === "number",
9834
+ identify: (value2) => typeof value2 === "number",
9835
9835
  default: true,
9836
9836
  tag: "tag:yaml.org,2002:float",
9837
9837
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
@@ -9839,7 +9839,7 @@ var require_float = __commonJS({
9839
9839
  stringify: stringifyNumber.stringifyNumber
9840
9840
  };
9841
9841
  var floatExp = {
9842
- identify: (value) => typeof value === "number",
9842
+ identify: (value2) => typeof value2 === "number",
9843
9843
  default: true,
9844
9844
  tag: "tag:yaml.org,2002:float",
9845
9845
  format: "EXP",
@@ -9851,7 +9851,7 @@ var require_float = __commonJS({
9851
9851
  }
9852
9852
  };
9853
9853
  var float = {
9854
- identify: (value) => typeof value === "number",
9854
+ identify: (value2) => typeof value2 === "number",
9855
9855
  default: true,
9856
9856
  tag: "tag:yaml.org,2002:float",
9857
9857
  test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
@@ -9875,16 +9875,16 @@ var require_int = __commonJS({
9875
9875
  "node_modules/yaml/dist/schema/core/int.js"(exports2) {
9876
9876
  "use strict";
9877
9877
  var stringifyNumber = require_stringifyNumber();
9878
- var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
9878
+ var intIdentify = (value2) => typeof value2 === "bigint" || Number.isInteger(value2);
9879
9879
  var intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
9880
9880
  function intStringify(node, radix, prefix) {
9881
- const { value } = node;
9882
- if (intIdentify(value) && value >= 0)
9883
- return prefix + value.toString(radix);
9881
+ const { value: value2 } = node;
9882
+ if (intIdentify(value2) && value2 >= 0)
9883
+ return prefix + value2.toString(radix);
9884
9884
  return stringifyNumber.stringifyNumber(node);
9885
9885
  }
9886
9886
  var intOct = {
9887
- identify: (value) => intIdentify(value) && value >= 0,
9887
+ identify: (value2) => intIdentify(value2) && value2 >= 0,
9888
9888
  default: true,
9889
9889
  tag: "tag:yaml.org,2002:int",
9890
9890
  format: "OCT",
@@ -9901,7 +9901,7 @@ var require_int = __commonJS({
9901
9901
  stringify: stringifyNumber.stringifyNumber
9902
9902
  };
9903
9903
  var intHex = {
9904
- identify: (value) => intIdentify(value) && value >= 0,
9904
+ identify: (value2) => intIdentify(value2) && value2 >= 0,
9905
9905
  default: true,
9906
9906
  tag: "tag:yaml.org,2002:int",
9907
9907
  format: "HEX",
@@ -9950,20 +9950,20 @@ var require_schema3 = __commonJS({
9950
9950
  var Scalar = require_Scalar();
9951
9951
  var map = require_map();
9952
9952
  var seq = require_seq();
9953
- function intIdentify(value) {
9954
- return typeof value === "bigint" || Number.isInteger(value);
9953
+ function intIdentify(value2) {
9954
+ return typeof value2 === "bigint" || Number.isInteger(value2);
9955
9955
  }
9956
- var stringifyJSON = ({ value }) => JSON.stringify(value);
9956
+ var stringifyJSON = ({ value: value2 }) => JSON.stringify(value2);
9957
9957
  var jsonScalars = [
9958
9958
  {
9959
- identify: (value) => typeof value === "string",
9959
+ identify: (value2) => typeof value2 === "string",
9960
9960
  default: true,
9961
9961
  tag: "tag:yaml.org,2002:str",
9962
9962
  resolve: (str) => str,
9963
9963
  stringify: stringifyJSON
9964
9964
  },
9965
9965
  {
9966
- identify: (value) => value == null,
9966
+ identify: (value2) => value2 == null,
9967
9967
  createNode: () => new Scalar.Scalar(null),
9968
9968
  default: true,
9969
9969
  tag: "tag:yaml.org,2002:null",
@@ -9972,7 +9972,7 @@ var require_schema3 = __commonJS({
9972
9972
  stringify: stringifyJSON
9973
9973
  },
9974
9974
  {
9975
- identify: (value) => typeof value === "boolean",
9975
+ identify: (value2) => typeof value2 === "boolean",
9976
9976
  default: true,
9977
9977
  tag: "tag:yaml.org,2002:bool",
9978
9978
  test: /^true$|^false$/,
@@ -9985,10 +9985,10 @@ var require_schema3 = __commonJS({
9985
9985
  tag: "tag:yaml.org,2002:int",
9986
9986
  test: /^-?(?:0|[1-9][0-9]*)$/,
9987
9987
  resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
9988
- stringify: ({ value }) => intIdentify(value) ? value.toString() : JSON.stringify(value)
9988
+ stringify: ({ value: value2 }) => intIdentify(value2) ? value2.toString() : JSON.stringify(value2)
9989
9989
  },
9990
9990
  {
9991
- identify: (value) => typeof value === "number",
9991
+ identify: (value2) => typeof value2 === "number",
9992
9992
  default: true,
9993
9993
  tag: "tag:yaml.org,2002:float",
9994
9994
  test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
@@ -10018,7 +10018,7 @@ var require_binary = __commonJS({
10018
10018
  var Scalar = require_Scalar();
10019
10019
  var stringifyString = require_stringifyString();
10020
10020
  var binary = {
10021
- identify: (value) => value instanceof Uint8Array,
10021
+ identify: (value2) => value2 instanceof Uint8Array,
10022
10022
  // Buffer inherits from Uint8Array
10023
10023
  default: false,
10024
10024
  tag: "tag:yaml.org,2002:binary",
@@ -10044,10 +10044,10 @@ var require_binary = __commonJS({
10044
10044
  return src;
10045
10045
  }
10046
10046
  },
10047
- stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
10048
- if (!value)
10047
+ stringify({ comment, type, value: value2 }, ctx, onComment, onChompKeep) {
10048
+ if (!value2)
10049
10049
  return "";
10050
- const buf = value;
10050
+ const buf = value2;
10051
10051
  let str;
10052
10052
  if (typeof node_buffer.Buffer === "function") {
10053
10053
  str = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
@@ -10119,25 +10119,25 @@ ${cn.comment}` : item.comment;
10119
10119
  for (let it of iterable) {
10120
10120
  if (typeof replacer === "function")
10121
10121
  it = replacer.call(iterable, String(i++), it);
10122
- let key, value;
10122
+ let key, value2;
10123
10123
  if (Array.isArray(it)) {
10124
10124
  if (it.length === 2) {
10125
10125
  key = it[0];
10126
- value = it[1];
10126
+ value2 = it[1];
10127
10127
  } else
10128
10128
  throw new TypeError(`Expected [key, value] tuple: ${it}`);
10129
10129
  } else if (it && it instanceof Object) {
10130
10130
  const keys = Object.keys(it);
10131
10131
  if (keys.length === 1) {
10132
10132
  key = keys[0];
10133
- value = it[key];
10133
+ value2 = it[key];
10134
10134
  } else {
10135
10135
  throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);
10136
10136
  }
10137
10137
  } else {
10138
10138
  key = it;
10139
10139
  }
10140
- pairs2.items.push(Pair.createPair(key, value, ctx));
10140
+ pairs2.items.push(Pair.createPair(key, value2, ctx));
10141
10141
  }
10142
10142
  return pairs2;
10143
10143
  }
@@ -10184,16 +10184,16 @@ var require_omap = __commonJS({
10184
10184
  if (ctx?.onCreate)
10185
10185
  ctx.onCreate(map);
10186
10186
  for (const pair of this.items) {
10187
- let key, value;
10187
+ let key, value2;
10188
10188
  if (identity.isPair(pair)) {
10189
10189
  key = toJS.toJS(pair.key, "", ctx);
10190
- value = toJS.toJS(pair.value, key, ctx);
10190
+ value2 = toJS.toJS(pair.value, key, ctx);
10191
10191
  } else {
10192
10192
  key = toJS.toJS(pair, "", ctx);
10193
10193
  }
10194
10194
  if (map.has(key))
10195
10195
  throw new Error("Ordered maps must not include duplicate keys");
10196
- map.set(key, value);
10196
+ map.set(key, value2);
10197
10197
  }
10198
10198
  return map;
10199
10199
  }
@@ -10207,7 +10207,7 @@ var require_omap = __commonJS({
10207
10207
  YAMLOMap.tag = "tag:yaml.org,2002:omap";
10208
10208
  var omap = {
10209
10209
  collection: "seq",
10210
- identify: (value) => value instanceof Map,
10210
+ identify: (value2) => value2 instanceof Map,
10211
10211
  nodeClass: YAMLOMap,
10212
10212
  default: false,
10213
10213
  tag: "tag:yaml.org,2002:omap",
@@ -10237,14 +10237,14 @@ var require_bool2 = __commonJS({
10237
10237
  "node_modules/yaml/dist/schema/yaml-1.1/bool.js"(exports2) {
10238
10238
  "use strict";
10239
10239
  var Scalar = require_Scalar();
10240
- function boolStringify({ value, source: source2 }, ctx) {
10241
- const boolObj = value ? trueTag : falseTag;
10240
+ function boolStringify({ value: value2, source: source2 }, ctx) {
10241
+ const boolObj = value2 ? trueTag : falseTag;
10242
10242
  if (source2 && boolObj.test.test(source2))
10243
10243
  return source2;
10244
- return value ? ctx.options.trueStr : ctx.options.falseStr;
10244
+ return value2 ? ctx.options.trueStr : ctx.options.falseStr;
10245
10245
  }
10246
10246
  var trueTag = {
10247
- identify: (value) => value === true,
10247
+ identify: (value2) => value2 === true,
10248
10248
  default: true,
10249
10249
  tag: "tag:yaml.org,2002:bool",
10250
10250
  test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,
@@ -10252,7 +10252,7 @@ var require_bool2 = __commonJS({
10252
10252
  stringify: boolStringify
10253
10253
  };
10254
10254
  var falseTag = {
10255
- identify: (value) => value === false,
10255
+ identify: (value2) => value2 === false,
10256
10256
  default: true,
10257
10257
  tag: "tag:yaml.org,2002:bool",
10258
10258
  test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,
@@ -10271,7 +10271,7 @@ var require_float2 = __commonJS({
10271
10271
  var Scalar = require_Scalar();
10272
10272
  var stringifyNumber = require_stringifyNumber();
10273
10273
  var floatNaN = {
10274
- identify: (value) => typeof value === "number",
10274
+ identify: (value2) => typeof value2 === "number",
10275
10275
  default: true,
10276
10276
  tag: "tag:yaml.org,2002:float",
10277
10277
  test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
@@ -10279,7 +10279,7 @@ var require_float2 = __commonJS({
10279
10279
  stringify: stringifyNumber.stringifyNumber
10280
10280
  };
10281
10281
  var floatExp = {
10282
- identify: (value) => typeof value === "number",
10282
+ identify: (value2) => typeof value2 === "number",
10283
10283
  default: true,
10284
10284
  tag: "tag:yaml.org,2002:float",
10285
10285
  format: "EXP",
@@ -10291,7 +10291,7 @@ var require_float2 = __commonJS({
10291
10291
  }
10292
10292
  };
10293
10293
  var float = {
10294
- identify: (value) => typeof value === "number",
10294
+ identify: (value2) => typeof value2 === "number",
10295
10295
  default: true,
10296
10296
  tag: "tag:yaml.org,2002:float",
10297
10297
  test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
@@ -10318,7 +10318,7 @@ var require_int2 = __commonJS({
10318
10318
  "node_modules/yaml/dist/schema/yaml-1.1/int.js"(exports2) {
10319
10319
  "use strict";
10320
10320
  var stringifyNumber = require_stringifyNumber();
10321
- var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
10321
+ var intIdentify = (value2) => typeof value2 === "bigint" || Number.isInteger(value2);
10322
10322
  function intResolve(str, offset, radix, { intAsBigInt }) {
10323
10323
  const sign = str[0];
10324
10324
  if (sign === "-" || sign === "+")
@@ -10343,10 +10343,10 @@ var require_int2 = __commonJS({
10343
10343
  return sign === "-" ? -1 * n : n;
10344
10344
  }
10345
10345
  function intStringify(node, radix, prefix) {
10346
- const { value } = node;
10347
- if (intIdentify(value)) {
10348
- const str = value.toString(radix);
10349
- return value < 0 ? "-" + prefix + str.substr(1) : prefix + str;
10346
+ const { value: value2 } = node;
10347
+ if (intIdentify(value2)) {
10348
+ const str = value2.toString(radix);
10349
+ return value2 < 0 ? "-" + prefix + str.substr(1) : prefix + str;
10350
10350
  }
10351
10351
  return stringifyNumber.stringifyNumber(node);
10352
10352
  }
@@ -10424,13 +10424,13 @@ var require_set = __commonJS({
10424
10424
  const pair = YAMLMap.findPair(this.items, key);
10425
10425
  return !keepPair && identity.isPair(pair) ? identity.isScalar(pair.key) ? pair.key.value : pair.key : pair;
10426
10426
  }
10427
- set(key, value) {
10428
- if (typeof value !== "boolean")
10429
- throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value}`);
10427
+ set(key, value2) {
10428
+ if (typeof value2 !== "boolean")
10429
+ throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value2}`);
10430
10430
  const prev = YAMLMap.findPair(this.items, key);
10431
- if (prev && !value) {
10431
+ if (prev && !value2) {
10432
10432
  this.items.splice(this.items.indexOf(prev), 1);
10433
- } else if (!prev && value) {
10433
+ } else if (!prev && value2) {
10434
10434
  this.items.push(new Pair.Pair(key));
10435
10435
  }
10436
10436
  }
@@ -10449,10 +10449,10 @@ var require_set = __commonJS({
10449
10449
  const { replacer } = ctx;
10450
10450
  const set2 = new this(schema);
10451
10451
  if (iterable && Symbol.iterator in Object(iterable))
10452
- for (let value of iterable) {
10452
+ for (let value2 of iterable) {
10453
10453
  if (typeof replacer === "function")
10454
- value = replacer.call(iterable, value, value);
10455
- set2.items.push(Pair.createPair(value, null, ctx));
10454
+ value2 = replacer.call(iterable, value2, value2);
10455
+ set2.items.push(Pair.createPair(value2, null, ctx));
10456
10456
  }
10457
10457
  return set2;
10458
10458
  }
@@ -10460,7 +10460,7 @@ var require_set = __commonJS({
10460
10460
  YAMLSet.tag = "tag:yaml.org,2002:set";
10461
10461
  var set = {
10462
10462
  collection: "map",
10463
- identify: (value) => value instanceof Set,
10463
+ identify: (value2) => value2 instanceof Set,
10464
10464
  nodeClass: YAMLSet,
10465
10465
  default: false,
10466
10466
  tag: "tag:yaml.org,2002:set",
@@ -10494,33 +10494,33 @@ var require_timestamp = __commonJS({
10494
10494
  return sign === "-" ? num(-1) * res : res;
10495
10495
  }
10496
10496
  function stringifySexagesimal(node) {
10497
- let { value } = node;
10497
+ let { value: value2 } = node;
10498
10498
  let num = (n) => n;
10499
- if (typeof value === "bigint")
10499
+ if (typeof value2 === "bigint")
10500
10500
  num = (n) => BigInt(n);
10501
- else if (isNaN(value) || !isFinite(value))
10501
+ else if (isNaN(value2) || !isFinite(value2))
10502
10502
  return stringifyNumber.stringifyNumber(node);
10503
10503
  let sign = "";
10504
- if (value < 0) {
10504
+ if (value2 < 0) {
10505
10505
  sign = "-";
10506
- value *= num(-1);
10506
+ value2 *= num(-1);
10507
10507
  }
10508
10508
  const _60 = num(60);
10509
- const parts = [value % _60];
10510
- if (value < 60) {
10509
+ const parts = [value2 % _60];
10510
+ if (value2 < 60) {
10511
10511
  parts.unshift(0);
10512
10512
  } else {
10513
- value = (value - parts[0]) / _60;
10514
- parts.unshift(value % _60);
10515
- if (value >= 60) {
10516
- value = (value - parts[0]) / _60;
10517
- parts.unshift(value);
10513
+ value2 = (value2 - parts[0]) / _60;
10514
+ parts.unshift(value2 % _60);
10515
+ if (value2 >= 60) {
10516
+ value2 = (value2 - parts[0]) / _60;
10517
+ parts.unshift(value2);
10518
10518
  }
10519
10519
  }
10520
10520
  return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
10521
10521
  }
10522
10522
  var intTime = {
10523
- identify: (value) => typeof value === "bigint" || Number.isInteger(value),
10523
+ identify: (value2) => typeof value2 === "bigint" || Number.isInteger(value2),
10524
10524
  default: true,
10525
10525
  tag: "tag:yaml.org,2002:int",
10526
10526
  format: "TIME",
@@ -10529,7 +10529,7 @@ var require_timestamp = __commonJS({
10529
10529
  stringify: stringifySexagesimal
10530
10530
  };
10531
10531
  var floatTime = {
10532
- identify: (value) => typeof value === "number",
10532
+ identify: (value2) => typeof value2 === "number",
10533
10533
  default: true,
10534
10534
  tag: "tag:yaml.org,2002:float",
10535
10535
  format: "TIME",
@@ -10538,7 +10538,7 @@ var require_timestamp = __commonJS({
10538
10538
  stringify: stringifySexagesimal
10539
10539
  };
10540
10540
  var timestamp = {
10541
- identify: (value) => value instanceof Date,
10541
+ identify: (value2) => value2 instanceof Date,
10542
10542
  default: true,
10543
10543
  tag: "tag:yaml.org,2002:timestamp",
10544
10544
  // If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part
@@ -10551,17 +10551,17 @@ var require_timestamp = __commonJS({
10551
10551
  throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
10552
10552
  const [, year, month, day, hour, minute, second] = match.map(Number);
10553
10553
  const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0;
10554
- let date = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
10554
+ let date2 = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
10555
10555
  const tz = match[8];
10556
10556
  if (tz && tz !== "Z") {
10557
10557
  let d = parseSexagesimal(tz, false);
10558
10558
  if (Math.abs(d) < 30)
10559
10559
  d *= 60;
10560
- date -= 6e4 * d;
10560
+ date2 -= 6e4 * d;
10561
10561
  }
10562
- return new Date(date);
10562
+ return new Date(date2);
10563
10563
  },
10564
- stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
10564
+ stringify: ({ value: value2 }) => value2?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
10565
10565
  };
10566
10566
  exports2.floatTime = floatTime;
10567
10567
  exports2.intTime = intTime;
@@ -10835,7 +10835,7 @@ var require_Document = __commonJS({
10835
10835
  var createNode = require_createNode();
10836
10836
  var directives = require_directives();
10837
10837
  var Document = class _Document {
10838
- constructor(value, replacer, options) {
10838
+ constructor(value2, replacer, options) {
10839
10839
  this.commentBefore = null;
10840
10840
  this.comment = null;
10841
10841
  this.errors = [];
@@ -10867,7 +10867,7 @@ var require_Document = __commonJS({
10867
10867
  } else
10868
10868
  this.directives = new directives.Directives({ version });
10869
10869
  this.setSchema(version, options);
10870
- this.contents = value === void 0 ? null : this.createNode(value, _replacer, options);
10870
+ this.contents = value2 === void 0 ? null : this.createNode(value2, _replacer, options);
10871
10871
  }
10872
10872
  /**
10873
10873
  * Create a deep copy of this Document and its contents.
@@ -10892,14 +10892,14 @@ var require_Document = __commonJS({
10892
10892
  return copy;
10893
10893
  }
10894
10894
  /** Adds a value to the document. */
10895
- add(value) {
10895
+ add(value2) {
10896
10896
  if (assertCollection(this.contents))
10897
- this.contents.add(value);
10897
+ this.contents.add(value2);
10898
10898
  }
10899
10899
  /** Adds a value to the document. */
10900
- addIn(path, value) {
10900
+ addIn(path, value2) {
10901
10901
  if (assertCollection(this.contents))
10902
- this.contents.addIn(path, value);
10902
+ this.contents.addIn(path, value2);
10903
10903
  }
10904
10904
  /**
10905
10905
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -10918,10 +10918,10 @@ var require_Document = __commonJS({
10918
10918
  }
10919
10919
  return new Alias.Alias(node.anchor);
10920
10920
  }
10921
- createNode(value, replacer, options) {
10921
+ createNode(value2, replacer, options) {
10922
10922
  let _replacer = void 0;
10923
10923
  if (typeof replacer === "function") {
10924
- value = replacer.call({ "": value }, "", value);
10924
+ value2 = replacer.call({ "": value2 }, "", value2);
10925
10925
  _replacer = replacer;
10926
10926
  } else if (Array.isArray(replacer)) {
10927
10927
  const keyToStr = (v) => typeof v === "number" || v instanceof String || v instanceof Number;
@@ -10948,7 +10948,7 @@ var require_Document = __commonJS({
10948
10948
  schema: this.schema,
10949
10949
  sourceObjects
10950
10950
  };
10951
- const node = createNode.createNode(value, tag, ctx);
10951
+ const node = createNode.createNode(value2, tag, ctx);
10952
10952
  if (flow && identity.isCollection(node))
10953
10953
  node.flow = true;
10954
10954
  setAnchors();
@@ -10958,9 +10958,9 @@ var require_Document = __commonJS({
10958
10958
  * Convert a key and a value into a `Pair` using the current schema,
10959
10959
  * recursively wrapping all values as `Scalar` or `Collection` nodes.
10960
10960
  */
10961
- createPair(key, value, options = {}) {
10961
+ createPair(key, value2, options = {}) {
10962
10962
  const k = this.createNode(key, null, options);
10963
- const v = this.createNode(value, null, options);
10963
+ const v = this.createNode(value2, null, options);
10964
10964
  return new Pair.Pair(k, v);
10965
10965
  }
10966
10966
  /**
@@ -11019,24 +11019,24 @@ var require_Document = __commonJS({
11019
11019
  * Sets a value in this document. For `!!set`, `value` needs to be a
11020
11020
  * boolean to add/remove the item from the set.
11021
11021
  */
11022
- set(key, value) {
11022
+ set(key, value2) {
11023
11023
  if (this.contents == null) {
11024
- this.contents = Collection.collectionFromPath(this.schema, [key], value);
11024
+ this.contents = Collection.collectionFromPath(this.schema, [key], value2);
11025
11025
  } else if (assertCollection(this.contents)) {
11026
- this.contents.set(key, value);
11026
+ this.contents.set(key, value2);
11027
11027
  }
11028
11028
  }
11029
11029
  /**
11030
11030
  * Sets a value in this document. For `!!set`, `value` needs to be a
11031
11031
  * boolean to add/remove the item from the set.
11032
11032
  */
11033
- setIn(path, value) {
11033
+ setIn(path, value2) {
11034
11034
  if (Collection.isEmptyPath(path)) {
11035
- this.contents = value;
11035
+ this.contents = value2;
11036
11036
  } else if (this.contents == null) {
11037
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
11037
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value2);
11038
11038
  } else if (assertCollection(this.contents)) {
11039
- this.contents.setIn(path, value);
11039
+ this.contents.setIn(path, value2);
11040
11040
  }
11041
11041
  }
11042
11042
  /**
@@ -11422,7 +11422,7 @@ var require_resolve_block_map = __commonJS({
11422
11422
  let offset = bm.offset;
11423
11423
  let commentEnd = null;
11424
11424
  for (const collItem of bm.items) {
11425
- const { start, key, sep: sep2, value } = collItem;
11425
+ const { start, key, sep: sep2, value: value2 } = collItem;
11426
11426
  const keyProps = resolveProps.resolveProps(start, {
11427
11427
  indicator: "explicit-key-ind",
11428
11428
  next: key ?? sep2?.[0],
@@ -11465,7 +11465,7 @@ var require_resolve_block_map = __commonJS({
11465
11465
  onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
11466
11466
  const valueProps = resolveProps.resolveProps(sep2 ?? [], {
11467
11467
  indicator: "map-value-ind",
11468
- next: value,
11468
+ next: value2,
11469
11469
  offset: keyNode.range[2],
11470
11470
  onError,
11471
11471
  parentIndent: bm.indent,
@@ -11474,14 +11474,14 @@ var require_resolve_block_map = __commonJS({
11474
11474
  offset = valueProps.end;
11475
11475
  if (valueProps.found) {
11476
11476
  if (implicitKey) {
11477
- if (value?.type === "block-map" && !valueProps.hasNewline)
11477
+ if (value2?.type === "block-map" && !valueProps.hasNewline)
11478
11478
  onError(offset, "BLOCK_AS_IMPLICIT_KEY", "Nested mappings are not allowed in compact mappings");
11479
11479
  if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
11480
11480
  onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
11481
11481
  }
11482
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : composeEmptyNode(ctx, offset, sep2, null, valueProps, onError);
11482
+ const valueNode = value2 ? composeNode(ctx, value2, valueProps, onError) : composeEmptyNode(ctx, offset, sep2, null, valueProps, onError);
11483
11483
  if (ctx.schema.compat)
11484
- utilFlowIndentCheck.flowIndentCheck(bm.indent, value, onError);
11484
+ utilFlowIndentCheck.flowIndentCheck(bm.indent, value2, onError);
11485
11485
  offset = valueNode.range[2];
11486
11486
  const pair = new Pair.Pair(keyNode, valueNode);
11487
11487
  if (ctx.options.keepSourceTokens)
@@ -11527,18 +11527,18 @@ var require_resolve_block_seq = __commonJS({
11527
11527
  ctx.atKey = false;
11528
11528
  let offset = bs.offset;
11529
11529
  let commentEnd = null;
11530
- for (const { start, value } of bs.items) {
11530
+ for (const { start, value: value2 } of bs.items) {
11531
11531
  const props = resolveProps.resolveProps(start, {
11532
11532
  indicator: "seq-item-ind",
11533
- next: value,
11533
+ next: value2,
11534
11534
  offset,
11535
11535
  onError,
11536
11536
  parentIndent: bs.indent,
11537
11537
  startOnNewline: true
11538
11538
  });
11539
11539
  if (!props.found) {
11540
- if (props.anchor || props.tag || value) {
11541
- if (value?.type === "block-seq")
11540
+ if (props.anchor || props.tag || value2) {
11541
+ if (value2?.type === "block-seq")
11542
11542
  onError(props.end, "BAD_INDENT", "All sequence items must start at the same column");
11543
11543
  else
11544
11544
  onError(offset, "MISSING_CHAR", "Sequence item without - indicator");
@@ -11549,9 +11549,9 @@ var require_resolve_block_seq = __commonJS({
11549
11549
  continue;
11550
11550
  }
11551
11551
  }
11552
- const node = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
11552
+ const node = value2 ? composeNode(ctx, value2, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
11553
11553
  if (ctx.schema.compat)
11554
- utilFlowIndentCheck.flowIndentCheck(bs.indent, value, onError);
11554
+ utilFlowIndentCheck.flowIndentCheck(bs.indent, value2, onError);
11555
11555
  offset = node.range[2];
11556
11556
  seq.items.push(node);
11557
11557
  }
@@ -11633,7 +11633,7 @@ var require_resolve_flow_collection = __commonJS({
11633
11633
  let offset = fc.offset + fc.start.source.length;
11634
11634
  for (let i = 0; i < fc.items.length; ++i) {
11635
11635
  const collItem = fc.items[i];
11636
- const { start, key, sep: sep2, value } = collItem;
11636
+ const { start, key, sep: sep2, value: value2 } = collItem;
11637
11637
  const props = resolveProps.resolveProps(start, {
11638
11638
  flow: fcName,
11639
11639
  indicator: "explicit-key-ind",
@@ -11644,7 +11644,7 @@ var require_resolve_flow_collection = __commonJS({
11644
11644
  startOnNewline: false
11645
11645
  });
11646
11646
  if (!props.found) {
11647
- if (!props.anchor && !props.tag && !sep2 && !value) {
11647
+ if (!props.anchor && !props.tag && !sep2 && !value2) {
11648
11648
  if (i === 0 && props.comma)
11649
11649
  onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
11650
11650
  else if (i < fc.items.length - 1)
@@ -11699,10 +11699,10 @@ var require_resolve_flow_collection = __commonJS({
11699
11699
  }
11700
11700
  }
11701
11701
  if (!isMap && !sep2 && !props.found) {
11702
- const valueNode = value ? composeNode(ctx, value, props, onError) : composeEmptyNode(ctx, props.end, sep2, null, props, onError);
11702
+ const valueNode = value2 ? composeNode(ctx, value2, props, onError) : composeEmptyNode(ctx, props.end, sep2, null, props, onError);
11703
11703
  coll.items.push(valueNode);
11704
11704
  offset = valueNode.range[2];
11705
- if (isBlock(value))
11705
+ if (isBlock(value2))
11706
11706
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
11707
11707
  } else {
11708
11708
  ctx.atKey = true;
@@ -11714,7 +11714,7 @@ var require_resolve_flow_collection = __commonJS({
11714
11714
  const valueProps = resolveProps.resolveProps(sep2 ?? [], {
11715
11715
  flow: fcName,
11716
11716
  indicator: "map-value-ind",
11717
- next: value,
11717
+ next: value2,
11718
11718
  offset: keyNode.range[2],
11719
11719
  onError,
11720
11720
  parentIndent: fc.indent,
@@ -11734,15 +11734,15 @@ var require_resolve_flow_collection = __commonJS({
11734
11734
  if (props.start < valueProps.found.offset - 1024)
11735
11735
  onError(valueProps.found, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit flow sequence key");
11736
11736
  }
11737
- } else if (value) {
11738
- if ("source" in value && value.source?.[0] === ":")
11739
- onError(value, "MISSING_CHAR", `Missing space after : in ${fcName}`);
11737
+ } else if (value2) {
11738
+ if ("source" in value2 && value2.source?.[0] === ":")
11739
+ onError(value2, "MISSING_CHAR", `Missing space after : in ${fcName}`);
11740
11740
  else
11741
11741
  onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
11742
11742
  }
11743
- const valueNode = value ? composeNode(ctx, value, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep2, null, valueProps, onError) : null;
11743
+ const valueNode = value2 ? composeNode(ctx, value2, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep2, null, valueProps, onError) : null;
11744
11744
  if (valueNode) {
11745
- if (isBlock(value))
11745
+ if (isBlock(value2))
11746
11746
  onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
11747
11747
  } else if (valueProps.comment) {
11748
11748
  if (keyNode.comment)
@@ -11885,11 +11885,11 @@ var require_resolve_block_scalar = __commonJS({
11885
11885
  break;
11886
11886
  }
11887
11887
  if (chompStart === 0) {
11888
- const value2 = header.chomp === "+" && lines.length > 0 ? "\n".repeat(Math.max(1, lines.length - 1)) : "";
11888
+ const value3 = header.chomp === "+" && lines.length > 0 ? "\n".repeat(Math.max(1, lines.length - 1)) : "";
11889
11889
  let end2 = start + header.length;
11890
11890
  if (scalar2.source)
11891
11891
  end2 += scalar2.source.length;
11892
- return { value: value2, type, comment: header.comment, range: [start, end2, end2] };
11892
+ return { value: value3, type, comment: header.comment, range: [start, end2, end2] };
11893
11893
  }
11894
11894
  let trimIndent = scalar2.indent + header.indent;
11895
11895
  let offset = scalar2.offset + header.length;
@@ -11919,11 +11919,11 @@ var require_resolve_block_scalar = __commonJS({
11919
11919
  if (lines[i][0].length > trimIndent)
11920
11920
  chompStart = i + 1;
11921
11921
  }
11922
- let value = "";
11922
+ let value2 = "";
11923
11923
  let sep2 = "";
11924
11924
  let prevMoreIndented = false;
11925
11925
  for (let i = 0; i < contentStart; ++i)
11926
- value += lines[i][0].slice(trimIndent) + "\n";
11926
+ value2 += lines[i][0].slice(trimIndent) + "\n";
11927
11927
  for (let i = contentStart; i < chompStart; ++i) {
11928
11928
  let [indent2, content] = lines[i];
11929
11929
  offset += indent2.length + content.length + 1;
@@ -11937,23 +11937,23 @@ var require_resolve_block_scalar = __commonJS({
11937
11937
  indent2 = "";
11938
11938
  }
11939
11939
  if (type === Scalar.Scalar.BLOCK_LITERAL) {
11940
- value += sep2 + indent2.slice(trimIndent) + content;
11940
+ value2 += sep2 + indent2.slice(trimIndent) + content;
11941
11941
  sep2 = "\n";
11942
11942
  } else if (indent2.length > trimIndent || content[0] === " ") {
11943
11943
  if (sep2 === " ")
11944
11944
  sep2 = "\n";
11945
11945
  else if (!prevMoreIndented && sep2 === "\n")
11946
11946
  sep2 = "\n\n";
11947
- value += sep2 + indent2.slice(trimIndent) + content;
11947
+ value2 += sep2 + indent2.slice(trimIndent) + content;
11948
11948
  sep2 = "\n";
11949
11949
  prevMoreIndented = true;
11950
11950
  } else if (content === "") {
11951
11951
  if (sep2 === "\n")
11952
- value += "\n";
11952
+ value2 += "\n";
11953
11953
  else
11954
11954
  sep2 = "\n";
11955
11955
  } else {
11956
- value += sep2 + content;
11956
+ value2 += sep2 + content;
11957
11957
  sep2 = " ";
11958
11958
  prevMoreIndented = false;
11959
11959
  }
@@ -11963,15 +11963,15 @@ var require_resolve_block_scalar = __commonJS({
11963
11963
  break;
11964
11964
  case "+":
11965
11965
  for (let i = chompStart; i < lines.length; ++i)
11966
- value += "\n" + lines[i][0].slice(trimIndent);
11967
- if (value[value.length - 1] !== "\n")
11968
- value += "\n";
11966
+ value2 += "\n" + lines[i][0].slice(trimIndent);
11967
+ if (value2[value2.length - 1] !== "\n")
11968
+ value2 += "\n";
11969
11969
  break;
11970
11970
  default:
11971
- value += "\n";
11971
+ value2 += "\n";
11972
11972
  }
11973
11973
  const end = start + header.length + scalar2.source.length;
11974
- return { value, type, comment: header.comment, range: [start, end, end] };
11974
+ return { value: value2, type, comment: header.comment, range: [start, end, end] };
11975
11975
  }
11976
11976
  function parseBlockScalarHeader({ offset, props }, strict, onError) {
11977
11977
  if (props[0].type !== "block-scalar-header") {
@@ -12056,20 +12056,20 @@ var require_resolve_flow_scalar = __commonJS({
12056
12056
  function resolveFlowScalar(scalar2, strict, onError) {
12057
12057
  const { offset, type, source: source2, end } = scalar2;
12058
12058
  let _type;
12059
- let value;
12059
+ let value2;
12060
12060
  const _onError = (rel, code, msg) => onError(offset + rel, code, msg);
12061
12061
  switch (type) {
12062
12062
  case "scalar":
12063
12063
  _type = Scalar.Scalar.PLAIN;
12064
- value = plainValue(source2, _onError);
12064
+ value2 = plainValue(source2, _onError);
12065
12065
  break;
12066
12066
  case "single-quoted-scalar":
12067
12067
  _type = Scalar.Scalar.QUOTE_SINGLE;
12068
- value = singleQuotedValue(source2, _onError);
12068
+ value2 = singleQuotedValue(source2, _onError);
12069
12069
  break;
12070
12070
  case "double-quoted-scalar":
12071
12071
  _type = Scalar.Scalar.QUOTE_DOUBLE;
12072
- value = doubleQuotedValue(source2, _onError);
12072
+ value2 = doubleQuotedValue(source2, _onError);
12073
12073
  break;
12074
12074
  /* istanbul ignore next should not happen */
12075
12075
  default:
@@ -12084,7 +12084,7 @@ var require_resolve_flow_scalar = __commonJS({
12084
12084
  const valueEnd = offset + source2.length;
12085
12085
  const re = resolveEnd.resolveEnd(end, valueEnd, strict, onError);
12086
12086
  return {
12087
- value,
12087
+ value: value2,
12088
12088
  type: _type,
12089
12089
  comment: re.comment,
12090
12090
  range: [offset, valueEnd, re.offset]
@@ -12277,28 +12277,28 @@ var require_compose_scalar = __commonJS({
12277
12277
  var resolveBlockScalar = require_resolve_block_scalar();
12278
12278
  var resolveFlowScalar = require_resolve_flow_scalar();
12279
12279
  function composeScalar(ctx, token, tagToken, onError) {
12280
- const { value, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
12280
+ const { value: value2, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
12281
12281
  const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
12282
12282
  let tag;
12283
12283
  if (ctx.options.stringKeys && ctx.atKey) {
12284
12284
  tag = ctx.schema[identity.SCALAR];
12285
12285
  } else if (tagName)
12286
- tag = findScalarTagByName(ctx.schema, value, tagName, tagToken, onError);
12286
+ tag = findScalarTagByName(ctx.schema, value2, tagName, tagToken, onError);
12287
12287
  else if (token.type === "scalar")
12288
- tag = findScalarTagByTest(ctx, value, token, onError);
12288
+ tag = findScalarTagByTest(ctx, value2, token, onError);
12289
12289
  else
12290
12290
  tag = ctx.schema[identity.SCALAR];
12291
12291
  let scalar2;
12292
12292
  try {
12293
- const res = tag.resolve(value, (msg) => onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg), ctx.options);
12293
+ const res = tag.resolve(value2, (msg) => onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg), ctx.options);
12294
12294
  scalar2 = identity.isScalar(res) ? res : new Scalar.Scalar(res);
12295
12295
  } catch (error) {
12296
12296
  const msg = error instanceof Error ? error.message : String(error);
12297
12297
  onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
12298
- scalar2 = new Scalar.Scalar(value);
12298
+ scalar2 = new Scalar.Scalar(value2);
12299
12299
  }
12300
12300
  scalar2.range = range;
12301
- scalar2.source = value;
12301
+ scalar2.source = value2;
12302
12302
  if (type)
12303
12303
  scalar2.type = type;
12304
12304
  if (tagName)
@@ -12309,7 +12309,7 @@ var require_compose_scalar = __commonJS({
12309
12309
  scalar2.comment = comment;
12310
12310
  return scalar2;
12311
12311
  }
12312
- function findScalarTagByName(schema, value, tagName, tagToken, onError) {
12312
+ function findScalarTagByName(schema, value2, tagName, tagToken, onError) {
12313
12313
  if (tagName === "!")
12314
12314
  return schema[identity.SCALAR];
12315
12315
  const matchWithTest = [];
@@ -12322,7 +12322,7 @@ var require_compose_scalar = __commonJS({
12322
12322
  }
12323
12323
  }
12324
12324
  for (const tag of matchWithTest)
12325
- if (tag.test?.test(value))
12325
+ if (tag.test?.test(value2))
12326
12326
  return tag;
12327
12327
  const kt = schema.knownTags[tagName];
12328
12328
  if (kt && !kt.collection) {
@@ -12332,10 +12332,10 @@ var require_compose_scalar = __commonJS({
12332
12332
  onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, tagName !== "tag:yaml.org,2002:str");
12333
12333
  return schema[identity.SCALAR];
12334
12334
  }
12335
- function findScalarTagByTest({ atKey, directives, schema }, value, token, onError) {
12336
- const tag = schema.tags.find((tag2) => (tag2.default === true || atKey && tag2.default === "key") && tag2.test?.test(value)) || schema[identity.SCALAR];
12335
+ function findScalarTagByTest({ atKey, directives, schema }, value2, token, onError) {
12336
+ const tag = schema.tags.find((tag2) => (tag2.default === true || atKey && tag2.default === "key") && tag2.test?.test(value2)) || schema[identity.SCALAR];
12337
12337
  if (schema.compat) {
12338
- const compat = schema.compat.find((tag2) => tag2.default && tag2.test?.test(value)) ?? schema[identity.SCALAR];
12338
+ const compat = schema.compat.find((tag2) => tag2.default && tag2.test?.test(value2)) ?? schema[identity.SCALAR];
12339
12339
  if (tag.tag !== compat.tag) {
12340
12340
  const ts = directives.tagString(tag.tag);
12341
12341
  const cs = directives.tagString(compat.tag);
@@ -12493,7 +12493,7 @@ var require_compose_doc = __commonJS({
12493
12493
  var composeNode = require_compose_node();
12494
12494
  var resolveEnd = require_resolve_end();
12495
12495
  var resolveProps = require_resolve_props();
12496
- function composeDoc(options, directives, { offset, start, value, end }, onError) {
12496
+ function composeDoc(options, directives, { offset, start, value: value2, end }, onError) {
12497
12497
  const opts = Object.assign({ _directives: directives }, options);
12498
12498
  const doc = new Document.Document(void 0, opts);
12499
12499
  const ctx = {
@@ -12505,7 +12505,7 @@ var require_compose_doc = __commonJS({
12505
12505
  };
12506
12506
  const props = resolveProps.resolveProps(start, {
12507
12507
  indicator: "doc-start",
12508
- next: value ?? end?.[0],
12508
+ next: value2 ?? end?.[0],
12509
12509
  offset,
12510
12510
  onError,
12511
12511
  parentIndent: 0,
@@ -12513,10 +12513,10 @@ var require_compose_doc = __commonJS({
12513
12513
  });
12514
12514
  if (props.found) {
12515
12515
  doc.directives.docStart = true;
12516
- if (value && (value.type === "block-map" || value.type === "block-seq") && !props.hasNewline)
12516
+ if (value2 && (value2.type === "block-map" || value2.type === "block-seq") && !props.hasNewline)
12517
12517
  onError(props.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker");
12518
12518
  }
12519
- doc.contents = value ? composeNode.composeNode(ctx, value, props, onError) : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
12519
+ doc.contents = value2 ? composeNode.composeNode(ctx, value2, props, onError) : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
12520
12520
  const contentEnd = doc.contents.range[2];
12521
12521
  const re = resolveEnd.resolveEnd(end, contentEnd, false, onError);
12522
12522
  if (re.comment)
@@ -12764,9 +12764,9 @@ var require_cst_scalar = __commonJS({
12764
12764
  }
12765
12765
  return null;
12766
12766
  }
12767
- function createScalarToken(value, context) {
12767
+ function createScalarToken(value2, context) {
12768
12768
  const { implicitKey = false, indent: indent2, inFlow = false, offset = -1, type = "PLAIN" } = context;
12769
- const source2 = stringifyString.stringifyString({ type, value }, {
12769
+ const source2 = stringifyString.stringifyString({ type, value: value2 }, {
12770
12770
  implicitKey,
12771
12771
  indent: indent2 > 0 ? " ".repeat(indent2) : "",
12772
12772
  inFlow,
@@ -12796,7 +12796,7 @@ var require_cst_scalar = __commonJS({
12796
12796
  return { type: "scalar", offset, indent: indent2, source: source2, end };
12797
12797
  }
12798
12798
  }
12799
- function setScalarValue(token, value, context = {}) {
12799
+ function setScalarValue(token, value2, context = {}) {
12800
12800
  let { afterKey = false, implicitKey = false, inFlow = false, type } = context;
12801
12801
  let indent2 = "indent" in token ? token.indent : null;
12802
12802
  if (afterKey && typeof indent2 === "number")
@@ -12819,7 +12819,7 @@ var require_cst_scalar = __commonJS({
12819
12819
  default:
12820
12820
  type = "PLAIN";
12821
12821
  }
12822
- const source2 = stringifyString.stringifyString({ type, value }, {
12822
+ const source2 = stringifyString.stringifyString({ type, value: value2 }, {
12823
12823
  implicitKey: implicitKey || indent2 === null,
12824
12824
  indent: indent2 !== null && indent2 > 0 ? " ".repeat(indent2) : "",
12825
12825
  inFlow,
@@ -12965,7 +12965,7 @@ var require_cst_stringify = __commonJS({
12965
12965
  }
12966
12966
  }
12967
12967
  }
12968
- function stringifyItem({ start, key, sep: sep2, value }) {
12968
+ function stringifyItem({ start, key, sep: sep2, value: value2 }) {
12969
12969
  let res = "";
12970
12970
  for (const st of start)
12971
12971
  res += st.source;
@@ -12974,8 +12974,8 @@ var require_cst_stringify = __commonJS({
12974
12974
  if (sep2)
12975
12975
  for (const st of sep2)
12976
12976
  res += st.source;
12977
- if (value)
12978
- res += stringifyToken(value);
12977
+ if (value2)
12978
+ res += stringifyToken(value2);
12979
12979
  return res;
12980
12980
  }
12981
12981
  exports2.stringify = stringify;
@@ -14708,7 +14708,7 @@ var require_public_api = __commonJS({
14708
14708
  }
14709
14709
  return doc.toJS(Object.assign({ reviver: _reviver }, options));
14710
14710
  }
14711
- function stringify(value, replacer, options) {
14711
+ function stringify(value2, replacer, options) {
14712
14712
  let _replacer = null;
14713
14713
  if (typeof replacer === "function" || Array.isArray(replacer)) {
14714
14714
  _replacer = replacer;
@@ -14721,14 +14721,14 @@ var require_public_api = __commonJS({
14721
14721
  const indent2 = Math.round(options);
14722
14722
  options = indent2 < 1 ? void 0 : indent2 > 8 ? { indent: 8 } : { indent: indent2 };
14723
14723
  }
14724
- if (value === void 0) {
14724
+ if (value2 === void 0) {
14725
14725
  const { keepUndefined } = options ?? replacer ?? {};
14726
14726
  if (!keepUndefined)
14727
14727
  return void 0;
14728
14728
  }
14729
- if (identity.isDocument(value) && !_replacer)
14730
- return value.toString(options);
14731
- return new Document.Document(value, _replacer, options).toString(options);
14729
+ if (identity.isDocument(value2) && !_replacer)
14730
+ return value2.toString(options);
14731
+ return new Document.Document(value2, _replacer, options).toString(options);
14732
14732
  }
14733
14733
  exports2.parse = parse2;
14734
14734
  exports2.parseAllDocuments = parseAllDocuments;
@@ -14896,7 +14896,7 @@ var require_lz_string = __commonJS({
14896
14896
  },
14897
14897
  _compress: function(uncompressed, bitsPerChar, getCharFromInt) {
14898
14898
  if (uncompressed == null) return "";
14899
- var i, value, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
14899
+ var i, value2, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
14900
14900
  for (ii = 0; ii < uncompressed.length; ii += 1) {
14901
14901
  context_c = uncompressed.charAt(ii);
14902
14902
  if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
@@ -14919,9 +14919,9 @@ var require_lz_string = __commonJS({
14919
14919
  context_data_position++;
14920
14920
  }
14921
14921
  }
14922
- value = context_w.charCodeAt(0);
14922
+ value2 = context_w.charCodeAt(0);
14923
14923
  for (i = 0; i < 8; i++) {
14924
- context_data_val = context_data_val << 1 | value & 1;
14924
+ context_data_val = context_data_val << 1 | value2 & 1;
14925
14925
  if (context_data_position == bitsPerChar - 1) {
14926
14926
  context_data_position = 0;
14927
14927
  context_data.push(getCharFromInt(context_data_val));
@@ -14929,12 +14929,12 @@ var require_lz_string = __commonJS({
14929
14929
  } else {
14930
14930
  context_data_position++;
14931
14931
  }
14932
- value = value >> 1;
14932
+ value2 = value2 >> 1;
14933
14933
  }
14934
14934
  } else {
14935
- value = 1;
14935
+ value2 = 1;
14936
14936
  for (i = 0; i < context_numBits; i++) {
14937
- context_data_val = context_data_val << 1 | value;
14937
+ context_data_val = context_data_val << 1 | value2;
14938
14938
  if (context_data_position == bitsPerChar - 1) {
14939
14939
  context_data_position = 0;
14940
14940
  context_data.push(getCharFromInt(context_data_val));
@@ -14942,11 +14942,11 @@ var require_lz_string = __commonJS({
14942
14942
  } else {
14943
14943
  context_data_position++;
14944
14944
  }
14945
- value = 0;
14945
+ value2 = 0;
14946
14946
  }
14947
- value = context_w.charCodeAt(0);
14947
+ value2 = context_w.charCodeAt(0);
14948
14948
  for (i = 0; i < 16; i++) {
14949
- context_data_val = context_data_val << 1 | value & 1;
14949
+ context_data_val = context_data_val << 1 | value2 & 1;
14950
14950
  if (context_data_position == bitsPerChar - 1) {
14951
14951
  context_data_position = 0;
14952
14952
  context_data.push(getCharFromInt(context_data_val));
@@ -14954,7 +14954,7 @@ var require_lz_string = __commonJS({
14954
14954
  } else {
14955
14955
  context_data_position++;
14956
14956
  }
14957
- value = value >> 1;
14957
+ value2 = value2 >> 1;
14958
14958
  }
14959
14959
  }
14960
14960
  context_enlargeIn--;
@@ -14964,9 +14964,9 @@ var require_lz_string = __commonJS({
14964
14964
  }
14965
14965
  delete context_dictionaryToCreate[context_w];
14966
14966
  } else {
14967
- value = context_dictionary[context_w];
14967
+ value2 = context_dictionary[context_w];
14968
14968
  for (i = 0; i < context_numBits; i++) {
14969
- context_data_val = context_data_val << 1 | value & 1;
14969
+ context_data_val = context_data_val << 1 | value2 & 1;
14970
14970
  if (context_data_position == bitsPerChar - 1) {
14971
14971
  context_data_position = 0;
14972
14972
  context_data.push(getCharFromInt(context_data_val));
@@ -14974,7 +14974,7 @@ var require_lz_string = __commonJS({
14974
14974
  } else {
14975
14975
  context_data_position++;
14976
14976
  }
14977
- value = value >> 1;
14977
+ value2 = value2 >> 1;
14978
14978
  }
14979
14979
  }
14980
14980
  context_enlargeIn--;
@@ -14999,9 +14999,9 @@ var require_lz_string = __commonJS({
14999
14999
  context_data_position++;
15000
15000
  }
15001
15001
  }
15002
- value = context_w.charCodeAt(0);
15002
+ value2 = context_w.charCodeAt(0);
15003
15003
  for (i = 0; i < 8; i++) {
15004
- context_data_val = context_data_val << 1 | value & 1;
15004
+ context_data_val = context_data_val << 1 | value2 & 1;
15005
15005
  if (context_data_position == bitsPerChar - 1) {
15006
15006
  context_data_position = 0;
15007
15007
  context_data.push(getCharFromInt(context_data_val));
@@ -15009,12 +15009,12 @@ var require_lz_string = __commonJS({
15009
15009
  } else {
15010
15010
  context_data_position++;
15011
15011
  }
15012
- value = value >> 1;
15012
+ value2 = value2 >> 1;
15013
15013
  }
15014
15014
  } else {
15015
- value = 1;
15015
+ value2 = 1;
15016
15016
  for (i = 0; i < context_numBits; i++) {
15017
- context_data_val = context_data_val << 1 | value;
15017
+ context_data_val = context_data_val << 1 | value2;
15018
15018
  if (context_data_position == bitsPerChar - 1) {
15019
15019
  context_data_position = 0;
15020
15020
  context_data.push(getCharFromInt(context_data_val));
@@ -15022,11 +15022,11 @@ var require_lz_string = __commonJS({
15022
15022
  } else {
15023
15023
  context_data_position++;
15024
15024
  }
15025
- value = 0;
15025
+ value2 = 0;
15026
15026
  }
15027
- value = context_w.charCodeAt(0);
15027
+ value2 = context_w.charCodeAt(0);
15028
15028
  for (i = 0; i < 16; i++) {
15029
- context_data_val = context_data_val << 1 | value & 1;
15029
+ context_data_val = context_data_val << 1 | value2 & 1;
15030
15030
  if (context_data_position == bitsPerChar - 1) {
15031
15031
  context_data_position = 0;
15032
15032
  context_data.push(getCharFromInt(context_data_val));
@@ -15034,7 +15034,7 @@ var require_lz_string = __commonJS({
15034
15034
  } else {
15035
15035
  context_data_position++;
15036
15036
  }
15037
- value = value >> 1;
15037
+ value2 = value2 >> 1;
15038
15038
  }
15039
15039
  }
15040
15040
  context_enlargeIn--;
@@ -15044,9 +15044,9 @@ var require_lz_string = __commonJS({
15044
15044
  }
15045
15045
  delete context_dictionaryToCreate[context_w];
15046
15046
  } else {
15047
- value = context_dictionary[context_w];
15047
+ value2 = context_dictionary[context_w];
15048
15048
  for (i = 0; i < context_numBits; i++) {
15049
- context_data_val = context_data_val << 1 | value & 1;
15049
+ context_data_val = context_data_val << 1 | value2 & 1;
15050
15050
  if (context_data_position == bitsPerChar - 1) {
15051
15051
  context_data_position = 0;
15052
15052
  context_data.push(getCharFromInt(context_data_val));
@@ -15054,7 +15054,7 @@ var require_lz_string = __commonJS({
15054
15054
  } else {
15055
15055
  context_data_position++;
15056
15056
  }
15057
- value = value >> 1;
15057
+ value2 = value2 >> 1;
15058
15058
  }
15059
15059
  }
15060
15060
  context_enlargeIn--;
@@ -15063,9 +15063,9 @@ var require_lz_string = __commonJS({
15063
15063
  context_numBits++;
15064
15064
  }
15065
15065
  }
15066
- value = 2;
15066
+ value2 = 2;
15067
15067
  for (i = 0; i < context_numBits; i++) {
15068
- context_data_val = context_data_val << 1 | value & 1;
15068
+ context_data_val = context_data_val << 1 | value2 & 1;
15069
15069
  if (context_data_position == bitsPerChar - 1) {
15070
15070
  context_data_position = 0;
15071
15071
  context_data.push(getCharFromInt(context_data_val));
@@ -15073,7 +15073,7 @@ var require_lz_string = __commonJS({
15073
15073
  } else {
15074
15074
  context_data_position++;
15075
15075
  }
15076
- value = value >> 1;
15076
+ value2 = value2 >> 1;
15077
15077
  }
15078
15078
  while (true) {
15079
15079
  context_data_val = context_data_val << 1;
@@ -15253,8 +15253,8 @@ __export(cli_exports, {
15253
15253
  run: () => run
15254
15254
  });
15255
15255
  module.exports = __toCommonJS(cli_exports);
15256
- var import_node_fs14 = require("node:fs");
15257
- var import_node_path13 = require("node:path");
15256
+ var import_node_fs15 = require("node:fs");
15257
+ var import_node_path14 = require("node:path");
15258
15258
 
15259
15259
  // src/openapi/config.ts
15260
15260
  var import_node_fs2 = require("node:fs");
@@ -15668,9 +15668,9 @@ function tokenizeLine(text, line) {
15668
15668
  break;
15669
15669
  }
15670
15670
  if (ch === '"') {
15671
- const { value, end, closed } = readString(text, i);
15671
+ const { value: value2, end, closed } = readString(text, i);
15672
15672
  if (!closed) error("Unterminated string", start + 1, text.length - start);
15673
- tokens.push({ kind: "string", value, col: start + 1, length: end - start });
15673
+ tokens.push({ kind: "string", value: value2, col: start + 1, length: end - start });
15674
15674
  i = end;
15675
15675
  continue;
15676
15676
  }
@@ -15689,9 +15689,9 @@ function tokenizeLine(text, line) {
15689
15689
  const arrow = ["->>", "-->", "->"].find((a) => text.startsWith(a, i));
15690
15690
  const failed = text.startsWith("-x", i) && !IDENT_PART.test(text[i + 2] ?? "");
15691
15691
  if (arrow || failed) {
15692
- const value = arrow ?? "-x";
15693
- tokens.push({ kind: "arrow", value, col: start + 1, length: value.length });
15694
- i += value.length;
15692
+ const value2 = arrow ?? "-x";
15693
+ tokens.push({ kind: "arrow", value: value2, col: start + 1, length: value2.length });
15694
+ i += value2.length;
15695
15695
  continue;
15696
15696
  }
15697
15697
  if (DIGIT.test(text[i + 1] ?? "")) {
@@ -15703,15 +15703,15 @@ function tokenizeLine(text, line) {
15703
15703
  }
15704
15704
  if (DIGIT.test(ch)) {
15705
15705
  i = readQuantity(text, i);
15706
- const value = text.slice(start, i).replace(/[ \t]+/g, "");
15707
- const kind = /^\d+$/.test(value) ? "number" : "quantity";
15708
- tokens.push({ kind, value, col: start + 1, length: i - start });
15706
+ const value2 = text.slice(start, i).replace(/[ \t]+/g, "");
15707
+ const kind = /^\d+$/.test(value2) ? "number" : "quantity";
15708
+ tokens.push({ kind, value: value2, col: start + 1, length: i - start });
15709
15709
  continue;
15710
15710
  }
15711
15711
  if (ch === "<" || ch === ">") {
15712
- const value = text[i + 1] === "=" ? ch + "=" : ch;
15713
- tokens.push({ kind: "op", value, col: start + 1, length: value.length });
15714
- i += value.length;
15712
+ const value2 = text[i + 1] === "=" ? ch + "=" : ch;
15713
+ tokens.push({ kind: "op", value: value2, col: start + 1, length: value2.length });
15714
+ i += value2.length;
15715
15715
  continue;
15716
15716
  }
15717
15717
  if (ch === "@") {
@@ -15764,20 +15764,20 @@ function readQuantity(text, start) {
15764
15764
  return i;
15765
15765
  }
15766
15766
  function readString(text, start) {
15767
- let value = "";
15767
+ let value2 = "";
15768
15768
  let i = start + 1;
15769
15769
  while (i < text.length) {
15770
15770
  const ch = text[i];
15771
15771
  if (ch === "\\" && i + 1 < text.length) {
15772
- value += text[i + 1];
15772
+ value2 += text[i + 1];
15773
15773
  i += 2;
15774
15774
  continue;
15775
15775
  }
15776
- if (ch === '"') return { value, end: i + 1, closed: true };
15777
- value += ch;
15776
+ if (ch === '"') return { value: value2, end: i + 1, closed: true };
15777
+ value2 += ch;
15778
15778
  i++;
15779
15779
  }
15780
- return { value, end: text.length, closed: false };
15780
+ return { value: value2, end: text.length, closed: false };
15781
15781
  }
15782
15782
  function stripTrailingComment(text) {
15783
15783
  let depth = 0;
@@ -15823,6 +15823,19 @@ var BracketCounter = class {
15823
15823
  return this.depth;
15824
15824
  }
15825
15825
  };
15826
+ function qualify(tokens) {
15827
+ let out;
15828
+ for (let i = 0; i < tokens.length; i++) {
15829
+ const [t, next] = [tokens[i], tokens[i + 1]];
15830
+ const joined = t.kind === "ident" && next?.kind === "tag" && next.col === t.col + t.length;
15831
+ if (joined && (tokens[i + 2]?.kind === "arrow" || tokens[i - 1]?.kind === "arrow")) {
15832
+ out ??= tokens.slice(0, i);
15833
+ out.push({ ...t, value: `${t.value}.${next.value}`, length: t.length + next.length });
15834
+ i++;
15835
+ } else out?.push(t);
15836
+ }
15837
+ return out ?? tokens;
15838
+ }
15826
15839
 
15827
15840
  // ../frontend/src/dsl/format.ts
15828
15841
  function format(source2) {
@@ -15859,7 +15872,8 @@ function classify(lines) {
15859
15872
  entries2.push({ kind: "blank", depth, text: "" });
15860
15873
  continue;
15861
15874
  }
15862
- const { tokens, diagnostics } = tokenizeLine(raw, i + 1);
15875
+ const { tokens: lexed, diagnostics } = tokenizeLine(raw, i + 1);
15876
+ const tokens = qualify(lexed);
15863
15877
  if (diagnostics.some((d) => d.severity === "error") || tokens.length === 0) {
15864
15878
  entries2.push({ kind: "line", depth, text: original });
15865
15879
  continue;
@@ -16014,7 +16028,8 @@ function join(raw, tokens) {
16014
16028
  return out;
16015
16029
  }
16016
16030
  function sameTokens(text, tokens) {
16017
- const { tokens: again, diagnostics } = tokenizeLine(text, 1);
16031
+ const { tokens: lexed, diagnostics } = tokenizeLine(text, 1);
16032
+ const again = qualify(lexed);
16018
16033
  return diagnostics.length === 0 && again.length === tokens.length && again.every((t, i) => t.kind === tokens[i].kind && t.value === tokens[i].value);
16019
16034
  }
16020
16035
  function reindent(line, delta) {
@@ -16538,14 +16553,14 @@ var Parser = class _Parser {
16538
16553
  return index;
16539
16554
  }
16540
16555
  parseTitle(tokens, line) {
16541
- const value = tokens[1];
16542
- if (!value || value.kind !== "string" && value.kind !== "ident") {
16556
+ const value2 = tokens[1];
16557
+ if (!value2 || value2.kind !== "string" && value2.kind !== "ident") {
16543
16558
  this.error('Expected a title, e.g. title "My System"', this.locOf(tokens[0], line));
16544
16559
  return;
16545
16560
  }
16546
16561
  const summary = tokens[2]?.kind === "string" ? tokens[2] : void 0;
16547
16562
  if (this.file === this.rootFile) {
16548
- this.title = value.value;
16563
+ this.title = value2.value;
16549
16564
  if (summary) this.summary = summary.value;
16550
16565
  }
16551
16566
  this.expectEnd(tokens, summary ? 3 : 2, line);
@@ -16557,13 +16572,13 @@ var Parser = class _Parser {
16557
16572
  }
16558
16573
  /** `direction down|right|up|left`: at the top level for the whole diagram, inside a group for its members. */
16559
16574
  parseDirection(tokens, line) {
16560
- const [keyword, value] = tokens;
16561
- const loc = this.locOf(value, line);
16562
- if (!DIRECTIONS.includes(value.value)) {
16563
- this.error(`Unknown direction '${value.value}'; use direction down, right, up or left`, loc);
16575
+ const [keyword, value2] = tokens;
16576
+ const loc = this.locOf(value2, line);
16577
+ if (!DIRECTIONS.includes(value2.value)) {
16578
+ this.error(`Unknown direction '${value2.value}'; use direction down, right, up or left`, loc);
16564
16579
  return;
16565
16580
  }
16566
- const direction = value.value;
16581
+ const direction = value2.value;
16567
16582
  const top = this.top();
16568
16583
  if (top?.kind === "group") {
16569
16584
  const group = this.nodes.get(top.id);
@@ -16586,10 +16601,10 @@ var Parser = class _Parser {
16586
16601
  }
16587
16602
  /** `layout ordered`: lay edges out by declaration order. */
16588
16603
  parseLayoutMode(tokens, line) {
16589
- const [keyword, value] = tokens;
16590
- const loc = this.locOf(value, line);
16591
- if (value.value !== "ordered") {
16592
- this.error(`Unknown layout mode '${value.value}'; the only one is layout ordered`, loc);
16604
+ const [keyword, value2] = tokens;
16605
+ const loc = this.locOf(value2, line);
16606
+ if (value2.value !== "ordered") {
16607
+ this.error(`Unknown layout mode '${value2.value}'; the only one is layout ordered`, loc);
16593
16608
  return;
16594
16609
  }
16595
16610
  if (this.top()) {
@@ -16612,22 +16627,22 @@ var Parser = class _Parser {
16612
16627
  readRank(tokens, i, line, current) {
16613
16628
  const t = tokens[i];
16614
16629
  if (!isWord(t, "rank")) return 0;
16615
- const value = tokens[i + 1];
16630
+ const value2 = tokens[i + 1];
16616
16631
  const help = "a layer number from 0 (rank 0, rank 1, \u2026), rank first or rank last";
16617
16632
  if (current.rank !== void 0) {
16618
16633
  this.error(`A node takes one rank; rank ${current.rank} is already set`, this.locOf(t, line));
16619
16634
  return void 0;
16620
16635
  }
16621
- if (value?.kind === "number" && /^\d+$/.test(value.value)) {
16622
- current.rank = Number(value.value);
16636
+ if (value2?.kind === "number" && /^\d+$/.test(value2.value)) {
16637
+ current.rank = Number(value2.value);
16623
16638
  return 2;
16624
16639
  }
16625
- if (value?.kind === "ident" && (value.value === "first" || value.value === "last")) {
16626
- current.rank = value.value;
16640
+ if (value2?.kind === "ident" && (value2.value === "first" || value2.value === "last")) {
16641
+ current.rank = value2.value;
16627
16642
  return 2;
16628
16643
  }
16629
- const numeric = value?.kind === "number" || value?.kind === "quantity";
16630
- this.error(numeric ? `'${value.value}' is not a layer number; use ${help}` : `Expected ${help} after rank`, this.locOf(value ?? t, line));
16644
+ const numeric = value2?.kind === "number" || value2?.kind === "quantity";
16645
+ this.error(numeric ? `'${value2.value}' is not a layer number; use ${help}` : `Expected ${help} after rank`, this.locOf(value2 ?? t, line));
16631
16646
  return void 0;
16632
16647
  }
16633
16648
  parseImport(tokens, line) {
@@ -16886,11 +16901,11 @@ var Parser = class _Parser {
16886
16901
  stub.rps = rps;
16887
16902
  i++;
16888
16903
  } else if (isWord(t, "p99") || isWord(t, "latency") || isWord(t, "availability")) {
16889
- const value = this.quantityOf(i + 1 < to ? tokens[i + 1] : void 0, t.value === "availability" ? "%" : "ms", t, line);
16890
- if (value === void 0) return;
16891
- if (t.value === "p99") stub.p99Ms = value;
16892
- else if (t.value === "latency") stub.latencyMs = value;
16893
- else stub.availability = value;
16904
+ const value2 = this.quantityOf(i + 1 < to ? tokens[i + 1] : void 0, t.value === "availability" ? "%" : "ms", t, line);
16905
+ if (value2 === void 0) return;
16906
+ if (t.value === "p99") stub.p99Ms = value2;
16907
+ else if (t.value === "latency") stub.latencyMs = value2;
16908
+ else stub.availability = value2;
16894
16909
  i += 2;
16895
16910
  } else {
16896
16911
  this.error(`Expected ${STUB_HELP}`, this.locOf(t, line));
@@ -17272,10 +17287,10 @@ var Parser = class _Parser {
17272
17287
  else if (n < 1) this.error("A fan-out needs at least one call per request: x1, x2, \u2026", at(match[0].length));
17273
17288
  else out.multiplier = n;
17274
17289
  } else {
17275
- const bytes = parseSize(size[1]);
17290
+ const bytes2 = parseSize(size[1]);
17276
17291
  if (out.sizeBytes !== void 0) this.error("The payload size is given twice; write one ~<size>", at(match[0].length));
17277
- else if ("error" in bytes) this.error(bytes.error, at(match[0].length));
17278
- else out.sizeBytes = bytes.value;
17292
+ else if ("error" in bytes2) this.error(bytes2.error, at(match[0].length));
17293
+ else out.sizeBytes = bytes2.value;
17279
17294
  }
17280
17295
  offset += match[0].length;
17281
17296
  offset += label.slice(offset).length - label.slice(offset).trimStart().length;
@@ -17345,9 +17360,9 @@ var Parser = class _Parser {
17345
17360
  return 1;
17346
17361
  }
17347
17362
  if (isWord(t, "color")) {
17348
- const value = this.readColor(tokens[i + 1], t, line);
17349
- if (value === void 0) return void 0;
17350
- parts.color = value;
17363
+ const value2 = this.readColor(tokens[i + 1], t, line);
17364
+ if (value2 === void 0) return void 0;
17365
+ parts.color = value2;
17351
17366
  return 2;
17352
17367
  }
17353
17368
  if (isNode && isWord(t, "critical")) {
@@ -17619,12 +17634,12 @@ var Parser = class _Parser {
17619
17634
  } else if (isWord(t, "latency") || isWord(t, "availability") || isWord(t, "cost") || isWord(t, "timeout")) {
17620
17635
  part = t.value;
17621
17636
  const unit = part === "latency" || part === "timeout" ? "ms" : part === "availability" ? "%" : "usd/month";
17622
- const value = this.quantityOf(tokens[i + 1], unit, t, line);
17623
- if (value === void 0) return;
17624
- if (part === "latency") override.latencyMs = value;
17625
- else if (part === "timeout") override.timeoutMs = value;
17626
- else if (part === "availability") override.availability = value;
17627
- else override.costUsd = value;
17637
+ const value2 = this.quantityOf(tokens[i + 1], unit, t, line);
17638
+ if (value2 === void 0) return;
17639
+ if (part === "latency") override.latencyMs = value2;
17640
+ else if (part === "timeout") override.timeoutMs = value2;
17641
+ else if (part === "availability") override.availability = value2;
17642
+ else override.costUsd = value2;
17628
17643
  i += 2;
17629
17644
  } else if (isWord(t, "durable") || isWord(t, "volatile")) {
17630
17645
  part = "durable or volatile";
@@ -17632,10 +17647,10 @@ var Parser = class _Parser {
17632
17647
  i++;
17633
17648
  } else if (isWord(t, "reads") || isWord(t, "writes")) {
17634
17649
  part = t.value;
17635
- const value = this.quantityOf(tokens[i + 1], "rps", t, line);
17636
- if (value === void 0) return;
17637
- if (part === "reads") override.readRps = value;
17638
- else override.writeRps = value;
17650
+ const value2 = this.quantityOf(tokens[i + 1], "rps", t, line);
17651
+ if (value2 === void 0) return;
17652
+ if (part === "reads") override.readRps = value2;
17653
+ else override.writeRps = value2;
17639
17654
  i += 2;
17640
17655
  } else if (isWord(t, "shards")) {
17641
17656
  part = "shards";
@@ -17648,33 +17663,33 @@ var Parser = class _Parser {
17648
17663
  i += 2;
17649
17664
  } else if (isWord(t, "size")) {
17650
17665
  part = "size";
17651
- const value = tokens[i + 1];
17652
- if (!isWord(value, "S") && !isWord(value, "M") && !isWord(value, "L")) {
17653
- this.error(`Expected S, M or L after size${value ? `, not ${describe(value)}` : ""}`, this.locOf(value ?? t, line));
17666
+ const value2 = tokens[i + 1];
17667
+ if (!isWord(value2, "S") && !isWord(value2, "M") && !isWord(value2, "L")) {
17668
+ this.error(`Expected S, M or L after size${value2 ? `, not ${describe(value2)}` : ""}`, this.locOf(value2 ?? t, line));
17654
17669
  return;
17655
17670
  }
17656
- override.size = value.value;
17671
+ override.size = value2.value;
17657
17672
  i += 2;
17658
17673
  } else if (isWord(t, "consistency")) {
17659
17674
  part = "consistency";
17660
- const value = tokens[i + 1];
17661
- if (!isWord(value, "strong") && !isWord(value, "eventual")) {
17662
- this.error(`Expected strong or eventual after consistency${value ? `, not ${describe(value)}` : ""}`, this.locOf(value ?? t, line));
17675
+ const value2 = tokens[i + 1];
17676
+ if (!isWord(value2, "strong") && !isWord(value2, "eventual")) {
17677
+ this.error(`Expected strong or eventual after consistency${value2 ? `, not ${describe(value2)}` : ""}`, this.locOf(value2 ?? t, line));
17663
17678
  return;
17664
17679
  }
17665
- override.consistency = value.value;
17680
+ override.consistency = value2.value;
17666
17681
  i += 2;
17667
17682
  } else if (isWord(t, "bandwidth") || isWord(t, "egress")) {
17668
17683
  part = t.value;
17669
- const value = this.quantityOf(tokens[i + 1], part === "bandwidth" ? "MBps" : "usd/GB", t, line);
17670
- if (value === void 0) return;
17684
+ const value2 = this.quantityOf(tokens[i + 1], part === "bandwidth" ? "MBps" : "usd/GB", t, line);
17685
+ if (value2 === void 0) return;
17671
17686
  if (part === "bandwidth") {
17672
- if (value <= 0) {
17687
+ if (value2 <= 0) {
17673
17688
  this.error("Bandwidth must be more than 0", this.locOf(tokens[i + 1], line));
17674
17689
  return;
17675
17690
  }
17676
- override.bandwidthMBps = value;
17677
- } else override.egressUsdPerGb = value;
17691
+ override.bandwidthMBps = value2;
17692
+ } else override.egressUsdPerGb = value2;
17678
17693
  i += 2;
17679
17694
  } else {
17680
17695
  this.error(`Unexpected ${describe(t)}; expected ${CAPACITY_PARTS}`, this.locOf(t, line));
@@ -18123,8 +18138,8 @@ var Parser = class _Parser {
18123
18138
  let id = base;
18124
18139
  for (let n = 2; taken.has(id); n++) id = `${base}-${n}`;
18125
18140
  taken.add(id);
18126
- const steps3 = this.buildSteps(useCase.id, id, path.steps);
18127
- const entry2 = steps3[0];
18141
+ const steps4 = this.buildSteps(useCase.id, id, path.steps);
18142
+ const entry2 = steps4[0];
18128
18143
  const failedEntry = !!entry2 && (entry2.failed || (entry2.statusCode ?? 0) >= 400);
18129
18144
  const condition = path.conditions.join(" \xB7 ");
18130
18145
  return {
@@ -18132,22 +18147,22 @@ var Parser = class _Parser {
18132
18147
  name: path.names.length ? path.names.join(" \u203A ") : useCase.name,
18133
18148
  outcome: failedEntry ? "error" : "success",
18134
18149
  ...condition ? { condition } : {},
18135
- steps: steps3,
18150
+ steps: steps4,
18136
18151
  loc: path.locs.at(-1) ?? useCase.loc
18137
18152
  };
18138
18153
  });
18139
- const steps2 = scenarios[0]?.steps ?? [];
18140
- const entry = steps2[0];
18154
+ const steps3 = scenarios[0]?.steps ?? [];
18155
+ const entry = steps3[0];
18141
18156
  return {
18142
18157
  ...useCase,
18143
18158
  entryServiceId: entry?.fromServiceId,
18144
18159
  endpoint: entry?.httpMethod ? `${entry.httpMethod} ${entry.endpoint}` : void 0,
18145
- steps: steps2,
18160
+ steps: steps3,
18146
18161
  scenarios
18147
18162
  };
18148
18163
  }
18149
18164
  buildSteps(useCaseId, scenarioId, raw) {
18150
- const steps2 = [];
18165
+ const steps3 = [];
18151
18166
  const answered = /* @__PURE__ */ new Set();
18152
18167
  const prefix = scenarioId === "main" ? useCaseId : `${useCaseId}-${scenarioId}`;
18153
18168
  for (const step of raw) {
@@ -18155,7 +18170,7 @@ var Parser = class _Parser {
18155
18170
  if (step.arrow === "-->") {
18156
18171
  const [respFrom] = this.splitRef(step.from);
18157
18172
  const [respTo] = this.splitRef(step.to);
18158
- const request2 = [...steps2].reverse().find((s) => s.fromServiceId === respTo && s.toServiceId === respFrom && !answered.has(s) && !s.failed);
18173
+ const request2 = [...steps3].reverse().find((s) => s.fromServiceId === respTo && s.toServiceId === respFrom && !answered.has(s) && !s.failed);
18159
18174
  if (!request2) {
18160
18175
  this.warning(`Response has no matching request from '${step.to}' to '${step.from}'`, step.loc);
18161
18176
  continue;
@@ -18179,9 +18194,9 @@ var Parser = class _Parser {
18179
18194
  const port = toPort ?? this.onlyEntry(to, step.loc);
18180
18195
  const target = this.nodes.get(to);
18181
18196
  const isAsync = step.arrow === "->>";
18182
- steps2.push({
18183
- id: `${prefix}-${steps2.length + 1}`,
18184
- stepOrder: steps2.length,
18197
+ steps3.push({
18198
+ id: `${prefix}-${steps3.length + 1}`,
18199
+ stepOrder: steps3.length,
18185
18200
  stepName: label.name || `${step.from} \u2192 ${step.to}`,
18186
18201
  fromServiceId: from,
18187
18202
  toServiceId: to,
@@ -18205,7 +18220,7 @@ var Parser = class _Parser {
18205
18220
  ...fromPort !== void 0 ? { fromPort } : {}
18206
18221
  });
18207
18222
  }
18208
- return steps2;
18223
+ return steps3;
18209
18224
  }
18210
18225
  /**
18211
18226
  * Warns when a step talks between two nodes the architecture never connects.
@@ -18357,19 +18372,6 @@ function expand(items) {
18357
18372
  }
18358
18373
  return paths;
18359
18374
  }
18360
- function qualify(tokens) {
18361
- let out;
18362
- for (let i = 0; i < tokens.length; i++) {
18363
- const [t, next] = [tokens[i], tokens[i + 1]];
18364
- const joined = t.kind === "ident" && next?.kind === "tag" && next.col === t.col + t.length;
18365
- if (joined && (tokens[i + 2]?.kind === "arrow" || tokens[i - 1]?.kind === "arrow")) {
18366
- out ??= tokens.slice(0, i);
18367
- out.push({ ...t, value: `${t.value}.${next.value}`, length: t.length + next.length });
18368
- i++;
18369
- } else out?.push(t);
18370
- }
18371
- return out ?? tokens;
18372
- }
18373
18375
  function findUseCaseIn(diagram, name) {
18374
18376
  const lower = name.toLowerCase();
18375
18377
  return diagram.useCases.find((u) => u.name === name) ?? diagram.useCases.find((u) => u.name.toLowerCase() === lower) ?? diagram.useCases.find((u) => u.id === name);
@@ -18395,8 +18397,8 @@ function splitPayload(input) {
18395
18397
  const formats = { json: "JSON", xml: "XML", text: "FREE_TEXT" };
18396
18398
  const leading = text.match(/^(json|xml|text)\s+([\s\S]+)$/i);
18397
18399
  if (leading) return { text: "", format: formats[leading[1].toLowerCase()], body: leading[2].trim() };
18398
- const keyed = text.match(/^([\s\S]*?)\s+(json|xml)\s+([{[<][\s\S]*)$/i);
18399
- if (keyed) return { text: keyed[1].trim(), format: formats[keyed[2].toLowerCase()], body: keyed[3].trim() };
18400
+ const keyed2 = text.match(/^([\s\S]*?)\s+(json|xml)\s+([{[<][\s\S]*)$/i);
18401
+ if (keyed2) return { text: keyed2[1].trim(), format: formats[keyed2[2].toLowerCase()], body: keyed2[3].trim() };
18400
18402
  const bare = text.search(/(^|\s)[{[<]/);
18401
18403
  if (bare !== -1) {
18402
18404
  const body = text.slice(bare).trim();
@@ -18426,9 +18428,9 @@ function parseSize(text) {
18426
18428
  if (!m) return { error: `Expected a payload size after ~, e.g. ~2MB, ~500KB or ~1.5GB${text ? `, not '~${text}'` : ""}` };
18427
18429
  const factor = SIZE_UNITS[m[2]];
18428
18430
  if (factor === void 0) return { error: m[2] ? `Unknown size unit '${m[2]}' in '~${text}'; use B, KB, MB, GB or TB` : `'~${text}' needs a unit: B, KB, MB, GB or TB` };
18429
- const value = Math.round(Number(m[1]) * factor);
18430
- if (value <= 0) return { error: `A payload size must be more than 0, not '~${text}'` };
18431
- return { value };
18431
+ const value2 = Math.round(Number(m[1]) * factor);
18432
+ if (value2 <= 0) return { error: `A payload size must be more than 0, not '~${text}'` };
18433
+ return { value: value2 };
18432
18434
  }
18433
18435
  function inferProtocol(isAsync, method, target) {
18434
18436
  if (isAsync || target?.type === "queue" || target?.type === "broker") return "MESSAGING";
@@ -18550,8 +18552,8 @@ function nodeLine(node) {
18550
18552
  if (node.description) parts.push(quote(node.description));
18551
18553
  return parts.join(" ");
18552
18554
  }
18553
- function stepLines(steps2, indent2, out) {
18554
- for (const step of steps2) {
18555
+ function stepLines(steps3, indent2, out) {
18556
+ for (const step of steps3) {
18555
18557
  if (step.kind === "step") {
18556
18558
  out.push(`${indent2}${step.from} ${step.arrow} ${step.to}${step.label ? ` : ${step.label}` : ""}`);
18557
18559
  } else if (step.kind === "par") {
@@ -18787,8 +18789,8 @@ var OpenApiSpec = class {
18787
18789
  const item = this.resolve(`/paths/${esc(path)}`);
18788
18790
  if (!item || !isObject2(item.value)) return void 0;
18789
18791
  const m = method.toLowerCase();
18790
- const value = item.value[m];
18791
- return isObject2(value) ? { path, method: method.toUpperCase(), pointer: `${item.pointer}/${m}`, value } : void 0;
18792
+ const value2 = item.value[m];
18793
+ return isObject2(value2) ? { path, method: method.toUpperCase(), pointer: `${item.pointer}/${m}`, value: value2 } : void 0;
18792
18794
  }
18793
18795
  /** Documented response keys of an operation: `201`, `4XX`, `default`. */
18794
18796
  statuses(op) {
@@ -18830,23 +18832,23 @@ var OpenApiSpec = class {
18830
18832
  }
18831
18833
  /** Follows local `$ref`s from the value at a JSON pointer; returns the final pointer and value. */
18832
18834
  resolve(pointer) {
18833
- let value = this.at(pointer);
18834
- for (let hops = 0; isObject2(value) && typeof value.$ref === "string" && hops < 20; hops++) {
18835
- if (!value.$ref.startsWith("#")) return void 0;
18836
- pointer = decodeURIComponent(value.$ref.slice(1));
18837
- value = this.at(pointer);
18835
+ let value2 = this.at(pointer);
18836
+ for (let hops = 0; isObject2(value2) && typeof value2.$ref === "string" && hops < 20; hops++) {
18837
+ if (!value2.$ref.startsWith("#")) return void 0;
18838
+ pointer = decodeURIComponent(value2.$ref.slice(1));
18839
+ value2 = this.at(pointer);
18838
18840
  }
18839
- return value === void 0 ? void 0 : { pointer, value };
18841
+ return value2 === void 0 ? void 0 : { pointer, value: value2 };
18840
18842
  }
18841
18843
  at(pointer) {
18842
- let value = this.doc;
18844
+ let value2 = this.doc;
18843
18845
  for (const raw of pointer.split("/").slice(1)) {
18844
18846
  const key = raw.replace(/~1/g, "/").replace(/~0/g, "~");
18845
- if (Array.isArray(value)) value = value[Number(key)];
18846
- else if (isObject2(value)) value = value[key];
18847
+ if (Array.isArray(value2)) value2 = value2[Number(key)];
18848
+ else if (isObject2(value2)) value2 = value2[key];
18847
18849
  else return void 0;
18848
18850
  }
18849
- return value;
18851
+ return value2;
18850
18852
  }
18851
18853
  };
18852
18854
  function describeError(e) {
@@ -18857,11 +18859,11 @@ function describeError(e) {
18857
18859
  if (e.keyword === "enum" && Array.isArray(p.allowedValues)) message += `: ${p.allowedValues.map((v) => JSON.stringify(v)).join(", ")}`;
18858
18860
  return `${where} ${message}`;
18859
18861
  }
18860
- function from30(value) {
18861
- if (Array.isArray(value)) return value.map(from30);
18862
- if (!isObject2(value)) return value;
18862
+ function from30(value2) {
18863
+ if (Array.isArray(value2)) return value2.map(from30);
18864
+ if (!isObject2(value2)) return value2;
18863
18865
  const out = {};
18864
- for (const [k, v] of Object.entries(value)) out[k] = from30(v);
18866
+ for (const [k, v] of Object.entries(value2)) out[k] = from30(v);
18865
18867
  for (const [bool, bound] of [
18866
18868
  ["exclusiveMinimum", "minimum"],
18867
18869
  ["exclusiveMaximum", "maximum"]
@@ -19019,10 +19021,10 @@ function readConfig(file) {
19019
19021
  configs.set(file, { mtimeMs, config });
19020
19022
  return config;
19021
19023
  }
19022
- function parseSpecFlag(value) {
19023
- const eq = value.indexOf("=");
19024
- if (eq <= 0 || eq === value.length - 1) return void 0;
19025
- return [value.slice(0, eq), (0, import_node_path3.resolve)(value.slice(eq + 1))];
19024
+ function parseSpecFlag(value2) {
19025
+ const eq = value2.indexOf("=");
19026
+ if (eq <= 0 || eq === value2.length - 1) return void 0;
19027
+ return [value2.slice(0, eq), (0, import_node_path3.resolve)(value2.slice(eq + 1))];
19026
19028
  }
19027
19029
  function openApiDiagnostics(file, diagram, overrides = {}) {
19028
19030
  let specs = {};
@@ -19058,6 +19060,152 @@ var RENDER_HELP = `render Writes the diagram as static files into --out (defaul
19058
19060
  var import_node_fs3 = require("node:fs");
19059
19061
  var import_node_path4 = require("node:path");
19060
19062
 
19063
+ // ../frontend/src/dsl/diff.ts
19064
+ var byKey2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
19065
+ function canonical(value2) {
19066
+ return JSON.stringify(value2, (key, v) => {
19067
+ if (key === "loc" || key === "responseLoc") return void 0;
19068
+ if (v && typeof v === "object" && !Array.isArray(v)) return Object.fromEntries(Object.entries(v).sort(([a], [b]) => byKey2(a, b)));
19069
+ return v;
19070
+ });
19071
+ }
19072
+ function keyed(items, key) {
19073
+ const map = /* @__PURE__ */ new Map();
19074
+ for (const item of items) {
19075
+ const base = key(item);
19076
+ let k = base;
19077
+ for (let n = 2; map.has(k); n++) k = `${base}#${n}`;
19078
+ map.set(k, item);
19079
+ }
19080
+ return map;
19081
+ }
19082
+ function fieldChanges(before2, after2) {
19083
+ return [.../* @__PURE__ */ new Set([...Object.keys(before2), ...Object.keys(after2)])].filter((field) => canonical(before2[field]) !== canonical(after2[field])).map((field) => ({ field, before: before2[field], after: after2[field] }));
19084
+ }
19085
+ function diffBy(before2, after2, key, fields, keyAfter = key) {
19086
+ const old = keyed(before2, key);
19087
+ const next = keyed(after2, keyAfter);
19088
+ const diff = { added: [], removed: [], changed: [] };
19089
+ for (const k of [...old.keys()].sort(byKey2)) if (!next.has(k)) diff.removed.push(old.get(k));
19090
+ for (const k of [...next.keys()].sort(byKey2)) {
19091
+ const b = old.get(k);
19092
+ const a = next.get(k);
19093
+ if (b === void 0) {
19094
+ diff.added.push(a);
19095
+ continue;
19096
+ }
19097
+ const changes = fieldChanges(fields(b), fields(a));
19098
+ if (changes.length) diff.changed.push({ key: k, before: b, after: a, changes });
19099
+ }
19100
+ return diff;
19101
+ }
19102
+ function withoutLoc({ loc: _loc, ...rest }) {
19103
+ void _loc;
19104
+ return rest;
19105
+ }
19106
+ function stepText(step) {
19107
+ const arrow = step.failed ? "-x" : step.executionType === "SYNC_REQUEST_RESPONSE" ? "->" : "->>";
19108
+ const prefixes = `${step.multiplier !== void 0 ? `x${step.multiplier} ` : ""}${step.sizeBytes !== void 0 ? `~${step.sizeBytes}B ` : ""}`;
19109
+ const label = `${prefixes}${step.stepName}`.trim();
19110
+ const reply = [step.statusCode, step.responseBody].filter((x) => x !== void 0 && x !== "").join(" ");
19111
+ const flags = `${step.isParallel ? " [par]" : ""}${step.isConditional ? ` [if ${step.conditionExpression ?? ""}]` : ""}`;
19112
+ return `${step.fromServiceId} ${arrow} ${step.toServiceId}${label ? ` : ${label}` : ""}${reply ? ` --> ${reply}` : ""}${flags}`;
19113
+ }
19114
+ var steps2 = (list) => list.map(stepText);
19115
+ var nodeFields = (n) => ({
19116
+ kind: n.kind,
19117
+ name: n.name,
19118
+ type: n.type,
19119
+ techStack: n.techStack,
19120
+ ownerTeam: n.ownerTeam,
19121
+ description: n.description,
19122
+ parent: n.parent,
19123
+ replicas: n.replicas,
19124
+ color: n.color,
19125
+ tag: n.tag,
19126
+ critical: n.critical,
19127
+ rank: n.rank,
19128
+ direction: n.direction,
19129
+ style: n.style,
19130
+ system: n.system,
19131
+ position: n.position
19132
+ });
19133
+ function edgeKey(edges) {
19134
+ const pairs = /* @__PURE__ */ new Map();
19135
+ for (const e of edges) pairs.set(`${e.source}->${e.target}`, (pairs.get(`${e.source}->${e.target}`) ?? 0) + 1);
19136
+ return (e) => {
19137
+ const pair = `${e.source}->${e.target}`;
19138
+ return pairs.get(pair) > 1 ? `${pair} : ${e.label ?? ""}` : pair;
19139
+ };
19140
+ }
19141
+ var edgeFields = (e) => ({ label: e.label, tag: e.tag, style: e.style, sourcePort: e.sourcePort, targetPort: e.targetPort });
19142
+ var useCaseFields = (u) => ({
19143
+ name: u.name,
19144
+ description: u.description,
19145
+ entryServiceId: u.entryServiceId,
19146
+ endpoint: u.endpoint,
19147
+ steps: steps2(u.steps)
19148
+ });
19149
+ var scenarioFields = ({ scenario: s }) => ({ name: s.name, outcome: s.outcome, condition: s.condition, steps: steps2(s.steps) });
19150
+ var scenariosOf = (d) => d.useCases.flatMap((u) => u.scenarios.map((scenario) => ({ useCase: u.id, scenario })));
19151
+ function requirementKey(r) {
19152
+ switch (r.kind) {
19153
+ case "latency":
19154
+ return `latency p${r.percentile} ${r.useCase ?? "*"}${r.scenario ? `/${r.scenario}` : ""}`;
19155
+ case "availability":
19156
+ return `availability ${r.useCase ?? "*"}`;
19157
+ case "durable":
19158
+ return `durable ${r.useCase}`;
19159
+ case "survive":
19160
+ return `survive ${canonical(r.target)}`;
19161
+ case "cost":
19162
+ return "cost";
19163
+ }
19164
+ }
19165
+ function requirementFields(r) {
19166
+ switch (r.kind) {
19167
+ case "latency":
19168
+ return { maxMs: r.maxMs };
19169
+ case "availability":
19170
+ return { minPercent: r.minPercent };
19171
+ case "cost":
19172
+ return { maxUsdPerMonth: r.maxUsdPerMonth };
19173
+ default:
19174
+ return {};
19175
+ }
19176
+ }
19177
+ var systemFields = (s) => ({
19178
+ from: s.from,
19179
+ entries: s.entries.map((e) => `${e.id}${e.name !== e.id ? ` "${e.name}"` : ""}${e.useCase ? ` -> "${e.useCase}"` : ""}`),
19180
+ stub: s.stub && withoutLoc(s.stub)
19181
+ });
19182
+ function diffDiagrams(before2, after2) {
19183
+ return {
19184
+ diagram: fieldChanges({ title: before2.title, summary: before2.summary }, { title: after2.title, summary: after2.summary }),
19185
+ nodes: diffBy(before2.nodes, after2.nodes, (n) => n.id, nodeFields),
19186
+ edges: diffBy(before2.edges, after2.edges, edgeKey(before2.edges), edgeFields, edgeKey(after2.edges)),
19187
+ useCases: diffBy(before2.useCases, after2.useCases, (u) => u.id, useCaseFields),
19188
+ scenarios: diffBy(scenariosOf(before2), scenariosOf(after2), (s) => `${s.useCase}/${s.scenario.id}`, scenarioFields),
19189
+ requirements: diffBy(before2.requirements ?? [], after2.requirements ?? [], requirementKey, requirementFields),
19190
+ traffic: diffBy(before2.traffic ?? [], after2.traffic ?? [], (t) => t.useCase, (t) => ({ rps: t.rps, mix: t.mix })),
19191
+ capacity: diffBy(before2.capacity ?? [], after2.capacity ?? [], (c) => c.node, withoutLoc),
19192
+ systems: diffBy(before2.systems ?? [], after2.systems ?? [], (s) => s.id, systemFields)
19193
+ };
19194
+ }
19195
+ var DIFF_SECTIONS = ["nodes", "edges", "useCases", "scenarios", "requirements", "traffic", "capacity", "systems"];
19196
+ function summarizeDiff(diff) {
19197
+ const total = { added: 0, removed: 0, changed: diff.diagram.length };
19198
+ const counts = { total };
19199
+ for (const section2 of DIFF_SECTIONS) {
19200
+ const { added, removed, changed } = diff[section2];
19201
+ counts[section2] = { added: added.length, removed: removed.length, changed: changed.length };
19202
+ total.added += added.length;
19203
+ total.removed += removed.length;
19204
+ total.changed += changed.length;
19205
+ }
19206
+ return counts;
19207
+ }
19208
+
19061
19209
  // ../frontend/src/dsl/sequence.ts
19062
19210
  var PAYLOAD_LIMIT = 40;
19063
19211
  function shorten(text, max = PAYLOAD_LIMIT) {
@@ -19109,9 +19257,9 @@ function buildSequence(useCase, scenario, nodes = []) {
19109
19257
  const depth = stack.map((s) => s.toServiceId).lastIndexOf(from);
19110
19258
  while (stack.length > depth + 1) emit(response(stack.pop()));
19111
19259
  };
19112
- const steps2 = scenario.steps;
19113
- for (let i = 0; i < steps2.length; i++) {
19114
- const step = steps2[i];
19260
+ const steps3 = scenario.steps;
19261
+ for (let i = 0; i < steps3.length; i++) {
19262
+ const step = steps3[i];
19115
19263
  if (step.parallelGroup === void 0) {
19116
19264
  unwindFor(step.fromServiceId);
19117
19265
  emit(request(step));
@@ -19119,7 +19267,7 @@ function buildSequence(useCase, scenario, nodes = []) {
19119
19267
  continue;
19120
19268
  }
19121
19269
  const group = [];
19122
- while (i < steps2.length && steps2[i].parallelGroup === step.parallelGroup) group.push(steps2[i++]);
19270
+ while (i < steps3.length && steps3[i].parallelGroup === step.parallelGroup) group.push(steps3[i++]);
19123
19271
  i--;
19124
19272
  unwindFor(step.fromServiceId);
19125
19273
  items.push({ kind: "par", branches: group.map((s) => hasResponse(s) ? [request(s), response(s)] : [request(s)]) });
@@ -19134,7 +19282,7 @@ function buildSequence(useCase, scenario, nodes = []) {
19134
19282
  const node = byId.get(id);
19135
19283
  participants.push({ id, name: node?.name ?? id, tech: node && !node.implicit ? node.techStack : void 0 });
19136
19284
  };
19137
- for (const step of steps2) {
19285
+ for (const step of steps3) {
19138
19286
  add(step.fromServiceId);
19139
19287
  add(step.toServiceId);
19140
19288
  }
@@ -19622,7 +19770,7 @@ function sharedLoad(root, rootInbound) {
19622
19770
  }
19623
19771
  };
19624
19772
  visit(root, "");
19625
- const send = (d, prefix, inbound) => {
19773
+ const send2 = (d, prefix, inbound) => {
19626
19774
  for (const s of d.systems ?? []) {
19627
19775
  if (!s.diagram) continue;
19628
19776
  const key = teamKey(s);
@@ -19632,12 +19780,12 @@ function sharedLoad(root, rootInbound) {
19632
19780
  if (rps > 0) load.callers.push({ path: prefix ? `${prefix}.${s.id}` : s.id, ...d.title !== void 0 ? { from: d.title } : {}, rps });
19633
19781
  }
19634
19782
  };
19635
- send(root, "", rootInbound);
19783
+ send2(root, "", rootInbound);
19636
19784
  for (const key of order.reverse()) {
19637
19785
  const { diagram, path, loc } = designs.get(key);
19638
19786
  if (!diagram.systems?.length) continue;
19639
19787
  const combined = withExtraTraffic(diagram, byFile.get(key)?.useCases ?? /* @__PURE__ */ new Map(), loc);
19640
- send(diagram, path, inboundLoad(combined, resolveTraffic(combined)));
19788
+ send2(diagram, path, inboundLoad(combined, resolveTraffic(combined)));
19641
19789
  }
19642
19790
  return { byFile, analyses: /* @__PURE__ */ new Map() };
19643
19791
  }
@@ -19755,8 +19903,8 @@ function breachesOf(team, sent, analysis) {
19755
19903
  if (r.scenario !== void 0 && !scenario) continue;
19756
19904
  const what = `${key} of "${u.name}"${scenario ? ` scenario "${scenario.name}"` : ""}`;
19757
19905
  const name = `${what} < ${formatMs(r.maxMs)}`;
19758
- const steps2 = scenario ? scenario.steps : u.scenarios.flatMap((s) => s.steps);
19759
- const saturated = steps2.map((s) => nodes.get(s.toServiceId)).reduce((best, n) => n?.saturated && (!best || n.utilization > best.utilization) ? n : best, void 0);
19906
+ const steps3 = scenario ? scenario.steps : u.scenarios.flatMap((s) => s.steps);
19907
+ const saturated = steps3.map((s) => nodes.get(s.toServiceId)).reduce((best, n) => n?.saturated && (!best || n.utilization > best.utilization) ? n : best, void 0);
19760
19908
  if (saturated) {
19761
19909
  breaches.push({ requirement: name, message: `${what}: ${saturated.id} is saturated (${usageText(saturated)}) ${under} (limit ${formatMs(r.maxMs)})` });
19762
19910
  continue;
@@ -19848,13 +19996,13 @@ function computeEgressGb(diagram, traffic, kindOf2 = (id) => profileOfId(diagram
19848
19996
  }
19849
19997
  var BANDWIDTH_BOUND = (kind) => !["client", "external", "dns", "other", "storage", "cdn"].includes(kind);
19850
19998
  function computeBytesPerSecond(diagram, traffic) {
19851
- const bytes = /* @__PURE__ */ new Map();
19999
+ const bytes2 = /* @__PURE__ */ new Map();
19852
20000
  forEachStepRate(diagram, traffic, (step, rate) => {
19853
20001
  if (!step.sizeBytes || step.sizeBytes <= 0) return;
19854
20002
  const b = rate * multiplierOf(step) * step.sizeBytes;
19855
- for (const id of /* @__PURE__ */ new Set([step.fromServiceId, step.toServiceId])) bytes.set(id, (bytes.get(id) ?? 0) + b);
20003
+ for (const id of /* @__PURE__ */ new Set([step.fromServiceId, step.toServiceId])) bytes2.set(id, (bytes2.get(id) ?? 0) + b);
19856
20004
  });
19857
- return bytes;
20005
+ return bytes2;
19858
20006
  }
19859
20007
  function profileOfId(diagram, id) {
19860
20008
  const node = diagram.nodes.find((n) => n.id === id);
@@ -20010,14 +20158,14 @@ function analyze(diagram, options = {}) {
20010
20158
  const traffic = resolveTraffic(diagram, warnings);
20011
20159
  const load = computeLoad(diagram, traffic);
20012
20160
  const egress = computeEgressGb(diagram, traffic, kindOf2);
20013
- const bytes = computeBytesPerSecond(diagram, traffic);
20161
+ const bytes2 = computeBytesPerSecond(diagram, traffic);
20014
20162
  const systems = diagram.systems?.length ? analyzeSystems(diagram, traffic, options) : void 0;
20015
20163
  const hops = /* @__PURE__ */ new Map();
20016
20164
  const nodeResults = nodes.map((n) => {
20017
20165
  const p = profiles.get(n.id);
20018
20166
  const replicas = Math.max(1, options.replicas?.get(n.id) ?? replicasOf(n));
20019
20167
  const { read, write } = load.get(n.id) ?? { read: 0, write: 0 };
20020
- const usage = usageOf(p, replicas, read, write, bytes.get(n.id) ?? 0);
20168
+ const usage = usageOf(p, replicas, read, write, bytes2.get(n.id) ?? 0);
20021
20169
  const servers = serversOf(usage, replicas);
20022
20170
  const hop = hopModel(p.latencyMs, usage.utilization, servers);
20023
20171
  hops.set(n.id, hop);
@@ -20193,7 +20341,7 @@ var CATEGORY = {
20193
20341
  };
20194
20342
  var percentileName = (q) => PERCENTILE_KEYS[q];
20195
20343
  var lineOf = (loc) => `${loc.file ? `${loc.file}:` : "line "}${loc.line}`;
20196
- function stepText(step) {
20344
+ function stepText2(step) {
20197
20345
  const arrow = step.failed ? "-x" : step.executionType === "SYNC_REQUEST_RESPONSE" ? "->" : "->>";
20198
20346
  const label = requestLabel(step);
20199
20347
  return `${step.fromServiceId} ${arrow} ${step.toServiceId}${label ? ` : ${label}` : ""} at ${lineOf(step.loc)}`;
@@ -20248,10 +20396,10 @@ function unknownUseCase(run2, name) {
20248
20396
  const hint = near.length ? `Use one of ${near.map((u) => quote2(u.name)).join(", ")}` : `Add usecase ${quote2(name)} { \u2026 }`;
20249
20397
  return { ...fail(`No use case named ${quote2(name)}`, hint), missing: `use case ${name}` };
20250
20398
  }
20251
- function saturatedOn(run2, ids, value, maxMs) {
20399
+ function saturatedOn(run2, ids, value2, maxMs) {
20252
20400
  const n = [...new Set(ids)].map((id) => run2.nodes.get(id)).find((x) => !!x?.saturated);
20253
20401
  if (!n) return void 0;
20254
- const v = value(n);
20402
+ const v = value2(n);
20255
20403
  return { ...fail(`${v} (limit ${formatMs(maxMs)})`, saturationHint(run2, n)), value: v };
20256
20404
  }
20257
20405
  function latency(run2, u, q, maxMs) {
@@ -20262,12 +20410,12 @@ function latency(run2, u, q, maxMs) {
20262
20410
  const saturated = saturatedOn(run2, touched, (n) => `${key} of ${u.name}: ${n.id} is saturated (${usageText(n)})`, maxMs);
20263
20411
  if (saturated) return saturated;
20264
20412
  const ms = result.percentiles[key];
20265
- const value = `${key} of ${u.name} is ${formatMs(ms)}${result.rps > 0 ? "" : " with no traffic"}`;
20266
- const message = `${value} (limit ${formatMs(maxMs)})`;
20267
- if (ms < maxMs) return { ...pass(message), value };
20413
+ const value2 = `${key} of ${u.name} is ${formatMs(ms)}${result.rps > 0 ? "" : " with no traffic"}`;
20414
+ const message = `${value2} (limit ${formatMs(maxMs)})`;
20415
+ if (ms < maxMs) return { ...pass(message), value: value2 };
20268
20416
  const index = Math.min(result.tailScenario[key] ?? 0, u.scenarios.length - 1);
20269
20417
  const lead = u.scenarios.length > 1 ? `The "${u.scenarios[index].name}" path (${formatPercent(result.scenarios[index].share)} of traffic) sets ${key}. ` : "";
20270
- return { ...fail(message, lead + latencyHint(run2, u, u.scenarios[index])), value };
20418
+ return { ...fail(message, lead + latencyHint(run2, u, u.scenarios[index])), value: value2 };
20271
20419
  }
20272
20420
  function scenarioLatency(run2, useCase, scenario, q, maxMs) {
20273
20421
  const sc = scope(run2, useCase, scenario);
@@ -20308,14 +20456,14 @@ function latencyHint(run2, u, scenario) {
20308
20456
  const sized = hops.find((h) => (h.step.sizeBytes ?? 0) > 0);
20309
20457
  const node = run2.nodes.get(slowest.target);
20310
20458
  if (node && node.utilization > HOT) return `${label} runs at ${formatPercent(node.utilization)} and queues requests; add replicas to it.`;
20311
- const payload = sized ? ` Payloads add transfer time too (${stepText(sized.step)}): send fewer bytes or let the client fetch them from a CDN or storage directly.` : "";
20459
+ const payload = sized ? ` Payloads add transfer time too (${stepText2(sized.step)}): send fewer bytes or let the client fetch them from a CDN or storage directly.` : "";
20312
20460
  return `Its slowest hop is ${label} at ${formatMs(cost3(slowest))}: put a cache in front of it, run independent calls in par, or move work off the request path with ->>.${payload}`;
20313
20461
  }
20314
20462
  function availability(run2, u, minPercent) {
20315
20463
  const result = run2.useCases.get(u.id);
20316
- const value = `availability of ${u.name} is ${formatAvailability(result.availability)}`;
20317
- const message = `${value} (limit ${minPercent}%)`;
20318
- if (result.availability * 100 >= minPercent - 1e-9) return { ...pass(message), value };
20464
+ const value2 = `availability of ${u.name} is ${formatAvailability(result.availability)}`;
20465
+ const message = `${value2} (limit ${minPercent}%)`;
20466
+ if (result.availability * 100 >= minPercent - 1e-9) return { ...pass(message), value: value2 };
20319
20467
  const shares = run2.shares.get(u.id) ?? [];
20320
20468
  const main = u.scenarios.length ? pathNodes(u, u.scenarios[mainScenarioIndex(shares)]) : [];
20321
20469
  const writes = mainWrites(u, shares, run2.isWrite);
@@ -20323,7 +20471,7 @@ function availability(run2, u, minPercent) {
20323
20471
  const weakest = main.filter((id) => fallbacksFor(u, id).length === 0).map((id) => run2.nodes.get(id)).filter((n) => !!n && effective(n) < 1).sort((a, b) => effective(a) - effective(b))[0];
20324
20472
  const primaryBound = weakest && writes.has(weakest.id) && weakest.writeAvailability < weakest.availability;
20325
20473
  const hint = !weakest ? "Add replicas to the nodes on the main path, or fallback scenarios that complete without them" : primaryBound ? `The weakest link is writing to ${nodeLabel(run2.diagram, weakest.id)}: writes need its primary, ${formatAvailability(weakest.writeAvailability)} with failover${weakest.replicas < 2 ? " (none without a second replica; add one)" : ` (a replica takes over, but about ${formatPercent(FAILOVER_SHARE)} of each outage is lost)`}. Move the writes to a partitioned store, or add a fallback scenario that calls it with -x and still completes` : `The weakest link is ${nodeLabel(run2.diagram, weakest.id)} at ${formatAvailability(effective(weakest))}: add a replica (x${weakest.replicas + 1}) or a fallback scenario that calls it with -x and still completes`;
20326
- return { ...fail(message, hint), value };
20474
+ return { ...fail(message, hint), value: value2 };
20327
20475
  }
20328
20476
  function writeGap(run2, u, s, accept) {
20329
20477
  const { requests, beforeResponse } = requestOrder(u, s);
@@ -20350,11 +20498,11 @@ function writesCheck(run2, u, scenarios, accept, what) {
20350
20498
  const text = (s, gap) => {
20351
20499
  switch (gap.kind) {
20352
20500
  case "async":
20353
- return `${where(s)} writes to ${what} only asynchronously: ${stepText(gap.step)}`;
20501
+ return `${where(s)} writes to ${what} only asynchronously: ${stepText2(gap.step)}`;
20354
20502
  case "after":
20355
- return `${where(s)} writes to ${what} only after responding: ${stepText(gap.step)}`;
20503
+ return `${where(s)} writes to ${what} only after responding: ${stepText2(gap.step)}`;
20356
20504
  case "read":
20357
- return `${where(s)} only reads from ${what} before responding: ${stepText(gap.step)} is a read`;
20505
+ return `${where(s)} only reads from ${what} before responding: ${stepText2(gap.step)} is a read`;
20358
20506
  case "none":
20359
20507
  return `${where(s)} never writes to ${what} before responding`;
20360
20508
  }
@@ -20548,7 +20696,7 @@ function calls(run2, a) {
20548
20696
  const first = calling[0];
20549
20697
  const step = called(first)[0];
20550
20698
  return fail(
20551
- `${multi ? quote2(first.name) : sc.label} calls ${nodeLabel(run2.diagram, step.toServiceId)}: ${stepText(step)}`,
20699
+ `${multi ? quote2(first.name) : sc.label} calls ${nodeLabel(run2.diagram, step.toServiceId)}: ${stepText2(step)}`,
20552
20700
  `Take the call to ${step.toServiceId} out of ${quote2(first.name)}, e.g. serve it from a cache`
20553
20701
  );
20554
20702
  }
@@ -20579,7 +20727,7 @@ function before(run2, a) {
20579
20727
  if (ix < 0 || ix > iy) {
20580
20728
  const where = sc.scenarios.length > 1 || a.scenario ? `In ${quote2(s.name)}` : `In ${quote2(sc.u.name)}`;
20581
20729
  return fail(
20582
- ix < 0 ? `${where}, ${order[iy].to} is called (${stepText(order[iy].step)}) but ${x} never is` : `${where}, ${order[iy].to} is called (${stepText(order[iy].step)}) before ${order[ix].to} (${stepText(order[ix].step)})`,
20730
+ ix < 0 ? `${where}, ${order[iy].to} is called (${stepText2(order[iy].step)}) but ${x} never is` : `${where}, ${order[iy].to} is called (${stepText2(order[iy].step)}) before ${order[ix].to} (${stepText2(order[ix].step)})`,
20583
20731
  `Call ${x} before the first call to ${y}`
20584
20732
  );
20585
20733
  }
@@ -20597,7 +20745,7 @@ function neverWaits(run2, a) {
20597
20745
  if (hop) {
20598
20746
  const where = sc.scenarios.length > 1 ? quote2(s.name) : sc.label;
20599
20747
  return fail(
20600
- `${where} waits for ${nodeLabel(run2.diagram, hop.target)} before responding: ${stepText(hop.step)}${hop.failed ? " times out on the request path" : " is synchronous"}`,
20748
+ `${where} waits for ${nodeLabel(run2.diagram, hop.target)} before responding: ${stepText2(hop.step)}${hop.failed ? " times out on the request path" : " is synchronous"}`,
20601
20749
  `Send it with ->> (through a queue if it must not be lost), or move it after the line that answers the entry request`
20602
20750
  );
20603
20751
  }
@@ -20623,7 +20771,7 @@ function after(run2, a) {
20623
20771
  if (iy < ix) {
20624
20772
  const where = sc.scenarios.length > 1 || a.scenario ? `In ${quote2(s.name)}` : `In ${quote2(sc.u.name)}`;
20625
20773
  return fail(
20626
- `${where}, the last call to ${y} (${stepText(order[iy].step)}) comes before the first call to ${x} (${stepText(order[ix].step)})`,
20774
+ `${where}, the last call to ${y} (${stepText2(order[iy].step)}) comes before the first call to ${x} (${stepText2(order[ix].step)})`,
20627
20775
  `Call ${y} after ${x}: move the step to ${order[iy].to} below the call to ${order[ix].to}`
20628
20776
  );
20629
20777
  }
@@ -20652,9 +20800,9 @@ function senderCalls(run2, a) {
20652
20800
  const step = s.steps.find((st) => from.has(st.fromServiceId) && to.has(st.toServiceId));
20653
20801
  if (!step) continue;
20654
20802
  const where = u.scenarios.length > 1 ? `${quote2(u.name)} scenario ${quote2(s.name)}` : quote2(u.name);
20655
- if (a.quantifier === "some") return pass(`${x} calls ${y}${within}: ${stepText(step)} in ${where}`);
20803
+ if (a.quantifier === "some") return pass(`${x} calls ${y}${within}: ${stepText2(step)} in ${where}`);
20656
20804
  return fail(
20657
- `${x} calls ${y}${within}: ${stepText(step)} in ${where}`,
20805
+ `${x} calls ${y}${within}: ${stepText2(step)} in ${where}`,
20658
20806
  `Let another node make this call (e.g. the client uploads to storage with a presigned URL), or remove the step`
20659
20807
  );
20660
20808
  }
@@ -20675,7 +20823,7 @@ function startsAt(run2, a) {
20675
20823
  const wrong = entries2.find((s) => !ids.has(s.fromServiceId));
20676
20824
  if (wrong) {
20677
20825
  return fail(
20678
- `${quote2(u.name)} starts at ${nodeLabel(run2.diagram, wrong.fromServiceId)}, not ${what}: ${stepText(wrong)}`,
20826
+ `${quote2(u.name)} starts at ${nodeLabel(run2.diagram, wrong.fromServiceId)}, not ${what}: ${stepText2(wrong)}`,
20679
20827
  `Make the first step of "${u.name}" a step sent by ${what}`
20680
20828
  );
20681
20829
  }
@@ -20765,6 +20913,10 @@ var import_node_path6 = require("node:path");
20765
20913
  var ImportError = class extends Error {
20766
20914
  name = "ImportError";
20767
20915
  };
20916
+ var LATEST_TAG = "latest";
20917
+ var VERSION_TAG = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
20918
+ var CLOUD_NAME_SEGMENT = /^[A-Za-z0-9_][A-Za-z0-9._+-]*$/;
20919
+ var MAX_CLOUD_NAME = 200;
20768
20920
  var MAX_SPEC_LENGTH = 1024;
20769
20921
  var SEGMENT = /^[A-Za-z0-9_][A-Za-z0-9._ +-]*$/;
20770
20922
  var HOST = /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?)*(?::\d{1,5})?$/;
@@ -20812,8 +20964,9 @@ function parseRemoteSpec(spec) {
20812
20964
  checkRef(ref, spec);
20813
20965
  return { kind: "git", repo, path, ref };
20814
20966
  }
20967
+ if (scheme === "cloud") return parseCloudSpec(spec);
20815
20968
  if (scheme === "http") throw new ImportError(`'${spec}' uses http://; only https:// imports are allowed`);
20816
- if (scheme !== "https") throw new ImportError(`'${spec}' is not a supported import source; use a relative path, git: or https://`);
20969
+ if (scheme !== "https") throw new ImportError(`'${spec}' is not a supported import source; use a relative path, git:, https:// or cloud:`);
20817
20970
  let url;
20818
20971
  try {
20819
20972
  url = new URL(spec);
@@ -20825,15 +20978,51 @@ function parseRemoteSpec(spec) {
20825
20978
  if (!HOST.test(url.host)) throw new ImportError(`'${spec}' has an invalid host`);
20826
20979
  return { kind: "https", url: url.href };
20827
20980
  }
20981
+ function parseCloudSpec(spec) {
20982
+ const body = spec.slice("cloud:".length);
20983
+ const split2 = body.indexOf("//");
20984
+ const head = split2 === -1 ? body : body.slice(0, split2);
20985
+ const parts = head.split(":");
20986
+ if (parts.length > 2) throw new ImportError(`'${spec}' is not a cloud source; write cloud:<name> or cloud:<name>:<tag>`);
20987
+ const name = parts[0].endsWith(".proschi") ? parts[0].slice(0, -".proschi".length) : parts[0];
20988
+ if (!name || name.length > MAX_CLOUD_NAME || name.split("/").some((p) => !CLOUD_NAME_SEGMENT.test(p) || p === "." || p === "..")) {
20989
+ throw new ImportError(
20990
+ `'${spec}' names an invalid diagram '${parts[0]}'; use the diagram's file name (letters, digits, '.', '_', '+', '-' and '/', no spaces), with or without .proschi`
20991
+ );
20992
+ }
20993
+ const tag = parts.length === 2 ? parts[1] : LATEST_TAG;
20994
+ if (!VERSION_TAG.test(tag)) {
20995
+ throw new ImportError(`'${spec}' has an invalid version tag '${tag}'; use up to 64 letters, digits, '.', '_' and '-', starting with a letter or digit, e.g. 2026-11-01`);
20996
+ }
20997
+ if (split2 === -1) return { kind: "cloud", name, tag };
20998
+ return { kind: "cloud", name, tag, path: repoPathSegments(body.slice(split2 + 2), spec).join("/") };
20999
+ }
20828
21000
  function formatRemoteSpec(spec) {
21001
+ if (spec.kind === "cloud") return `cloud:${spec.name}:${spec.tag}${spec.path ? `//${spec.path}` : ""}`;
20829
21002
  return spec.kind === "git" ? `git:${spec.repo}//${spec.path}@${spec.ref}` : spec.url;
20830
21003
  }
21004
+ function cloudDocumentName(spec) {
21005
+ return `${spec.name}.proschi`;
21006
+ }
20831
21007
  function resolveImportPath(fromPath, importPath) {
20832
21008
  if (importPath.includes("\0")) throw new ImportError(`'${importPath.replace(/\0/g, "")}' contains a NUL character`);
20833
21009
  const remote = parseRemoteSpec(importPath);
21010
+ if (remote?.kind === "cloud" && fromPath && isRemoteSpec(fromPath) && parseRemoteSpec(fromPath)?.kind !== "cloud") {
21011
+ throw new ImportError(`'${importPath}' is a cloud import inside ${fromPath}; cloud: sources only work from your own diagrams`);
21012
+ }
20834
21013
  if (remote) return formatRemoteSpec(remote);
20835
21014
  if (isAbsolutePath(importPath)) throw new ImportError(`'${importPath}' is an absolute path; imports must be relative to the importing file`);
20836
21015
  const from = fromPath && isRemoteSpec(fromPath) ? parseRemoteSpec(fromPath) : void 0;
21016
+ if (from?.kind === "cloud") {
21017
+ const parts2 = (from.path ?? "").split("/").slice(0, -1);
21018
+ for (const part of importPath.split("/")) {
21019
+ if (part === "" || part === ".") continue;
21020
+ if (part !== "..") parts2.push(part);
21021
+ else if (parts2.length > 0) parts2.pop();
21022
+ else throw new ImportError(`'${importPath}' leaves the files saved with cloud:${from.name}:${from.tag}`);
21023
+ }
21024
+ return formatRemoteSpec({ ...from, path: repoPathSegments(parts2.join("/"), importPath).join("/") });
21025
+ }
20837
21026
  if (from?.kind === "git") {
20838
21027
  const parts2 = from.path.split("/").slice(0, -1);
20839
21028
  for (const part of importPath.split("/")) {
@@ -20867,6 +21056,15 @@ function joinImportPath(fromPath, importPath) {
20867
21056
  throw e;
20868
21057
  }
20869
21058
  }
21059
+ function isImportKey(key) {
21060
+ if (key.includes("\0")) return false;
21061
+ if (!isRemoteSpec(key)) return !isAbsolutePath(key);
21062
+ try {
21063
+ return resolveImportPath(void 0, key) === key;
21064
+ } catch {
21065
+ return false;
21066
+ }
21067
+ }
20870
21068
  function mapResolver(files) {
20871
21069
  const paths = Object.keys(files).filter((p) => !isRemoteSpec(p));
20872
21070
  return (importPath, fromPath) => {
@@ -20935,12 +21133,12 @@ function parseArgs(args, styles, err) {
20935
21133
  for (let i = 0; i < args.length; i++) {
20936
21134
  const arg = args[i];
20937
21135
  if (arg === "--format") {
20938
- const value = args[++i];
20939
- if (!styles.includes(value)) {
20940
- err(`Unknown format '${value ?? ""}'; use ${styles.join(", ")}`);
21136
+ const value2 = args[++i];
21137
+ if (!styles.includes(value2)) {
21138
+ err(`Unknown format '${value2 ?? ""}'; use ${styles.join(", ")}`);
20941
21139
  return void 0;
20942
21140
  }
20943
- style = value;
21141
+ style = value2;
20944
21142
  } else if (arg.startsWith("-")) {
20945
21143
  err(`Unknown option ${arg}
20946
21144
 
@@ -21054,11 +21252,14 @@ var LOCK_FILE = "proschi.lock";
21054
21252
  var CACHE_DIR = ".proschi/cache";
21055
21253
  var HASH = /^[0-9a-f]{64}$/;
21056
21254
  var COMMIT = /^[0-9a-f]{40}([0-9a-f]{24})?$/;
21057
- var emptyLock = () => ({ version: 1, git: {}, https: {} });
21255
+ var emptyLock = () => ({ version: 1, git: {}, https: {}, cloud: {} });
21058
21256
  var gitKey = (repo, ref) => `${repo}@${ref}`;
21257
+ var cloudKey = (name, tag) => `${name}:${tag}`;
21059
21258
  var remoteError = {
21060
21259
  noLock: (spec) => new ImportError(`'${spec}' is a remote import and there is no ${LOCK_FILE}; run proschi imports sync`),
21061
- notLocked: (spec) => new ImportError(`'${spec}' is not in ${LOCK_FILE}; run proschi imports sync`),
21260
+ notLocked: (spec) => spec.startsWith("cloud:") ? remoteError.cloud(spec) : new ImportError(`'${spec}' is not in ${LOCK_FILE}; run proschi imports sync`),
21261
+ /** A cloud version that is not pinned yet (docs/design/versions-and-cloud.md). */
21262
+ cloud: (spec) => new ImportError(`'${spec}' is a version in your Proschi account; run proschi imports sync to pin it (cloud sources need proschi login)`),
21062
21263
  notCached: (spec) => new ImportError(`'${spec}' is not in the import cache (${CACHE_DIR}); run proschi imports sync`),
21063
21264
  altered: (spec) => new ImportError(`The cached copy of '${spec}' does not match its hash in ${LOCK_FILE}; run proschi imports sync`)
21064
21265
  };
@@ -21075,7 +21276,8 @@ function parseLock(text) {
21075
21276
  const lock = emptyLock();
21076
21277
  const git = json2.git ?? {};
21077
21278
  const https = json2.https ?? {};
21078
- if (!isRecord(git) || !isRecord(https)) throw invalid('"git" and "https" must be objects');
21279
+ const cloud = json2.cloud ?? {};
21280
+ if (!isRecord(git) || !isRecord(https) || !isRecord(cloud)) throw invalid('"git", "https" and "cloud" must be objects');
21079
21281
  for (const [key, entry] of Object.entries(git)) {
21080
21282
  const at = key.lastIndexOf("@");
21081
21283
  const valid = at > 0 && isRecord(entry) && typeof entry.commit === "string" && COMMIT.test(entry.commit) && isRecord(entry.files) && Object.entries(entry.files).every(([path, hash]) => typeof hash === "string" && HASH.test(hash) && isGitSpec(`git:${key.slice(0, at)}//${path}@${key.slice(at + 1)}`));
@@ -21086,8 +21288,28 @@ function parseLock(text) {
21086
21288
  if (typeof hash !== "string" || !HASH.test(hash) || parseRemoteSpec(url)?.kind !== "https") throw invalid(`bad https entry '${url}'`);
21087
21289
  lock.https[url] = hash;
21088
21290
  }
21291
+ for (const [key, entry] of Object.entries(cloud)) {
21292
+ const hash = (v) => typeof v === "string" && HASH.test(v);
21293
+ const valid = isCanonicalSpec(`cloud:${key}`, "cloud") && isRecord(entry) && typeof entry.tag === "string" && VERSION_TAG.test(entry.tag) && entry.tag !== LATEST_TAG && Number.isSafeInteger(entry.seq) && entry.seq > 0 && hash(entry.sha256) && (entry.source === void 0 || hash(entry.source)) && isRecord(entry.files) && Object.entries(entry.files).every(([path, h]) => hash(h) && isCanonicalSpec(`cloud:${key}//${path}`, "cloud"));
21294
+ if (!valid) throw invalid(`bad cloud entry '${key}'`);
21295
+ lock.cloud[key] = {
21296
+ tag: entry.tag,
21297
+ seq: entry.seq,
21298
+ sha256: entry.sha256,
21299
+ ...entry.source === void 0 ? {} : { source: entry.source },
21300
+ files: { ...entry.files }
21301
+ };
21302
+ }
21089
21303
  return lock;
21090
21304
  }
21305
+ function isCanonicalSpec(spec, kind) {
21306
+ try {
21307
+ const remote = parseRemoteSpec(spec);
21308
+ return remote?.kind === kind && formatRemoteSpec(remote) === spec;
21309
+ } catch {
21310
+ return false;
21311
+ }
21312
+ }
21091
21313
  function isGitSpec(spec) {
21092
21314
  try {
21093
21315
  return parseRemoteSpec(spec)?.kind === "git";
@@ -21099,18 +21321,23 @@ function lockedHash(lock, spec) {
21099
21321
  const remote = parseRemoteSpec(spec);
21100
21322
  if (remote?.kind === "git") return lock.git[gitKey(remote.repo, remote.ref)]?.files[remote.path];
21101
21323
  if (remote?.kind === "https") return lock.https[remote.url];
21324
+ if (remote?.kind === "cloud") {
21325
+ const entry = lock.cloud[cloudKey(remote.name, remote.tag)];
21326
+ return remote.path === void 0 ? entry?.source : entry?.files[remote.path];
21327
+ }
21102
21328
  return void 0;
21103
21329
  }
21104
21330
 
21105
21331
  // src/lock.ts
21106
- var sha256 = (bytes) => (0, import_node_crypto.createHash)("sha256").update(bytes).digest("hex");
21332
+ var sha256 = (bytes2) => (0, import_node_crypto.createHash)("sha256").update(bytes2).digest("hex");
21107
21333
  function readLock(root) {
21108
21334
  const file = (0, import_node_path5.join)(root, LOCK_FILE);
21109
21335
  return (0, import_node_fs4.existsSync)(file) ? parseLock((0, import_node_fs4.readFileSync)(file, "utf8")) : void 0;
21110
21336
  }
21111
21337
  var sorted = (o, map = (v) => v) => Object.fromEntries(Object.keys(o).sort().map((k) => [k, map(o[k])]));
21112
21338
  function formatLock(lock) {
21113
- return JSON.stringify({ version: 1, git: sorted(lock.git, (e) => ({ commit: e.commit, files: sorted(e.files) })), https: sorted(lock.https) }, null, 2) + "\n";
21339
+ const cloud = Object.keys(lock.cloud).length ? { cloud: sorted(lock.cloud, (e) => ({ tag: e.tag, seq: e.seq, sha256: e.sha256, ...e.source ? { source: e.source } : {}, files: sorted(e.files) })) } : {};
21340
+ return JSON.stringify({ version: 1, git: sorted(lock.git, (e) => ({ commit: e.commit, files: sorted(e.files) })), https: sorted(lock.https), ...cloud }, null, 2) + "\n";
21114
21341
  }
21115
21342
  function writeLock(root, lock) {
21116
21343
  (0, import_node_fs4.writeFileSync)((0, import_node_path5.join)(root, LOCK_FILE), formatLock(lock));
@@ -21120,16 +21347,16 @@ function readCached(root, hash, spec) {
21120
21347
  if (!HASH.test(hash)) return void 0;
21121
21348
  const file = cacheFile(root, hash);
21122
21349
  if (!(0, import_node_fs4.existsSync)(file)) return void 0;
21123
- const bytes = (0, import_node_fs4.readFileSync)(file);
21124
- if (sha256(bytes) !== hash) throw remoteError.altered(spec);
21125
- return bytes;
21350
+ const bytes2 = (0, import_node_fs4.readFileSync)(file);
21351
+ if (sha256(bytes2) !== hash) throw remoteError.altered(spec);
21352
+ return bytes2;
21126
21353
  }
21127
- function writeCached(root, bytes) {
21128
- const hash = sha256(bytes);
21354
+ function writeCached(root, bytes2) {
21355
+ const hash = sha256(bytes2);
21129
21356
  const dir = (0, import_node_path5.join)(root, CACHE_DIR);
21130
21357
  (0, import_node_fs4.mkdirSync)(dir, { recursive: true });
21131
21358
  const tmp = (0, import_node_path5.join)(dir, `${hash}.${process.pid}.tmp`);
21132
- (0, import_node_fs4.writeFileSync)(tmp, bytes);
21359
+ (0, import_node_fs4.writeFileSync)(tmp, bytes2);
21133
21360
  (0, import_node_fs4.renameSync)(tmp, cacheFile(root, hash));
21134
21361
  return hash;
21135
21362
  }
@@ -21173,9 +21400,9 @@ function fileResolver({ entry, read = () => void 0, toPath = (p) => p, remote }
21173
21400
  if (!lock) throw remoteError.noLock(spec);
21174
21401
  const hash = lockedHash(lock, spec);
21175
21402
  if (!hash) throw remoteError.notLocked(spec);
21176
- const bytes = readCached(root, hash, spec);
21177
- if (!bytes) throw remoteError.notCached(spec);
21178
- return bytes.toString("utf8");
21403
+ const bytes2 = readCached(root, hash, spec);
21404
+ if (!bytes2) throw remoteError.notCached(spec);
21405
+ return bytes2.toString("utf8");
21179
21406
  };
21180
21407
  const loadRemote = remote ?? fromCache;
21181
21408
  const found = (path, source2, level) => {
@@ -21301,9 +21528,9 @@ function scalar(text, line, inFlow) {
21301
21528
  return text;
21302
21529
  }
21303
21530
  function stringItem(text, line, inFlow) {
21304
- const value = scalar(text, line, inFlow);
21305
- if (typeof value !== "string") throw new FrontMatterError(`List items must be strings; quote ${text}`, line);
21306
- return value;
21531
+ const value2 = scalar(text, line, inFlow);
21532
+ if (typeof value2 !== "string") throw new FrontMatterError(`List items must be strings; quote ${text}`, line);
21533
+ return value2;
21307
21534
  }
21308
21535
  function flowItems(inner, line) {
21309
21536
  const items = [];
@@ -21346,9 +21573,9 @@ function parseFrontMatter(text) {
21346
21573
  const item = raw.match(/^ +- (.*)$/) ?? raw.match(/^ +-()$/);
21347
21574
  if (item) {
21348
21575
  if (!list) throw new FrontMatterError('A list item must follow a key with no value, e.g. "hints:"', line);
21349
- const value2 = item[1].trim();
21350
- if (value2 === "") throw new FrontMatterError("Empty list item", line);
21351
- list.items.push(stringItem(value2, line, false));
21576
+ const value3 = item[1].trim();
21577
+ if (value3 === "") throw new FrontMatterError("Empty list item", line);
21578
+ list.items.push(stringItem(value3, line, false));
21352
21579
  continue;
21353
21580
  }
21354
21581
  if (/^\s/.test(raw)) throw new FrontMatterError(`Unexpected indented line: ${raw.trim()}`, line);
@@ -21357,19 +21584,19 @@ function parseFrontMatter(text) {
21357
21584
  if (!m) throw new FrontMatterError(`Expected "key: value", got: ${raw}`, line);
21358
21585
  const [, key, rest] = m;
21359
21586
  if (Object.prototype.hasOwnProperty.call(data, key)) throw new FrontMatterError(`Duplicate key '${key}'`, line);
21360
- const value = (rest ?? "").trim();
21361
- if (value === "") {
21587
+ const value2 = (rest ?? "").trim();
21588
+ if (value2 === "") {
21362
21589
  list = { key, items: [] };
21363
21590
  data[key] = list.items;
21364
- } else if (value.startsWith("[")) {
21365
- if (!value.endsWith("]")) throw new FrontMatterError(`A list must close on the same line: ${value}`, line);
21366
- data[key] = flowItems(value.slice(1, -1), line);
21591
+ } else if (value2.startsWith("[")) {
21592
+ if (!value2.endsWith("]")) throw new FrontMatterError(`A list must close on the same line: ${value2}`, line);
21593
+ data[key] = flowItems(value2.slice(1, -1), line);
21367
21594
  } else {
21368
- data[key] = scalar(value, line, false);
21595
+ data[key] = scalar(value2, line, false);
21369
21596
  }
21370
21597
  }
21371
- for (const [key, value] of Object.entries(data)) {
21372
- if (Array.isArray(value) && value.length === 0) {
21598
+ for (const [key, value2] of Object.entries(data)) {
21599
+ if (Array.isArray(value2) && value2.length === 0) {
21373
21600
  const line = lines.findIndex((l, i) => i > 0 && i < end && l.startsWith(`${key}:`)) + 1;
21374
21601
  throw new FrontMatterError(`'${key}' has no value`, line);
21375
21602
  }
@@ -21444,11 +21671,11 @@ function readMistake(source2) {
21444
21671
  const m = FIELD_LINE.exec(lines[i]);
21445
21672
  if (!m) continue;
21446
21673
  const field = m[1];
21447
- const value = m[2];
21448
- if (value === "") issues.push({ message: `"# ${field}:" is empty`, line: i + 1 });
21449
- if (field === "explain") values.explain = values.explain ? `${values.explain} ${value}` : value;
21674
+ const value2 = m[2];
21675
+ if (value2 === "") issues.push({ message: `"# ${field}:" is empty`, line: i + 1 });
21676
+ if (field === "explain") values.explain = values.explain ? `${values.explain} ${value2}` : value2;
21450
21677
  else if (values[field] !== void 0) issues.push({ message: `"# ${field}:" appears twice`, line: i + 1 });
21451
- else values[field] = value;
21678
+ else values[field] = value2;
21452
21679
  }
21453
21680
  if (values.mistake === void 0) return { issues };
21454
21681
  const cards = (values.cards ?? "").split(",").map((c) => c.trim()).filter(Boolean);
@@ -21929,8 +22156,8 @@ function readSelector(text) {
21929
22156
  }
21930
22157
  function parseGuided(text) {
21931
22158
  const issues = [];
21932
- const steps2 = [];
21933
- if (!text.trim()) return { steps: steps2, issues: [{ message: "The walkthrough is empty" }] };
22159
+ const steps3 = [];
22160
+ if (!text.trim()) return { steps: steps3, issues: [{ message: "The walkthrough is empty" }] };
21934
22161
  const { preamble, parts } = splitAt(numberedLines(text), 2);
21935
22162
  if (hasText(preamble)) issues.push({ message: 'Each step is a "## " heading; nothing goes before the first one', line: preamble.find((l) => l.text.trim())?.line });
21936
22163
  for (const part of parts) {
@@ -21964,11 +22191,11 @@ function parseGuided(text) {
21964
22191
  }
21965
22192
  if (meta.size === 0) bad(item.line, "a step needs at least one check (- node, - edge, - usecase, - replicas or - test)");
21966
22193
  if (!item.body) bad(item.line, "write what to do and why under the checks");
21967
- steps2.push({ title: item.title, explanation: item.body, checks });
22194
+ steps3.push({ title: item.title, explanation: item.body, checks });
21968
22195
  }
21969
- if (steps2.length < MIN_STEPS) issues.push({ message: `At least ${MIN_STEPS} steps (there are ${steps2.length})` });
21970
- if (steps2.length > MAX_STEPS) issues.push({ message: `At most ${MAX_STEPS} steps (there are ${steps2.length})` });
21971
- return { steps: steps2, issues };
22196
+ if (steps3.length < MIN_STEPS) issues.push({ message: `At least ${MIN_STEPS} steps (there are ${steps3.length})` });
22197
+ if (steps3.length > MAX_STEPS) issues.push({ message: `At most ${MAX_STEPS} steps (there are ${steps3.length})` });
22198
+ return { steps: steps3, issues };
21972
22199
  }
21973
22200
  function matches2(node, s) {
21974
22201
  return "id" in s ? node.id === s.id : kindMatches(kindOf(node), s.kind);
@@ -22032,12 +22259,12 @@ function evaluateChecks(checks, diagram, tests) {
22032
22259
  });
22033
22260
  }
22034
22261
  function guidedIssues(text, solution, solutionTests) {
22035
- const { steps: steps2, issues } = parseGuided(text);
22262
+ const { steps: steps3, issues } = parseGuided(text);
22036
22263
  const ids = new Set(solution.nodes.map((n) => n.id));
22037
22264
  const testNames = new Set((solutionTests ?? []).map((r) => r.name));
22038
22265
  const lines = text.split("\n");
22039
22266
  const lineOf3 = (title) => lines.findIndex((l) => /^##\s/.test(l) && l.includes(title)) + 1 || void 0;
22040
- for (const step of steps2) {
22267
+ for (const step of steps3) {
22041
22268
  const line = lineOf3(step.title);
22042
22269
  for (const c of step.checks) {
22043
22270
  const selectors = c.type === "edge" ? [c.from, c.to] : c.type === "node" || c.type === "replicas" ? [c.node] : [];
@@ -22307,8 +22534,8 @@ function parseNumber(text) {
22307
22534
  if (!Object.prototype.hasOwnProperty.call(SUFFIX, suffix)) return void 0;
22308
22535
  factor = SUFFIX[suffix];
22309
22536
  }
22310
- const value = Number(digits.replace(/[, _]/g, "")) * 10 ** Number(exponent ?? 0) * factor * (sign === "-" ? -1 : 1);
22311
- return Number.isFinite(value) ? value : void 0;
22537
+ const value2 = Number(digits.replace(/[, _]/g, "")) * 10 ** Number(exponent ?? 0) * factor * (sign === "-" ? -1 : 1);
22538
+ return Number.isFinite(value2) ? value2 : void 0;
22312
22539
  }
22313
22540
  function hashText(text) {
22314
22541
  let h = 2166136261;
@@ -22798,12 +23025,12 @@ function problemCheck(args, out, err, cwd) {
22798
23025
  for (let i = 0; i < args.length; i++) {
22799
23026
  const arg = args[i];
22800
23027
  if (arg === "--format") {
22801
- const value = args[++i];
22802
- if (value !== "text" && value !== "github" && value !== "json") {
22803
- err(`Unknown format '${value ?? ""}'; use text, github or json`);
23028
+ const value2 = args[++i];
23029
+ if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
23030
+ err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
22804
23031
  return 2;
22805
23032
  }
22806
- style = value;
23033
+ style = value2;
22807
23034
  } else if (arg.startsWith("-")) {
22808
23035
  err(`Unknown option ${arg}
22809
23036
 
@@ -23089,12 +23316,12 @@ function parseArgs2(args, err, allowFormat) {
23089
23316
  for (let i = 0; i < args.length; i++) {
23090
23317
  const arg = args[i];
23091
23318
  if (allowFormat && arg === "--format") {
23092
- const value = args[++i];
23093
- if (value !== "text" && value !== "github" && value !== "json") {
23094
- err(`Unknown format '${value ?? ""}'; use text, github or json`);
23319
+ const value2 = args[++i];
23320
+ if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
23321
+ err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
23095
23322
  return void 0;
23096
23323
  }
23097
- parsed.style = value;
23324
+ parsed.style = value2;
23098
23325
  } else if (allowFormat && arg === "--problems") {
23099
23326
  parsed.problems = args[++i];
23100
23327
  if (!parsed.problems) {
@@ -23416,19 +23643,19 @@ function parseArgs3(args, err) {
23416
23643
  for (let i = 0; i < args.length; i++) {
23417
23644
  const arg = args[i];
23418
23645
  if (arg === "--format") {
23419
- const value = args[++i];
23420
- if (value !== "text" && value !== "github" && value !== "json") {
23421
- err(`Unknown format '${value ?? ""}'; use text, github or json`);
23646
+ const value2 = args[++i];
23647
+ if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
23648
+ err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
23422
23649
  return void 0;
23423
23650
  }
23424
- parsed.style = value;
23651
+ parsed.style = value2;
23425
23652
  } else if (arg === "--problems" || arg === "--cards") {
23426
- const value = args[++i];
23427
- if (!value) {
23653
+ const value2 = args[++i];
23654
+ if (!value2) {
23428
23655
  err(`Expected a directory after ${arg}`);
23429
23656
  return void 0;
23430
23657
  }
23431
- parsed[arg === "--problems" ? "problems" : "cards"] = value;
23658
+ parsed[arg === "--problems" ? "problems" : "cards"] = value2;
23432
23659
  } else if (arg.startsWith("-")) {
23433
23660
  err(`Unknown option ${arg}
23434
23661
 
@@ -23671,26 +23898,26 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
23671
23898
  if (situation.bots) {
23672
23899
  const chain = chainTo(() => true) ?? [board.nodes.find((n) => n.component === USERS)?.id ?? USERS];
23673
23900
  const stop = chain.findIndex((id) => roleOf2(id) === "waf" || roleOf2(id) === "gateway");
23674
- const steps2 = [];
23901
+ const steps3 = [];
23675
23902
  const path = stop >= 0 ? chain.slice(0, stop + 1) : chain;
23676
- for (let i = 0; i + 1 < path.length; i++) steps2.push(` ${path[i]} -> ${path[i + 1]} : GET /random-${i}`);
23903
+ for (let i = 0; i + 1 < path.length; i++) steps3.push(` ${path[i]} -> ${path[i + 1]} : GET /random-${i}`);
23677
23904
  const last = path[path.length - 1];
23678
23905
  if (stop < 0 && roleOf2(last) === "app") {
23679
23906
  const db = wired(last, "db");
23680
- if (db) steps2.push(` ${last} -> ${db} : SELECT random key`, ` ${db} --> ${last} : nothing`);
23907
+ if (db) steps3.push(` ${last} -> ${db} : SELECT random key`, ` ${db} --> ${last} : nothing`);
23681
23908
  }
23682
23909
  const status = stop >= 0 ? roleOf2(path[stop]) === "waf" ? 403 : 429 : 404;
23683
- for (let i = path.length - 1; i > 0; i--) steps2.push(` ${path[i]} --> ${path[i - 1]} : ${status}`);
23684
- if (steps2.length) bodies.push(`usecase ${quote4(BOTS)} "Scrapers and credential stuffers" {`, ...steps2, "}", "");
23910
+ for (let i = path.length - 1; i > 0; i--) steps3.push(` ${path[i]} --> ${path[i - 1]} : ${status}`);
23911
+ if (steps3.length) bodies.push(`usecase ${quote4(BOTS)} "Scrapers and credential stuffers" {`, ...steps3, "}", "");
23685
23912
  bots = { stoppedBy: stop >= 0 ? path[stop] : void 0, chain: path };
23686
23913
  }
23687
23914
  function routeUseCase(key, uc, chain, handler) {
23688
- const steps2 = uc.steps;
23915
+ const steps3 = uc.steps;
23689
23916
  const queue = wired(handler, "queue");
23690
23917
  const worker = queue ? wired(queue, "worker", true) : void 0;
23691
23918
  const viaWorker = (s) => !!(s.async && queue && worker);
23692
23919
  const targets2 = [];
23693
- for (const s of steps2) {
23920
+ for (const s of steps3) {
23694
23921
  const from = viaWorker(s) ? worker : handler;
23695
23922
  const target = s.op === "call" ? wiredTo(from, s.to) ? s.to : void 0 : wired(from, s.to);
23696
23923
  if (!target) {
@@ -23706,9 +23933,9 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
23706
23933
  const cacheNode = uc.cache !== void 0 && !uc.strong ? wired(handler, "cache", true) : void 0;
23707
23934
  const cacheable = (s) => s.op === "read" && s.to !== "blob" && !viaWorker(s);
23708
23935
  const direct = (s) => !!options.presigned && s.op === "write" && s.to === "blob" && !viaWorker(s);
23709
- const directUpload = steps2.some(direct);
23936
+ const directUpload = steps3.some(direct);
23710
23937
  const chainSize = directUpload ? "" : sizeLabel(uc.size, options.payload);
23711
- const usesCache = cacheNode !== void 0 && steps2.some(cacheable);
23938
+ const usesCache = cacheNode !== void 0 && steps3.some(cacheable);
23712
23939
  const cacheStates = !usesCache ? ["none"] : down.has(cacheNode) ? ["down"] : ["hit", "miss", "down"];
23713
23940
  const regions = situation.global ? [false, true] : [false];
23714
23941
  const plans = [];
@@ -23724,8 +23951,8 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
23724
23951
  const verb = s.op === "call" ? "SEND" : STORE_VERB[s.to]?.[write ? 1 : 0] ?? (write ? "WRITE" : "GET");
23725
23952
  return `${prefix ? `${prefix} ` : ""}${verb} ${s.entity ?? (s.op === "call" ? "message" : "data")}`;
23726
23953
  };
23727
- const cacheKey = steps2.find(cacheable)?.entity ?? "item";
23728
- const hasBackground = steps2.some(viaWorker);
23954
+ const cacheKey = steps3.find(cacheable)?.entity ?? "item";
23955
+ const hasBackground = steps3.some(viaWorker);
23729
23956
  const scenarioText = (p) => {
23730
23957
  const t = [];
23731
23958
  const path = p.edge === "hit" ? chain.slice(0, chain.indexOf(cdn) + 1) : chain;
@@ -23739,7 +23966,7 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
23739
23966
  if (p.cache === "hit") t.push(`${handler} -> ${cacheNode} : GET ${cacheKey}`, `${cacheNode} --> ${handler} : hit`);
23740
23967
  else if (p.cache === "miss") t.push(`${handler} -> ${cacheNode} : GET ${cacheKey}`, `${cacheNode} --> ${handler} : miss`);
23741
23968
  else if (p.cache === "down") t.push(`${handler} -x ${cacheNode} : GET ${cacheKey}`);
23742
- steps2.forEach((s, i) => {
23969
+ steps3.forEach((s, i) => {
23743
23970
  if (viaWorker(s)) return;
23744
23971
  if (p.cache === "hit" && cacheable(s)) return;
23745
23972
  const write = s.op !== "read";
@@ -23749,7 +23976,7 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
23749
23976
  if (hasBackground) t.push(`${handler} ->> ${queue} : ENQUEUE ${uc.name.replace(/[^A-Za-z0-9 ]/g, "")}`);
23750
23977
  }
23751
23978
  for (let i = hops.length - 1; i > 0; i--) t.push(`${hops[i]} --> ${hops[i - 1]} : ${uc.status}`);
23752
- if (p.edge !== "hit") steps2.forEach((s, i) => {
23979
+ if (p.edge !== "hit") steps3.forEach((s, i) => {
23753
23980
  if (direct(s)) t.push(`${hops[0]} -> ${targets2[i]} : ${sizeLabel(s.size ?? uc.size, options.payload)} PUT ${s.entity ?? "file"}`, `${targets2[i]} --> ${hops[0]} : 200`);
23754
23981
  });
23755
23982
  return t;
@@ -23766,13 +23993,13 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
23766
23993
  text.push("}", "");
23767
23994
  let background;
23768
23995
  if (hasBackground) {
23769
- const stalled = down.has(worker) || steps2.some((s, i) => viaWorker(s) && (down.has(targets2[i]) || s.op === "write" && writesDown.has(targets2[i])));
23996
+ const stalled = down.has(worker) || steps3.some((s, i) => viaWorker(s) && (down.has(targets2[i]) || s.op === "write" && writesDown.has(targets2[i])));
23770
23997
  const batching = options.writeShare < 1;
23771
23998
  const bgName = `${uc.name} (background)`;
23772
23999
  const bgScenarios = batching ? [{ name: "Write", writes: true }, { name: "Buffer", writes: false }] : [{ name: "Write", writes: true }];
23773
24000
  const bgText = (writes) => {
23774
24001
  const t = [`${queue} -> ${worker} : job`];
23775
- steps2.forEach((s, i) => {
24002
+ steps3.forEach((s, i) => {
23776
24003
  if (!viaWorker(s)) return;
23777
24004
  if (!writes && s.op === "write") return;
23778
24005
  const write = s.op !== "read";
@@ -24230,7 +24457,7 @@ function eventFromFile(file, text) {
24230
24457
  const requires = f.list("requires");
24231
24458
  for (const r of requires) if (!ROLES.includes(r)) throw new ContentError(file, `"requires:" lists component roles (${ROLES.join(", ")}), not ${r}`);
24232
24459
  const target = f.optionalString("target");
24233
- const value = f.optionalNumber("value");
24460
+ const value2 = f.optionalNumber("value");
24234
24461
  const from = f.optionalNumber("from");
24235
24462
  const then = f.optionalString("then");
24236
24463
  return {
@@ -24242,7 +24469,7 @@ function eventFromFile(file, text) {
24242
24469
  learn: f.list("learn"),
24243
24470
  effect: f.oneOf("effect", EVENT_EFFECTS),
24244
24471
  ...target !== void 0 ? { target } : {},
24245
- ...value !== void 0 ? { value } : {},
24472
+ ...value2 !== void 0 ? { value: value2 } : {},
24246
24473
  ...values.length ? { values } : {},
24247
24474
  duration: f.number("duration", 1),
24248
24475
  ...from !== void 0 ? { from } : {},
@@ -24623,14 +24850,14 @@ function indexOf(content) {
24623
24850
  function mergeRequirements(current, added) {
24624
24851
  const out = [...current];
24625
24852
  for (const line of added) {
24626
- const key = requirementKey(line);
24627
- const at = out.findIndex((l) => requirementKey(l) === key);
24853
+ const key = requirementKey2(line);
24854
+ const at = out.findIndex((l) => requirementKey2(l) === key);
24628
24855
  if (at >= 0) out[at] = line;
24629
24856
  else out.push(line);
24630
24857
  }
24631
24858
  return out;
24632
24859
  }
24633
- function requirementKey(line) {
24860
+ function requirementKey2(line) {
24634
24861
  const t = line.trim();
24635
24862
  const uc = /"([^"]*)"/.exec(t)?.[1] ?? "";
24636
24863
  const head = /^(p\d+(?:\.\d+)?|availability|durable|survive|cost)/.exec(t)?.[1] ?? t;
@@ -26164,9 +26391,9 @@ var Game = class _Game {
26164
26391
  const jobs = [];
26165
26392
  for (const m of this.mode.mechanics) m.shapeUseCases?.(this, useCases, jobs);
26166
26393
  const served = [...s.useCases.filter((k) => this.mode.mechanics.every((m) => m.serves?.(this, k) ?? true)), ...jobs.map((j) => j.key)];
26167
- const value = { useCases, served, jobs };
26168
- this.effectiveCache = { key, value };
26169
- return value;
26394
+ const value2 = { useCases, served, jobs };
26395
+ this.effectiveCache = { key, value: value2 };
26396
+ return value2;
26170
26397
  }
26171
26398
  /** @internal The board compiled to a diagram for a situation, cached. */
26172
26399
  compileFor(board, situation) {
@@ -26698,26 +26925,26 @@ function parseArgs4(args, err) {
26698
26925
  const a = { style: "text", positional: [] };
26699
26926
  for (let i = 0; i < args.length; i++) {
26700
26927
  const arg = args[i];
26701
- const value = () => {
26928
+ const value2 = () => {
26702
26929
  const v = args[++i];
26703
26930
  if (v === void 0) err(`Expected a value after ${arg}`);
26704
26931
  return v;
26705
26932
  };
26706
26933
  if (arg === "--format") {
26707
- const v = value();
26934
+ const v = value2();
26708
26935
  if (v !== "text" && v !== "github" && v !== "json") {
26709
26936
  err(`Unknown format '${v ?? ""}'; use text, github or json`);
26710
26937
  return void 0;
26711
26938
  }
26712
26939
  a.style = v;
26713
26940
  } else if (arg === "--run") {
26714
- a.run = value();
26941
+ a.run = value2();
26715
26942
  if (a.run === void 0) return void 0;
26716
26943
  } else if (arg === "--seed") {
26717
- a.seed = value();
26944
+ a.seed = value2();
26718
26945
  if (a.seed === void 0) return void 0;
26719
26946
  } else if (arg === "--ascension") {
26720
- const v = Number(value());
26947
+ const v = Number(value2());
26721
26948
  if (!Number.isInteger(v) || v < 0) {
26722
26949
  err("--ascension takes a whole number from 0");
26723
26950
  return void 0;
@@ -26931,12 +27158,12 @@ function runShareLink(args, out, err) {
26931
27158
  for (let i = 0; i < args.length; i++) {
26932
27159
  const arg = args[i];
26933
27160
  if (arg === "--base") {
26934
- const value = args[++i];
26935
- if (!value || !/^https?:\/\//.test(value)) {
26936
- err(`Expected --base <http(s) url>, got '${value ?? ""}'`);
27161
+ const value2 = args[++i];
27162
+ if (!value2 || !/^https?:\/\//.test(value2)) {
27163
+ err(`Expected --base <http(s) url>, got '${value2 ?? ""}'`);
26937
27164
  return 2;
26938
27165
  }
26939
- base = value;
27166
+ base = value2;
26940
27167
  } else if (arg.startsWith("-")) {
26941
27168
  err(`Unknown option ${arg}
26942
27169
 
@@ -26997,8 +27224,8 @@ function readFrontMatter(block) {
26997
27224
  }
26998
27225
  block.lines = block.lines.slice(close + 1);
26999
27226
  }
27000
- function unquoteYaml(value) {
27001
- const v = value.trim();
27227
+ function unquoteYaml(value2) {
27228
+ const v = value2.trim();
27002
27229
  if (v.startsWith('"')) {
27003
27230
  try {
27004
27231
  return String(JSON.parse(v));
@@ -27393,12 +27620,12 @@ function readSequence(block, b, start, index) {
27393
27620
  b.warn(line, `Could not read '${statement}'; left out`);
27394
27621
  }
27395
27622
  const name = title || block.title || (index === 0 ? "Sequence" : `Sequence ${index + 1}`);
27396
- const steps2 = new SequenceConverter(b).convert(root, false);
27397
- if (!steps2.some(hasStep)) {
27623
+ const steps3 = new SequenceConverter(b).convert(root, false);
27624
+ if (!steps3.some(hasStep)) {
27398
27625
  b.warn(block.lines[start]?.line, `Sequence diagram '${name}' has no messages; left out`);
27399
27626
  return;
27400
27627
  }
27401
- b.design.useCases.push({ name, steps: steps2, ...scenario ? { scenario } : {} });
27628
+ b.design.useCases.push({ name, steps: steps3, ...scenario ? { scenario } : {} });
27402
27629
  }
27403
27630
  var hasStep = (s) => s.kind === "step" || (s.kind === "par" ? s.steps.some(hasStep) : s.branches.some((br) => br.steps.some(hasStep)));
27404
27631
  var SequenceConverter = class {
@@ -27427,14 +27654,14 @@ var SequenceConverter = class {
27427
27654
  for (const br of branches) out.push(...this.convert(br.items, true));
27428
27655
  continue;
27429
27656
  }
27430
- const steps2 = branches.flatMap((br) => {
27657
+ const steps3 = branches.flatMap((br) => {
27431
27658
  const converted = this.convert(br.items, true);
27432
27659
  if (converted.filter((s) => s.kind === "step" && s.arrow !== "-->").length > 1) {
27433
27660
  this.b.warn(line, `A par branch${br.label ? ` ('${br.label}')` : ""} makes several calls; Proschi runs every step of a par block in parallel`);
27434
27661
  }
27435
27662
  return converted;
27436
27663
  });
27437
- if (steps2.length) out.push({ kind: "par", steps: steps2 });
27664
+ if (steps3.length) out.push({ kind: "par", steps: steps3 });
27438
27665
  } else {
27439
27666
  if (inPar) {
27440
27667
  this.b.warn(line, `${type} inside par: only its first branch is imported`);
@@ -27479,27 +27706,27 @@ var SequenceConverter = class {
27479
27706
  function mergeScenarios(useCases) {
27480
27707
  const out = [];
27481
27708
  const alts = /* @__PURE__ */ new Map();
27482
- const branch = (scenario, steps2) => ({ name: scenario.name, ...scenario.when ? { when: scenario.when } : {}, steps: steps2 });
27483
- for (const { name, description, steps: steps2, scenario } of useCases) {
27709
+ const branch = (scenario, steps3) => ({ name: scenario.name, ...scenario.when ? { when: scenario.when } : {}, steps: steps3 });
27710
+ for (const { name, description, steps: steps3, scenario } of useCases) {
27484
27711
  const alt = scenario && alts.get(name);
27485
27712
  if (alt) {
27486
27713
  let branchName = scenario.name;
27487
27714
  for (let n = 2; alt.branches.some((br) => br.name === branchName); n++) branchName = `${scenario.name} ${n}`;
27488
- alt.branches.push(branch({ ...scenario, name: branchName }, steps2));
27715
+ alt.branches.push(branch({ ...scenario, name: branchName }, steps3));
27489
27716
  continue;
27490
27717
  }
27491
27718
  if (scenario && !alts.has(name) && useCases.filter((u) => u.name === name && u.scenario).length > 1) {
27492
- const created = { kind: "alt", branches: [branch(scenario, steps2)] };
27719
+ const created = { kind: "alt", branches: [branch(scenario, steps3)] };
27493
27720
  alts.set(name, created);
27494
27721
  out.push({ name, ...description ? { description } : {}, steps: [created] });
27495
27722
  continue;
27496
27723
  }
27497
- out.push({ name, ...description ? { description } : {}, steps: steps2 });
27724
+ out.push({ name, ...description ? { description } : {}, steps: steps3 });
27498
27725
  }
27499
27726
  return out;
27500
27727
  }
27501
- function connectSteps(b, steps2) {
27502
- for (const step of steps2) {
27728
+ function connectSteps(b, steps3) {
27729
+ for (const step of steps3) {
27503
27730
  if (step.kind === "par") connectSteps(b, step.steps);
27504
27731
  else if (step.kind === "alt") step.branches.forEach((br) => connectSteps(b, br.steps));
27505
27732
  else if (step.arrow !== "-->" && step.from !== step.to && !b.connected(step.from, step.to)) b.edge(step.from, step.to, void 0);
@@ -27579,13 +27806,327 @@ ${IMPORT_USAGE}`);
27579
27806
  }
27580
27807
 
27581
27808
  // src/sync.ts
27582
- var import_node_fs13 = require("node:fs");
27809
+ var import_node_fs14 = require("node:fs");
27583
27810
 
27584
- // src/fetchers.ts
27585
- var import_node_child_process = require("node:child_process");
27811
+ // src/credentials.ts
27586
27812
  var import_node_fs12 = require("node:fs");
27587
27813
  var import_node_os = require("node:os");
27588
27814
  var import_node_path12 = require("node:path");
27815
+ var DEFAULT_SITE = "https://proschi.app";
27816
+ function credentialsPath(env = process.env, platform = process.platform, home = (0, import_node_os.homedir)()) {
27817
+ if (platform === "win32") return (0, import_node_path12.join)(env.APPDATA || (0, import_node_path12.join)(home, "AppData", "Roaming"), "proschi", "credentials.json");
27818
+ const config = env.XDG_CONFIG_HOME && env.XDG_CONFIG_HOME.startsWith("/") ? env.XDG_CONFIG_HOME : (0, import_node_path12.join)(home, ".config");
27819
+ return (0, import_node_path12.join)(config, "proschi", "credentials.json");
27820
+ }
27821
+ function normalizeBase(value2) {
27822
+ let url;
27823
+ try {
27824
+ url = new URL(value2);
27825
+ } catch {
27826
+ throw new Error(`'${value2}' is not a URL; use e.g. ${DEFAULT_SITE}`);
27827
+ }
27828
+ const local = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
27829
+ if (url.protocol !== "https:" && !(url.protocol === "http:" && local)) {
27830
+ throw new Error(`'${value2}' is not https; only https:// sites (or http://localhost and http://127.0.0.1 for development) are allowed`);
27831
+ }
27832
+ if (url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") {
27833
+ throw new Error(`'${value2}' must be the site's address only, like ${DEFAULT_SITE}`);
27834
+ }
27835
+ return url.origin;
27836
+ }
27837
+ var isSession = (v) => !!v && typeof v === "object" && typeof v.accessToken === "string" && typeof v.refreshToken === "string" && typeof v.expiresAt === "number";
27838
+ var CredentialStore = class {
27839
+ constructor(file = credentialsPath()) {
27840
+ this.file = file;
27841
+ }
27842
+ file;
27843
+ read() {
27844
+ if (!(0, import_node_fs12.existsSync)(this.file)) return { version: 1, sessions: {} };
27845
+ let json2;
27846
+ try {
27847
+ json2 = JSON.parse((0, import_node_fs12.readFileSync)(this.file, "utf8"));
27848
+ } catch {
27849
+ throw new Error(`${this.file} is not valid JSON; delete it and run proschi login`);
27850
+ }
27851
+ const sessions = {};
27852
+ const stored = json2?.sessions;
27853
+ if (stored && typeof stored === "object") {
27854
+ for (const [base, s] of Object.entries(stored)) if (isSession(s)) sessions[base] = s;
27855
+ }
27856
+ return { version: 1, sessions };
27857
+ }
27858
+ /** Writes the file with mode 0600 through a temp file in the same folder, so a reader never sees half a file. */
27859
+ write(data) {
27860
+ const dir = (0, import_node_path12.dirname)(this.file);
27861
+ (0, import_node_fs12.mkdirSync)(dir, { recursive: true, mode: 448 });
27862
+ const tmp = `${this.file}.${process.pid}.${Date.now()}.tmp`;
27863
+ const fd = (0, import_node_fs12.openSync)(tmp, "wx", 384);
27864
+ try {
27865
+ (0, import_node_fs12.writeSync)(fd, JSON.stringify(data, null, 2) + "\n");
27866
+ } finally {
27867
+ (0, import_node_fs12.closeSync)(fd);
27868
+ }
27869
+ if (process.platform !== "win32") (0, import_node_fs12.chmodSync)(tmp, 384);
27870
+ (0, import_node_fs12.renameSync)(tmp, this.file);
27871
+ }
27872
+ get(base) {
27873
+ return this.read().sessions[base];
27874
+ }
27875
+ set(base, session) {
27876
+ const data = this.read();
27877
+ data.sessions[base] = session;
27878
+ this.write(data);
27879
+ }
27880
+ delete(base) {
27881
+ const data = this.read();
27882
+ if (!(base in data.sessions)) return;
27883
+ delete data.sessions[base];
27884
+ this.write(data);
27885
+ }
27886
+ /**
27887
+ * Runs `fn` holding the lock file next to the credentials, so two
27888
+ * processes never refresh with the same token. A lock older than
27889
+ * `staleMs` (a crashed process) is taken over.
27890
+ */
27891
+ async locked(fn, { timeoutMs = 15e3, staleMs = 3e4 } = {}) {
27892
+ const lock = `${this.file}.lock`;
27893
+ (0, import_node_fs12.mkdirSync)((0, import_node_path12.dirname)(lock), { recursive: true, mode: 448 });
27894
+ const start = Date.now();
27895
+ for (; ; ) {
27896
+ try {
27897
+ (0, import_node_fs12.closeSync)((0, import_node_fs12.openSync)(lock, "wx", 384));
27898
+ break;
27899
+ } catch (e) {
27900
+ if (e.code !== "EEXIST") throw e;
27901
+ try {
27902
+ if (Date.now() - (0, import_node_fs12.statSync)(lock).mtimeMs > staleMs) (0, import_node_fs12.rmSync)(lock, { force: true });
27903
+ } catch {
27904
+ }
27905
+ if (Date.now() - start > timeoutMs) throw new Error(`Another proschi process holds ${lock}; try again, or delete it if none runs`);
27906
+ await new Promise((r) => setTimeout(r, 50));
27907
+ }
27908
+ }
27909
+ try {
27910
+ return await fn();
27911
+ } finally {
27912
+ (0, import_node_fs12.rmSync)(lock, { force: true });
27913
+ }
27914
+ }
27915
+ };
27916
+
27917
+ // src/api.ts
27918
+ var TIMEOUT_MS = 3e4;
27919
+ var MAX_RESPONSE_BYTES = 4e6;
27920
+ var EXPIRY_MARGIN_MS = 6e4;
27921
+ var NotSignedInError = class extends Error {
27922
+ name = "NotSignedInError";
27923
+ };
27924
+ var ApiError = class extends Error {
27925
+ constructor(message, status, code) {
27926
+ super(message);
27927
+ this.status = status;
27928
+ this.code = code;
27929
+ }
27930
+ status;
27931
+ code;
27932
+ name = "ApiError";
27933
+ };
27934
+ async function readJson(response2) {
27935
+ const reader = response2.body?.getReader();
27936
+ const chunks = [];
27937
+ let size = 0;
27938
+ for (; ; ) {
27939
+ const chunk = reader ? await reader.read() : { done: true, value: void 0 };
27940
+ if (chunk.done) break;
27941
+ size += chunk.value.byteLength;
27942
+ if (size > MAX_RESPONSE_BYTES) {
27943
+ await reader?.cancel();
27944
+ throw new Error("The answer is too large");
27945
+ }
27946
+ chunks.push(chunk.value);
27947
+ }
27948
+ const text = Buffer.concat(chunks).toString("utf8");
27949
+ if (!text) return void 0;
27950
+ try {
27951
+ return JSON.parse(text);
27952
+ } catch {
27953
+ throw new Error(`The answer (HTTP ${response2.status}) is not JSON`);
27954
+ }
27955
+ }
27956
+ async function send(fetchImpl, url, init = {}) {
27957
+ try {
27958
+ return await fetchImpl(url, { ...init, redirect: "error", signal: AbortSignal.timeout(TIMEOUT_MS) });
27959
+ } catch (e) {
27960
+ throw new Error(`Cannot reach ${new URL(url).origin}: ${e.message}`);
27961
+ }
27962
+ }
27963
+ var messageOf = (body) => {
27964
+ if (!body || typeof body !== "object") return {};
27965
+ const { error, message, error_description } = body;
27966
+ return {
27967
+ code: typeof error === "string" ? error : void 0,
27968
+ message: typeof message === "string" ? message.slice(0, 300) : typeof error_description === "string" ? error_description.slice(0, 300) : void 0
27969
+ };
27970
+ };
27971
+ function sessionFrom(body, now = Date.now()) {
27972
+ const b = body ?? {};
27973
+ if (typeof b.access_token !== "string" || !b.access_token || typeof b.refresh_token !== "string" || !b.refresh_token) {
27974
+ throw new Error("The sign-in answer has no tokens");
27975
+ }
27976
+ const expiresIn = typeof b.expires_in === "number" && b.expires_in > 0 ? b.expires_in : 3600;
27977
+ return { accessToken: b.access_token, refreshToken: b.refresh_token, expiresAt: now + expiresIn * 1e3 };
27978
+ }
27979
+ async function requestTokens(fetchImpl, base, body) {
27980
+ const response2 = await send(fetchImpl, `${base}/auth/token`, {
27981
+ method: "POST",
27982
+ headers: { "content-type": "application/json", accept: "application/json" },
27983
+ body: JSON.stringify(body)
27984
+ });
27985
+ const json2 = await readJson(response2).catch(() => void 0);
27986
+ if (!response2.ok) {
27987
+ const { code, message } = messageOf(json2);
27988
+ throw new ApiError(`Sign-in failed (HTTP ${response2.status}${code ? `, ${code}` : ""})${message ? `: ${message}` : ""}`, response2.status, code);
27989
+ }
27990
+ return sessionFrom(json2);
27991
+ }
27992
+ var ApiClient = class {
27993
+ base;
27994
+ store;
27995
+ fetchImpl;
27996
+ now;
27997
+ constructor({ base, store = new CredentialStore(), fetch: fetchImpl = fetch, now = Date.now }) {
27998
+ this.base = base;
27999
+ this.store = store;
28000
+ this.fetchImpl = fetchImpl;
28001
+ this.now = now;
28002
+ }
28003
+ notSignedIn() {
28004
+ return new NotSignedInError(`Not signed in to ${this.base}; run proschi login`);
28005
+ }
28006
+ /** Whether tokens are stored for the site (they may still have expired). */
28007
+ signedIn() {
28008
+ return this.store.get(this.base) !== void 0;
28009
+ }
28010
+ /**
28011
+ * New tokens for the stored refresh token `used`, unless another process
28012
+ * already refreshed it (then its tokens). An invalid refresh token ends
28013
+ * the sign-in.
28014
+ */
28015
+ async refresh(used2) {
28016
+ return this.store.locked(async () => {
28017
+ const current = this.store.get(this.base);
28018
+ if (!current) throw this.notSignedIn();
28019
+ if (current.refreshToken !== used2.refreshToken) return current;
28020
+ let next;
28021
+ try {
28022
+ next = await requestTokens(this.fetchImpl, this.base, { grant_type: "refresh_token", refresh_token: current.refreshToken });
28023
+ } catch (e) {
28024
+ if (e instanceof ApiError && (e.code === "invalid_grant" || e.status === 401)) {
28025
+ this.store.delete(this.base);
28026
+ throw new NotSignedInError(`The sign-in to ${this.base} has ended; run proschi login`);
28027
+ }
28028
+ throw e;
28029
+ }
28030
+ this.store.set(this.base, next);
28031
+ return next;
28032
+ });
28033
+ }
28034
+ /** GETs a JSON path of the API as the signed-in user; an ApiError for an error answer. */
28035
+ async get(path) {
28036
+ let session = this.store.get(this.base);
28037
+ if (!session) throw this.notSignedIn();
28038
+ if (session.expiresAt - EXPIRY_MARGIN_MS <= this.now()) session = await this.refresh(session);
28039
+ for (let attempt = 0; ; attempt++) {
28040
+ const response2 = await send(this.fetchImpl, `${this.base}${path}`, {
28041
+ headers: { authorization: `Bearer ${session.accessToken}`, accept: "application/json" }
28042
+ });
28043
+ if (response2.status === 401 && attempt === 0) {
28044
+ await response2.body?.cancel();
28045
+ session = await this.refresh(session);
28046
+ continue;
28047
+ }
28048
+ if (response2.status === 401) throw new NotSignedInError(`${this.base} refused the sign-in; run proschi login`);
28049
+ const json2 = await readJson(response2).catch((e) => {
28050
+ if (response2.ok) throw e;
28051
+ return void 0;
28052
+ });
28053
+ if (!response2.ok) {
28054
+ const { code, message } = messageOf(json2);
28055
+ throw new ApiError(message ?? `HTTP ${response2.status}`, response2.status, code);
28056
+ }
28057
+ return json2;
28058
+ }
28059
+ }
28060
+ };
28061
+
28062
+ // src/cloud.ts
28063
+ var import_node_crypto2 = require("node:crypto");
28064
+ function canonicalSha256(source2, imports) {
28065
+ const pairs = Object.entries(imports ?? {}).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
28066
+ return (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify([source2, pairs]), "utf8").digest("hex");
28067
+ }
28068
+ function cloudName(name) {
28069
+ if (name.includes(":") || name.includes("//")) throw new Error(`'${name}' is not a diagram name; write it without cloud: or a tag, e.g. orders`);
28070
+ const spec = parseRemoteSpec(`cloud:${name}`);
28071
+ if (spec?.kind !== "cloud") throw new Error(`'${name}' is not a diagram name`);
28072
+ return spec;
28073
+ }
28074
+ var isRecord3 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
28075
+ var HASH2 = /^[0-9a-f]{64}$/;
28076
+ async function resolveVersion(client, spec, tag) {
28077
+ const where = `cloud:${spec.name}:${tag}`;
28078
+ let body;
28079
+ try {
28080
+ body = await client.get(`/api/me/versions/resolve?name=${encodeURIComponent(cloudDocumentName(spec))}&tag=${encodeURIComponent(tag)}`);
28081
+ } catch (e) {
28082
+ if (e instanceof ApiError && e.status === 404) throw new Error(`'${where}': your account has no diagram ${cloudDocumentName(spec)} with ${tag === LATEST_TAG ? "a saved version" : `a version tagged ${tag}`}`);
28083
+ if (e instanceof ApiError && e.code === "ambiguous_name") throw new Error(`'${where}': several of your diagrams are named ${cloudDocumentName(spec)}; rename one`);
28084
+ if (e instanceof ApiError) throw new Error(`'${where}': ${e.message}`);
28085
+ throw e;
28086
+ }
28087
+ const b = isRecord3(body) ? body : {};
28088
+ const imports = b.imports ?? {};
28089
+ const valid = typeof b.documentId === "string" && typeof b.name === "string" && typeof b.tag === "string" && VERSION_TAG.test(b.tag) && b.tag !== LATEST_TAG && (tag === LATEST_TAG || b.tag === tag) && Number.isSafeInteger(b.seq) && b.seq > 0 && typeof b.sha256 === "string" && HASH2.test(b.sha256) && typeof b.source === "string" && isRecord3(imports) && Object.entries(imports).every(([k, v]) => typeof v === "string" && isImportKey(k));
28090
+ if (!valid) throw new Error(`'${where}': the versions API gave an answer that is not a version`);
28091
+ const version = { ...b, imports };
28092
+ if (canonicalSha256(version.source, version.imports) !== version.sha256) {
28093
+ throw new Error(`'${where}': the content does not match its sha256 ${version.sha256.slice(0, 12)}; try again`);
28094
+ }
28095
+ return {
28096
+ documentId: version.documentId,
28097
+ name: version.name,
28098
+ tag: version.tag,
28099
+ seq: version.seq,
28100
+ sha256: version.sha256,
28101
+ source: version.source,
28102
+ imports: version.imports
28103
+ };
28104
+ }
28105
+ async function findDocument(client, spec) {
28106
+ const body = await client.get("/api/me/documents");
28107
+ const documents = isRecord3(body) && Array.isArray(body.documents) ? body.documents : [];
28108
+ const wanted = cloudDocumentName(spec);
28109
+ const matches3 = documents.filter(
28110
+ (d) => isRecord3(d) && typeof d.id === "string" && !d.deletedAt && (d.name === spec.name || d.name === wanted)
28111
+ );
28112
+ if (matches3.length === 0) throw new Error(`Your account has no diagram named ${wanted}`);
28113
+ if (matches3.length > 1) throw new Error(`Several of your diagrams are named ${wanted}; rename one`);
28114
+ return { id: matches3[0].id, name: matches3[0].name };
28115
+ }
28116
+ async function listVersions(client, documentId) {
28117
+ const body = await client.get(`/api/me/documents/${encodeURIComponent(documentId)}/versions`);
28118
+ const list = isRecord3(body) && Array.isArray(body.versions) ? body.versions : void 0;
28119
+ const ok = (v) => isRecord3(v) && typeof v.tag === "string" && Number.isSafeInteger(v.seq) && typeof v.createdAt === "number" && typeof v.size === "number" && typeof v.sha256 === "string";
28120
+ if (!list || !list.every(ok)) throw new Error("The versions API gave an answer that is not a list of versions");
28121
+ const limit = isRecord3(body) && typeof body.limit === "number" ? body.limit : void 0;
28122
+ return { versions: list.map((v) => ({ tag: v.tag, seq: v.seq, note: typeof v.note === "string" ? v.note : null, createdAt: v.createdAt, size: v.size, sha256: v.sha256 })), limit };
28123
+ }
28124
+
28125
+ // src/fetchers.ts
28126
+ var import_node_child_process = require("node:child_process");
28127
+ var import_node_fs13 = require("node:fs");
28128
+ var import_node_os2 = require("node:os");
28129
+ var import_node_path13 = require("node:path");
27589
28130
  var GIT_TIMEOUT_MS = 12e4;
27590
28131
  var HTTPS_TIMEOUT_MS = 3e4;
27591
28132
  var MAX_REDIRECTS = 5;
@@ -27612,11 +28153,11 @@ function gitEnv() {
27612
28153
  return env;
27613
28154
  }
27614
28155
  var GitScratch = class {
27615
- dir = (0, import_node_fs12.mkdtempSync)((0, import_node_path12.join)((0, import_node_os.tmpdir)(), "proschi-git-"));
27616
- repo = (0, import_node_path12.join)(this.dir, "repo.git");
27617
- noHooks = (0, import_node_path12.join)(this.dir, "no-hooks");
28156
+ dir = (0, import_node_fs13.mkdtempSync)((0, import_node_path13.join)((0, import_node_os2.tmpdir)(), "proschi-git-"));
28157
+ repo = (0, import_node_path13.join)(this.dir, "repo.git");
28158
+ noHooks = (0, import_node_path13.join)(this.dir, "no-hooks");
27618
28159
  constructor() {
27619
- (0, import_node_fs12.mkdirSync)(this.noHooks);
28160
+ (0, import_node_fs13.mkdirSync)(this.noHooks);
27620
28161
  this.git(["init", "--bare", "--quiet", this.repo], false);
27621
28162
  }
27622
28163
  git(args, inRepo = true, encoding = "utf8") {
@@ -27650,7 +28191,7 @@ var GitScratch = class {
27650
28191
  return this.git(["cat-file", "blob", oid], true, "buffer");
27651
28192
  }
27652
28193
  dispose() {
27653
- (0, import_node_fs12.rmSync)(this.dir, { recursive: true, force: true });
28194
+ (0, import_node_fs13.rmSync)(this.dir, { recursive: true, force: true });
27654
28195
  }
27655
28196
  };
27656
28197
  async function fetchHttps(url, fetchImpl = fetch) {
@@ -27690,32 +28231,72 @@ async function fetchHttps(url, fetchImpl = fetch) {
27690
28231
  }
27691
28232
 
27692
28233
  // src/sync.ts
27693
- var IMPORTS_USAGE = ` proschi imports sync [--frozen] [<file|dir>...]`;
28234
+ var IMPORTS_USAGE = ` proschi imports sync [--frozen | --update [<cloud:spec>...]] [--base <url>] [<file|dir>...]`;
27694
28235
  var IMPORTS_HELP = `imports sync
27695
- Downloads the git: and https:// imports of the files (default: the
27696
- current folder) into .proschi/cache and pins them in proschi.lock.
27697
- No other command uses the network. --frozen fails instead of
27698
- changing proschi.lock (for CI).`;
28236
+ Downloads the git:, https:// and cloud: imports of the files (default:
28237
+ the current folder) into .proschi/cache and pins them in proschi.lock:
28238
+ a git ref to its commit, cloud:<name> (latest) or cloud:<name>:<tag>
28239
+ to the version's tag, seq and sha256. A pinned import stays pinned;
28240
+ --update moves the given cloud:<name> imports (default: all of them)
28241
+ to their newest saved version (a concrete tag never moves). cloud:
28242
+ sources need proschi login (--base: the site, default
28243
+ ${DEFAULT_SITE}). No other command fetches imports. --frozen fails
28244
+ instead of changing proschi.lock (for CI).`;
27699
28245
  var staleLock = (what) => new ImportError(`${LOCK_FILE} is out of date: ${what}; run proschi imports sync and commit ${LOCK_FILE}`);
27700
- async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = defaultGitUrl } = {}) {
28246
+ async function syncImports(entries2, { frozen = false, update, fetch: fetch2, gitUrl = defaultGitUrl, api } = {}) {
28247
+ const updated = {};
27701
28248
  const roots = [...new Set(entries2.map((e) => projectRoot(e)))];
27702
28249
  if (roots.length !== 1) {
27703
28250
  const errors2 = roots.length ? [`The files belong to different project roots (${roots.map((r) => displayPath3(r)).join(", ")}); sync each separately`] : ["No .proschi files to sync"];
27704
- return { root: roots[0] ?? "", lock: emptyLock(), errors: errors2, written: false };
28251
+ return { root: roots[0] ?? "", lock: emptyLock(), errors: errors2, written: false, updated };
27705
28252
  }
27706
28253
  const [root] = roots;
27707
28254
  const lock = emptyLock();
28255
+ const fail2 = (errors2) => ({ root, lock, errors: errors2, written: false, updated });
28256
+ if (frozen && update) return fail2(["--update and --frozen cannot be used together"]);
28257
+ let moving;
28258
+ const asked = [];
28259
+ if (update === true) moving = true;
28260
+ else if (update) {
28261
+ moving = /* @__PURE__ */ new Set();
28262
+ for (const spec of update) {
28263
+ let remote;
28264
+ try {
28265
+ remote = parseRemoteSpec(spec);
28266
+ } catch (e) {
28267
+ return fail2([e.message]);
28268
+ }
28269
+ if (remote?.kind !== "cloud" || remote.path !== void 0) return fail2([`--update takes cloud:<name> imports, not '${spec}'`]);
28270
+ const key = cloudKey(remote.name, remote.tag);
28271
+ asked.push(key);
28272
+ if (remote.tag === LATEST_TAG) moving.add(key);
28273
+ }
28274
+ }
28275
+ const moves = (key) => moving === true ? key.endsWith(`:${LATEST_TAG}`) : !!moving?.has(key);
27708
28276
  let old;
27709
28277
  try {
27710
28278
  old = readLock(root);
27711
28279
  } catch (e) {
27712
- return { root, lock, errors: [e.message], written: false };
28280
+ return fail2([e.message]);
27713
28281
  }
27714
- if (frozen && !old) return { root, lock, errors: [`${LOCK_FILE} is missing; run proschi imports sync and commit it`], written: false };
28282
+ if (frozen && !old) return fail2([`${LOCK_FILE} is missing; run proschi imports sync and commit it`]);
27715
28283
  const texts = /* @__PURE__ */ new Map();
27716
28284
  const failed = /* @__PURE__ */ new Map();
27717
28285
  const scratches = /* @__PURE__ */ new Map();
27718
28286
  const commits = /* @__PURE__ */ new Map();
28287
+ const versions = /* @__PURE__ */ new Map();
28288
+ const version = (spec, remote, tag) => {
28289
+ const key = cloudKey(remote.name, tag);
28290
+ if (!versions.has(key)) {
28291
+ const client = api ??= new ApiClient({ base: DEFAULT_SITE });
28292
+ const got = client.signedIn() ? resolveVersion(client, remote, tag).catch((e) => {
28293
+ throw e instanceof ImportError ? e : new ImportError(e.message.startsWith("'cloud:") ? e.message : `'${spec}': ${e.message}`);
28294
+ }) : Promise.reject(new ImportError(`'${spec}': cloud: sources need \`proschi login\``));
28295
+ got.catch(() => void 0);
28296
+ versions.set(key, got);
28297
+ }
28298
+ return versions.get(key);
28299
+ };
27719
28300
  const obtain = async (spec) => {
27720
28301
  const remote = parseRemoteSpec(spec);
27721
28302
  const cached = (hash) => {
@@ -27726,25 +28307,50 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
27726
28307
  }
27727
28308
  };
27728
28309
  const changed = (pin) => new ImportError(`'${spec}' does not match its sha256 in ${LOCK_FILE} (${pin}); its content changed. If that is expected, delete its entry from ${LOCK_FILE} and sync again`);
28310
+ if (remote.kind === "cloud") {
28311
+ const key2 = cloudKey(remote.name, remote.tag);
28312
+ const pinned = moves(key2) ? void 0 : old?.cloud[key2];
28313
+ const pinnedHash2 = remote.path === void 0 ? pinned?.source : pinned?.files[remote.path];
28314
+ if (frozen && !pinnedHash2) throw staleLock(`'${spec}' is not locked`);
28315
+ let bytes3 = cached(pinnedHash2);
28316
+ let at = pinned;
28317
+ if (!bytes3) {
28318
+ const got = await version(spec, remote, pinned?.tag ?? remote.tag);
28319
+ if (pinned && (got.sha256 !== pinned.sha256 || got.seq !== pinned.seq)) {
28320
+ throw changed(`version ${pinned.tag}, seq ${pinned.seq}, sha256 ${pinned.sha256.slice(0, 12)}`);
28321
+ }
28322
+ const text2 = remote.path === void 0 ? got.source : got.imports[remote.path];
28323
+ if (text2 === void 0) throw new ImportError(`'${spec}': no file ${remote.path} is saved with cloud:${remote.name}:${got.tag}`);
28324
+ bytes3 = Buffer.from(text2, "utf8");
28325
+ if (pinnedHash2 && sha256(bytes3) !== pinnedHash2) throw changed(`version ${got.tag}`);
28326
+ writeCached(root, bytes3);
28327
+ at = { tag: got.tag, seq: got.seq, sha256: got.sha256, files: {} };
28328
+ if (moves(key2)) updated[key2] = { from: old?.cloud[key2]?.tag, to: got.tag };
28329
+ }
28330
+ const entry = lock.cloud[key2] ??= { tag: at.tag, seq: at.seq, sha256: at.sha256, files: {} };
28331
+ if (remote.path === void 0) entry.source = sha256(bytes3);
28332
+ else entry.files[remote.path] = sha256(bytes3);
28333
+ return bytes3;
28334
+ }
27729
28335
  if (remote.kind === "https") {
27730
28336
  const pinned = old?.https[remote.url];
27731
28337
  if (frozen && !pinned) throw staleLock(`'${spec}' is not locked`);
27732
- let bytes2 = cached(pinned);
27733
- if (!bytes2) {
27734
- bytes2 = await fetchHttps(remote.url, fetch2);
27735
- if (pinned && sha256(bytes2) !== pinned) throw changed(`sha256 ${pinned.slice(0, 12)}`);
27736
- writeCached(root, bytes2);
28338
+ let bytes3 = cached(pinned);
28339
+ if (!bytes3) {
28340
+ bytes3 = await fetchHttps(remote.url, fetch2);
28341
+ if (pinned && sha256(bytes3) !== pinned) throw changed(`sha256 ${pinned.slice(0, 12)}`);
28342
+ writeCached(root, bytes3);
27737
28343
  }
27738
- lock.https[remote.url] = sha256(bytes2);
27739
- return bytes2;
28344
+ lock.https[remote.url] = sha256(bytes3);
28345
+ return bytes3;
27740
28346
  }
27741
28347
  const key = gitKey(remote.repo, remote.ref);
27742
28348
  const pinnedEntry = old?.git[key];
27743
28349
  const pinnedHash = pinnedEntry?.files[remote.path];
27744
28350
  if (frozen && !pinnedHash) throw staleLock(`'${spec}' is not locked`);
27745
- let bytes = cached(pinnedHash);
28351
+ let bytes2 = cached(pinnedHash);
27746
28352
  let commit = pinnedEntry?.commit;
27747
- if (!bytes) {
28353
+ if (!bytes2) {
27748
28354
  let scratch = scratches.get(remote.repo);
27749
28355
  if (!scratch) scratches.set(remote.repo, scratch = new GitScratch());
27750
28356
  if (!commits.has(key)) {
@@ -27754,13 +28360,13 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
27754
28360
  commits.set(key, got);
27755
28361
  }
27756
28362
  commit = commits.get(key);
27757
- bytes = scratch.read(commit, remote.path, spec);
27758
- if (pinnedHash && sha256(bytes) !== pinnedHash) throw changed(`commit ${commit.slice(0, 12)}`);
27759
- writeCached(root, bytes);
28363
+ bytes2 = scratch.read(commit, remote.path, spec);
28364
+ if (pinnedHash && sha256(bytes2) !== pinnedHash) throw changed(`commit ${commit.slice(0, 12)}`);
28365
+ writeCached(root, bytes2);
27760
28366
  }
27761
28367
  lock.git[key] ??= { commit, files: {} };
27762
- lock.git[key].files[remote.path] = sha256(bytes);
27763
- return bytes;
28368
+ lock.git[key].files[remote.path] = sha256(bytes2);
28369
+ return bytes2;
27764
28370
  };
27765
28371
  let errors = [];
27766
28372
  try {
@@ -27776,7 +28382,7 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
27776
28382
  return void 0;
27777
28383
  }
27778
28384
  });
27779
- parse((0, import_node_fs13.readFileSync)(entry, "utf8"), { path: entry, resolve: resolver });
28385
+ parse((0, import_node_fs14.readFileSync)(entry, "utf8"), { path: entry, resolve: resolver });
27780
28386
  for (const [where, message] of resolver.errors) {
27781
28387
  const from = where.split("\0")[0] || entry;
27782
28388
  found.add(`${isRemoteSpec(from) ? from : displayPath3(from)}: ${message}`);
@@ -27799,15 +28405,18 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
27799
28405
  for (const scratch of scratches.values()) scratch.dispose();
27800
28406
  }
27801
28407
  errors.push(...failed.values());
27802
- if (errors.length) return { root, lock, errors, written: false };
28408
+ for (const key of asked) if (!lock.cloud[key]) errors.push(`--update: 'cloud:${key}' is not imported by these files`);
28409
+ if (errors.length) return fail2(errors);
27803
28410
  const text = formatLock(lock);
27804
28411
  if (old && text !== formatLock(old)) {
27805
- if (frozen) return { root, lock, errors: [staleLock("it locks imports that are no longer used").message], written: false };
28412
+ if (frozen) return fail2([staleLock("it locks imports that are no longer used").message]);
27806
28413
  }
27807
- const write = !frozen && (old ? text !== formatLock(old) : Object.keys(lock.git).length + Object.keys(lock.https).length > 0);
28414
+ const write = !frozen && (old ? text !== formatLock(old) : lockedSources(lock) > 0);
27808
28415
  if (write) writeLock(root, lock);
27809
- return { root, lock, errors, written: write };
28416
+ return { root, lock, errors, written: write, updated };
27810
28417
  }
28418
+ var lockedSources = (lock) => Object.keys(lock.git).length + Object.keys(lock.https).length + Object.keys(lock.cloud).length;
28419
+ var lockedFiles = (lock) => Object.values(lock.git).reduce((n, g) => n + Object.keys(g.files).length, 0) + Object.keys(lock.https).length + Object.values(lock.cloud).reduce((n, c) => n + Object.keys(c.files).length + (c.source ? 1 : 0), 0);
27811
28420
  async function runImports(args, collectFiles2, out, err, options = {}) {
27812
28421
  const [sub, ...rest] = args;
27813
28422
  if (sub !== "sync") {
@@ -27816,10 +28425,22 @@ ${IMPORTS_USAGE}`);
27816
28425
  return 2;
27817
28426
  }
27818
28427
  let frozen = false;
28428
+ let update;
28429
+ let base;
27819
28430
  const paths = [];
27820
- for (const arg of rest) {
28431
+ for (let i = 0; i < rest.length; i++) {
28432
+ const arg = rest[i];
27821
28433
  if (arg === "--frozen") frozen = true;
27822
- else if (arg.startsWith("-")) {
28434
+ else if (arg === "--update") update ??= true;
28435
+ else if (update && arg.startsWith("cloud:")) update = [...update === true ? [] : update, arg];
28436
+ else if (arg === "--base") {
28437
+ try {
28438
+ base = normalizeBase(rest[++i] ?? "");
28439
+ } catch (e) {
28440
+ err(e.message);
28441
+ return 2;
28442
+ }
28443
+ } else if (arg.startsWith("-")) {
27823
28444
  err(`Unknown option ${arg}
27824
28445
 
27825
28446
  Usage:
@@ -27834,21 +28455,332 @@ ${IMPORTS_USAGE}`);
27834
28455
  err(String(e.message));
27835
28456
  return 2;
27836
28457
  }
27837
- const result = await syncImports(files, { ...options, frozen });
28458
+ const api = options.api ?? (base ? new ApiClient({ base }) : void 0);
28459
+ const result = await syncImports(files, { ...options, api, frozen, update });
27838
28460
  if (result.errors.length) {
27839
28461
  err(result.errors.map((e) => `error: ${e}`).join("\n"));
27840
28462
  return 1;
27841
28463
  }
27842
- const sources = Object.keys(result.lock.git).length + Object.keys(result.lock.https).length;
27843
- const filesLocked = Object.values(result.lock.git).reduce((n, g) => n + Object.keys(g.files).length, 0) + Object.keys(result.lock.https).length;
28464
+ for (const [key, { from, to }] of Object.entries(result.updated)) out(from === to ? `cloud:${key}: ${to} (already the newest)` : `cloud:${key}: ${from ?? "(not pinned)"} -> ${to}`);
28465
+ const sources = lockedSources(result.lock);
28466
+ const filesLocked = lockedFiles(result.lock);
27844
28467
  const lockPath = displayPath3(`${result.root}/${LOCK_FILE}`);
27845
- if (!sources) out("No git: or https:// imports to sync");
28468
+ if (!sources) out("No git:, https:// or cloud: imports to sync");
27846
28469
  else out(`${filesLocked} remote file(s) from ${sources} source(s) ${result.written ? "locked in" : "match"} ${lockPath}`);
27847
28470
  return 0;
27848
28471
  }
27849
28472
 
28473
+ // src/login.ts
28474
+ var import_node_child_process2 = require("node:child_process");
28475
+ var import_node_crypto3 = require("node:crypto");
28476
+ var import_node_http = require("node:http");
28477
+ var LOGIN_USAGE = ` proschi login [--provider github|google] [--base <url>]
28478
+ proschi logout [--base <url>]
28479
+ proschi whoami [--base <url>]`;
28480
+ var LOGIN_HELP = `login Signs in to your Proschi account in the browser (the link is printed
28481
+ too, for a machine without one) and stores the tokens in your user's
28482
+ config folder (readable by you only). cloud: imports and proschi
28483
+ versions need it. --base sets the site (default ${DEFAULT_SITE}).
28484
+ logout Ends the sign-in and deletes its tokens.
28485
+ whoami Prints the account you are signed in as.`;
28486
+ var PROVIDERS = ["github", "google"];
28487
+ var LOGIN_TIMEOUT_MS = 5 * 6e4;
28488
+ var base64url = (bytes2) => bytes2.toString("base64url");
28489
+ function openBrowser(url) {
28490
+ const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url]] : ["xdg-open", [url]];
28491
+ return new Promise((resolve8, reject) => {
28492
+ const child = (0, import_node_child_process2.execFile)(command, args, { timeout: 1e4, windowsHide: true }, (error) => error ? reject(error) : resolve8());
28493
+ child.on("error", reject);
28494
+ });
28495
+ }
28496
+ var page = (title, text) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${title}</title><meta name="viewport" content="width=device-width,initial-scale=1"><style>body{font:16px/1.5 system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#f8fafc;color:#0f172a}main{max-width:28rem;padding:2rem;text-align:center}h1{font-size:1.25rem}@media(prefers-color-scheme:dark){body{background:#0f172a;color:#e2e8f0}}</style></head><body><main><h1>${title}</h1><p>${text}</p></main></body></html>`;
28497
+ var sameText = (a, b) => {
28498
+ const x = Buffer.from(a);
28499
+ const y = Buffer.from(b);
28500
+ return x.length === y.length && (0, import_node_crypto3.timingSafeEqual)(x, y);
28501
+ };
28502
+ async function login({
28503
+ base = DEFAULT_SITE,
28504
+ provider = "github",
28505
+ store = new CredentialStore(),
28506
+ fetch: fetchImpl = fetch,
28507
+ open = openBrowser,
28508
+ print = () => void 0,
28509
+ timeoutMs = LOGIN_TIMEOUT_MS
28510
+ } = {}) {
28511
+ const verifier = base64url((0, import_node_crypto3.randomBytes)(32));
28512
+ const challenge = base64url((0, import_node_crypto3.createHash)("sha256").update(verifier).digest());
28513
+ const state = base64url((0, import_node_crypto3.randomBytes)(24));
28514
+ let settle;
28515
+ const callback = new Promise((resolve8, reject) => settle = { resolve: resolve8, reject });
28516
+ let done = false;
28517
+ const server = (0, import_node_http.createServer)((req, res) => {
28518
+ const reply = (status, title, text) => {
28519
+ res.writeHead(status, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "content-security-policy": "default-src 'none'; style-src 'unsafe-inline'" });
28520
+ res.end(page(title, text));
28521
+ };
28522
+ const url = new URL(req.url ?? "/", "http://127.0.0.1");
28523
+ if (done || req.method !== "GET" || url.pathname !== "/callback") return reply(404, "Not found", "Nothing here.");
28524
+ done = true;
28525
+ const got = url.searchParams.get("state") ?? "";
28526
+ const code = url.searchParams.get("code");
28527
+ const error = url.searchParams.get("error");
28528
+ if (!sameText(got, state)) {
28529
+ reply(400, "Sign-in failed", "This sign-in did not come from the proschi login that is waiting. Run proschi login again.");
28530
+ settle.reject(new Error("The sign-in answer does not match this login (state mismatch); run proschi login again"));
28531
+ } else if (error || !code) {
28532
+ reply(400, "Sign-in failed", error === "access_denied" ? "The sign-in was cancelled. You can close this tab." : "The sign-in did not finish. You can close this tab and try again.");
28533
+ settle.reject(new Error(error === "access_denied" ? "The sign-in was cancelled" : `The sign-in failed${error ? ` (${error.replace(/[^\w-]/g, "").slice(0, 40)})` : ""}`));
28534
+ } else {
28535
+ reply(200, "Signed in to Proschi", "You can close this tab and return to the terminal.");
28536
+ settle.resolve(code);
28537
+ }
28538
+ });
28539
+ server.keepAliveTimeout = 1;
28540
+ await new Promise((resolve8, reject) => {
28541
+ server.once("error", reject);
28542
+ server.listen(0, "127.0.0.1", () => resolve8());
28543
+ });
28544
+ const address = server.address();
28545
+ const port = typeof address === "object" && address ? address.port : 0;
28546
+ const redirectUri = `http://127.0.0.1:${port}/callback`;
28547
+ const timer = setTimeout(() => settle.reject(new Error(`No sign-in within ${Math.round(timeoutMs / 6e4) || 1} minute(s); run proschi login again`)), timeoutMs);
28548
+ try {
28549
+ const start = new URL(`${base}/auth/${provider}/start`);
28550
+ start.search = new URLSearchParams({ client: "proschi-cli", redirect_uri: redirectUri, code_challenge: challenge, code_challenge_method: "S256", state }).toString();
28551
+ print(`Opening your browser to sign in to ${base}. If it does not open, visit:
28552
+
28553
+ ${start.href}
28554
+ `);
28555
+ open(start.href).catch(() => print("Could not open a browser; open the link above."));
28556
+ const code = await callback;
28557
+ const session = await requestTokens(fetchImpl, base, { grant_type: "authorization_code", code, code_verifier: verifier, redirect_uri: redirectUri });
28558
+ store.set(base, session);
28559
+ } finally {
28560
+ clearTimeout(timer);
28561
+ server.closeAllConnections?.();
28562
+ server.close();
28563
+ }
28564
+ }
28565
+ async function logout({ base = DEFAULT_SITE, store = new CredentialStore(), fetch: fetchImpl = fetch } = {}) {
28566
+ const session = store.get(base);
28567
+ if (!session) return { signedIn: false, revoked: false };
28568
+ let revoked = false;
28569
+ try {
28570
+ const response2 = await send(fetchImpl, `${base}/auth/revoke`, {
28571
+ method: "POST",
28572
+ headers: { "content-type": "application/json" },
28573
+ body: JSON.stringify({ token: session.refreshToken })
28574
+ });
28575
+ await response2.body?.cancel();
28576
+ revoked = response2.ok;
28577
+ } catch {
28578
+ }
28579
+ store.delete(base);
28580
+ return { signedIn: true, revoked };
28581
+ }
28582
+ async function runAuth(command, args, out, err, deps = {}) {
28583
+ let base = DEFAULT_SITE;
28584
+ let provider = "github";
28585
+ for (let i = 0; i < args.length; i++) {
28586
+ const arg = args[i];
28587
+ if (arg === "--base") {
28588
+ try {
28589
+ base = normalizeBase(args[++i] ?? "");
28590
+ } catch (e) {
28591
+ err(e.message);
28592
+ return 2;
28593
+ }
28594
+ } else if (arg === "--provider" && command === "login") {
28595
+ const value2 = args[++i];
28596
+ if (!PROVIDERS.includes(value2)) {
28597
+ err(`Unknown provider '${value2 ?? ""}'; use ${PROVIDERS.join(" or ")}`);
28598
+ return 2;
28599
+ }
28600
+ provider = value2;
28601
+ } else {
28602
+ err(`Unknown option ${arg}
28603
+
28604
+ Usage:
28605
+ ${LOGIN_USAGE}`);
28606
+ return 2;
28607
+ }
28608
+ }
28609
+ try {
28610
+ if (command === "login") {
28611
+ await login({ base, provider, ...deps, print: err });
28612
+ out(`Signed in to ${base}`);
28613
+ return 0;
28614
+ }
28615
+ if (command === "logout") {
28616
+ const { signedIn, revoked } = await logout({ base, ...deps });
28617
+ if (!signedIn) out(`Not signed in to ${base}`);
28618
+ else out(revoked ? `Signed out of ${base}` : `Deleted the stored sign-in for ${base} (the site could not be reached to end it; it expires on its own)`);
28619
+ return 0;
28620
+ }
28621
+ const me = await new ApiClient({ base, store: deps.store, fetch: deps.fetch }).get("/api/me");
28622
+ const name = typeof me?.user?.displayName === "string" ? me.user.displayName : "an account without a name";
28623
+ out(`Signed in to ${base} as ${name}`);
28624
+ return 0;
28625
+ } catch (e) {
28626
+ err(`error: ${e.message}`);
28627
+ return 1;
28628
+ }
28629
+ }
28630
+
28631
+ // src/versions.ts
28632
+ var VERSIONS_USAGE = ` proschi versions list [--json] [--base <url>] <name>
28633
+ proschi versions diff [--json] [--base <url>] <name> <base-tag> [<target-tag>|<file.proschi>]`;
28634
+ var VERSIONS_HELP = `versions
28635
+ Reads the saved versions of a diagram in your account (proschi login
28636
+ first; <name> is its file name, with or without .proschi). list
28637
+ prints them, newest first. diff prints what changed from <base-tag>
28638
+ to <target-tag> (default: latest), or to a local file (a target
28639
+ ending in .proschi or containing a /). --json prints the result for
28640
+ scripts. Never changes proschi.lock or the cache.`;
28641
+ var SECTION_TITLES = {
28642
+ nodes: "Nodes",
28643
+ edges: "Edges",
28644
+ useCases: "Use cases",
28645
+ scenarios: "Scenarios",
28646
+ requirements: "Requirements",
28647
+ traffic: "Traffic",
28648
+ capacity: "Capacity",
28649
+ systems: "Systems"
28650
+ };
28651
+ function itemLabel(section2, item) {
28652
+ switch (section2) {
28653
+ case "edges": {
28654
+ const e = item;
28655
+ return `${e.source} -> ${e.target}${e.label ? ` : ${e.label}` : ""}`;
28656
+ }
28657
+ case "scenarios": {
28658
+ const s = item;
28659
+ return `${s.useCase}/${s.scenario.id}`;
28660
+ }
28661
+ case "requirements":
28662
+ return requirementKey(item);
28663
+ case "traffic":
28664
+ return item.useCase;
28665
+ case "capacity":
28666
+ return item.node;
28667
+ case "systems":
28668
+ return item.id;
28669
+ default:
28670
+ return item.id;
28671
+ }
28672
+ }
28673
+ var value = (v) => v === void 0 || v === null ? "(none)" : typeof v === "string" ? JSON.stringify(v) : typeof v === "object" ? JSON.stringify(v) : String(v);
28674
+ function changeLines({ field, before: before2, after: after2 }, indent2) {
28675
+ const list = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
28676
+ if ((list(before2) || before2 === void 0) && (list(after2) || after2 === void 0) && (before2 !== void 0 || after2 !== void 0)) {
28677
+ const old = before2 ?? [];
28678
+ const next = after2 ?? [];
28679
+ const lines = [`${indent2}${field}:`];
28680
+ for (const line of old) if (!next.includes(line)) lines.push(`${indent2} - ${line}`);
28681
+ for (const line of next) if (!old.includes(line)) lines.push(`${indent2} + ${line}`);
28682
+ if (lines.length === 1) lines.push(`${indent2} (reordered)`);
28683
+ return lines;
28684
+ }
28685
+ return [`${indent2}${field}: ${value(before2)} \u2192 ${value(after2)}`];
28686
+ }
28687
+ function formatDiff(diff, from, to) {
28688
+ const lines = [`${from} \u2192 ${to}`, ""];
28689
+ if (diff.diagram.length) {
28690
+ lines.push("Diagram");
28691
+ for (const c of diff.diagram) lines.push(...changeLines(c, " ~ "));
28692
+ }
28693
+ for (const section2 of DIFF_SECTIONS) {
28694
+ const { added, removed, changed } = diff[section2];
28695
+ if (!added.length && !removed.length && !changed.length) continue;
28696
+ lines.push(SECTION_TITLES[section2]);
28697
+ for (const item of added) lines.push(` + ${itemLabel(section2, item)}`);
28698
+ for (const item of removed) lines.push(` - ${itemLabel(section2, item)}`);
28699
+ for (const item of changed) {
28700
+ lines.push(` ~ ${item.key}`);
28701
+ for (const c of item.changes) lines.push(...changeLines(c, " "));
28702
+ }
28703
+ }
28704
+ const { total } = summarizeDiff(diff);
28705
+ if (lines.length === 2) lines.push("No changes");
28706
+ else lines.push("", `${total.added} added, ${total.removed} removed, ${total.changed} changed`);
28707
+ return lines.join("\n");
28708
+ }
28709
+ var parseVersion = (v) => parse(v.source, { path: v.name, resolve: mapResolver(v.imports) });
28710
+ var date = (ms) => new Date(ms).toISOString().slice(0, 16).replace("T", " ");
28711
+ var bytes = (n) => n < 1024 ? `${n} B` : `${(n / 1024).toFixed(1)} KB`;
28712
+ function formatVersionList(name, versions, limit) {
28713
+ const head = `${name}: ${versions.length} version${versions.length === 1 ? "" : "s"}${limit !== void 0 ? ` (keeps up to ${limit})` : ""}`;
28714
+ if (!versions.length) return `${head}
28715
+ Save one in the editor (Versions) to import it as cloud:${name.replace(/\.proschi$/, "")}:<tag>`;
28716
+ const rows = [["TAG", "SEQ", "SAVED (UTC)", "SIZE", "NOTE"], ...versions.map((v) => [v.tag, `#${v.seq}`, date(v.createdAt), bytes(v.size), v.note ?? ""])];
28717
+ const widths = rows[0].map((_, i) => Math.max(...rows.map((r) => r[i].length)));
28718
+ return [head, ...rows.map((r) => ` ${r.map((c, i) => i === r.length - 1 ? c : c.padEnd(widths[i])).join(" ")}`.trimEnd())].join("\n");
28719
+ }
28720
+ async function runVersions(args, out, err, deps = {}) {
28721
+ const [sub, ...rest] = args;
28722
+ let json2 = false;
28723
+ let base = DEFAULT_SITE;
28724
+ const positional = [];
28725
+ for (let i = 0; i < rest.length; i++) {
28726
+ const arg = rest[i];
28727
+ if (arg === "--json") json2 = true;
28728
+ else if (arg === "--base") {
28729
+ try {
28730
+ base = normalizeBase(rest[++i] ?? "");
28731
+ } catch (e) {
28732
+ err(e.message);
28733
+ return 2;
28734
+ }
28735
+ } else if (arg.startsWith("-")) {
28736
+ err(`Unknown option ${arg}
28737
+
28738
+ Usage:
28739
+ ${VERSIONS_USAGE}`);
28740
+ return 2;
28741
+ } else positional.push(arg);
28742
+ }
28743
+ const usage = () => (err(`Usage:
28744
+ ${VERSIONS_USAGE}`), 2);
28745
+ if (sub === "list" ? positional.length !== 1 : sub === "diff" ? positional.length < 2 || positional.length > 3 : true) return usage();
28746
+ const client = new ApiClient({ base, store: deps.store, fetch: deps.fetch });
28747
+ try {
28748
+ const spec = cloudName(positional[0]);
28749
+ if (sub === "list") {
28750
+ const doc = await findDocument(client, spec);
28751
+ const { versions, limit } = await listVersions(client, doc.id);
28752
+ out(json2 ? JSON.stringify({ name: doc.name, documentId: doc.id, versions, limit }, null, 2) : formatVersionList(doc.name, versions, limit));
28753
+ return 0;
28754
+ }
28755
+ const [, baseTag, target = LATEST_TAG] = positional;
28756
+ const isFile = target.endsWith(".proschi") || target.includes("/") || target.includes("\\");
28757
+ for (const tag of isFile ? [baseTag] : [baseTag, target]) {
28758
+ if (!VERSION_TAG.test(tag)) throw new Error(`'${tag}' is not a version tag (letters, digits, '.', '_' and '-'), or latest`);
28759
+ }
28760
+ const before2 = await resolveVersion(client, spec, baseTag);
28761
+ const after2 = isFile ? void 0 : await resolveVersion(client, spec, target);
28762
+ const left = parseVersion(before2);
28763
+ const right = after2 ? parseVersion(after2) : parseFile(target);
28764
+ const label = (v, asked) => `cloud:${spec.name}:${v.tag} (#${v.seq}${asked === LATEST_TAG ? ", latest" : ""})`;
28765
+ const toLabel = after2 ? label(after2, target) : displayPath3(target);
28766
+ for (const [what, r] of [[label(before2, baseTag), left], [toLabel, right]]) {
28767
+ const errors = r.diagnostics.filter((d) => d.severity === "error").length;
28768
+ if (errors) err(`warning: ${what} has ${errors} error(s); the diff covers what parsed`);
28769
+ }
28770
+ const diff = diffDiagrams(left.diagram, right.diagram);
28771
+ if (json2) {
28772
+ const side = (v) => ({ tag: v.tag, seq: v.seq, sha256: v.sha256 });
28773
+ out(JSON.stringify({ name: spec.name, base: side(before2), target: after2 ? side(after2) : { file: displayPath3(target) }, summary: summarizeDiff(diff), diff }, null, 2));
28774
+ } else out(formatDiff(diff, label(before2, baseTag), toLabel));
28775
+ return 0;
28776
+ } catch (e) {
28777
+ err(`error: ${e.message}`);
28778
+ return 1;
28779
+ }
28780
+ }
28781
+
27850
28782
  // src/cli.ts
27851
- var VERSION2 = true ? "0.13.0" : "dev";
28783
+ var VERSION2 = true ? "0.14.0" : "dev";
27852
28784
  var USAGE = `Usage:
27853
28785
  proschi check [--strict] [--format text|github|json] [--openapi <node>=<spec>]... <file|dir>...
27854
28786
  proschi parse <file>
@@ -27862,6 +28794,8 @@ ${GAME_USAGE}
27862
28794
  ${SHARE_USAGE}
27863
28795
  ${IMPORT_USAGE}
27864
28796
  ${IMPORTS_USAGE}
28797
+ ${LOGIN_USAGE}
28798
+ ${VERSIONS_USAGE}
27865
28799
  proschi --version
27866
28800
 
27867
28801
  check Reports errors and warnings. Directories are searched for *.proschi files.
@@ -27881,19 +28815,21 @@ ${ACHIEVEMENTS_HELP}
27881
28815
  ${GAME_HELP}
27882
28816
  ${SHARE_HELP}
27883
28817
  ${IMPORT_HELP}
27884
- ${IMPORTS_HELP}`;
28818
+ ${IMPORTS_HELP}
28819
+ ${LOGIN_HELP}
28820
+ ${VERSIONS_HELP}`;
27885
28821
  function collectFiles(paths) {
27886
28822
  const out = [];
27887
28823
  const walk = (dir) => {
27888
- for (const entry of (0, import_node_fs14.readdirSync)(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
28824
+ for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
27889
28825
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
27890
- const full = (0, import_node_path13.join)(dir, entry.name);
28826
+ const full = (0, import_node_path14.join)(dir, entry.name);
27891
28827
  if (entry.isDirectory()) walk(full);
27892
28828
  else if (entry.name.endsWith(".proschi")) out.push(full);
27893
28829
  }
27894
28830
  };
27895
28831
  for (const p of paths) {
27896
- if ((0, import_node_fs14.statSync)(p).isDirectory()) walk(p);
28832
+ if ((0, import_node_fs15.statSync)(p).isDirectory()) walk(p);
27897
28833
  else out.push(p);
27898
28834
  }
27899
28835
  return out;
@@ -27948,6 +28884,8 @@ function run(argv, out = console.log, err = console.error) {
27948
28884
  if (command === "share-link") return runShareLink(rest, out, err);
27949
28885
  if (command === "import") return runImport(rest, out, err);
27950
28886
  if (command === "imports") return runImports(rest, collectFiles, out, err);
28887
+ if (command === "login" || command === "logout" || command === "whoami") return runAuth(command, rest, out, err);
28888
+ if (command === "versions") return runVersions(rest, out, err);
27951
28889
  if (command === "check") {
27952
28890
  let strict = false;
27953
28891
  let style = "text";
@@ -27957,12 +28895,12 @@ function run(argv, out = console.log, err = console.error) {
27957
28895
  const arg = rest[i];
27958
28896
  if (arg === "--strict") strict = true;
27959
28897
  else if (arg === "--format") {
27960
- const value = rest[++i];
27961
- if (value !== "text" && value !== "github" && value !== "json") {
27962
- err(`Unknown format '${value ?? ""}'; use text, github or json`);
28898
+ const value2 = rest[++i];
28899
+ if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
28900
+ err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
27963
28901
  return 2;
27964
28902
  }
27965
- style = value;
28903
+ style = value2;
27966
28904
  } else if (arg === "--openapi") {
27967
28905
  const spec = parseSpecFlag(rest[++i] ?? "");
27968
28906
  if (!spec) {