@neocompose/cli 0.71.1 → 0.71.3

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/neo.mjs CHANGED
@@ -597,6 +597,13 @@ function isGeneratedCSharpReservedKeyword(value) {
597
597
  function generatedCSharpMemberNameForSchemaKey(schemaKey) {
598
598
  return isGeneratedCSharpReservedKeyword(schemaKey) ? `${schemaKey}Value` : schemaKey;
599
599
  }
600
+ function generatedCSharpTypeName(value, fallback) {
601
+ const parts = value.match(/[A-Za-z0-9]+/g) ?? [];
602
+ const joined = parts.map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join("");
603
+ const candidate = joined.length > 0 ? joined : fallback;
604
+ const safe = /^[0-9]/.test(candidate) ? `_${candidate}` : candidate;
605
+ return isGeneratedCSharpReservedKeyword(safe) ? `${safe}Type` : safe;
606
+ }
600
607
  var GENERATED_CSHARP_RESERVED_KEYWORDS, GENERATED_CSHARP_IDENTIFIER_REGEX;
601
608
  var init_generated_csharp_identifiers = __esm({
602
609
  "../packages/neoscript-language/src/generated-csharp-identifiers.ts"() {
@@ -4022,16 +4029,16 @@ function isLiteralValueContent(value) {
4022
4029
  return false;
4023
4030
  }
4024
4031
  }
4025
- const constructorArgs = getField(value, "constructorArgs");
4026
- if (constructorArgs === void 0) return true;
4027
- if (constructorArgs === null) return false;
4032
+ const constructorArgs2 = getField(value, "constructorArgs");
4033
+ if (constructorArgs2 === void 0) return true;
4034
+ if (constructorArgs2 === null) return false;
4028
4035
  if (typeof classIdField !== "string") return false;
4029
4036
  const literalValue = getField(value, "value");
4030
4037
  if (typeof literalValue !== "object" || literalValue === null) return false;
4031
4038
  if (Array.isArray(literalValue)) return false;
4032
- if (typeof constructorArgs !== "object") return false;
4033
- if (Array.isArray(constructorArgs)) return false;
4034
- return Object.keys(constructorArgs).every((key) => key.length > 0);
4039
+ if (typeof constructorArgs2 !== "object") return false;
4040
+ if (Array.isArray(constructorArgs2)) return false;
4041
+ return Object.keys(constructorArgs2).every((key) => key.length > 0);
4035
4042
  }
4036
4043
  function isInitValueContent(value) {
4037
4044
  if (!hasField(value, "init")) return false;
@@ -8199,16 +8206,16 @@ function encodeStoredValueRowFields(row) {
8199
8206
  };
8200
8207
  }
8201
8208
  function canonicalInstanceProvenanceViolation(value) {
8202
- const constructorArgs = "constructorArgs" in value ? value.constructorArgs : void 0;
8209
+ const constructorArgs2 = "constructorArgs" in value ? value.constructorArgs : void 0;
8203
8210
  const constructorId = "instanceConstructorId" in value ? value.instanceConstructorId : void 0;
8204
8211
  const variantId = "instanceVariantId" in value ? value.instanceVariantId : void 0;
8205
- if (constructorArgs !== void 0 && constructorId === void 0 && typeof variantId !== "string") {
8212
+ if (constructorArgs2 !== void 0 && constructorId === void 0 && typeof variantId !== "string") {
8206
8213
  return "constructor-args-without-stamp";
8207
8214
  }
8208
- if (typeof constructorId === "string" && constructorArgs === void 0) {
8215
+ if (typeof constructorId === "string" && constructorArgs2 === void 0) {
8209
8216
  return "named-constructor-without-args";
8210
8217
  }
8211
- if (constructorId === null && constructorArgs !== void 0 && typeof constructorArgs === "object" && constructorArgs !== null && !Array.isArray(constructorArgs) && Object.keys(constructorArgs).length > 0) {
8218
+ if (constructorId === null && constructorArgs2 !== void 0 && typeof constructorArgs2 === "object" && constructorArgs2 !== null && !Array.isArray(constructorArgs2) && Object.keys(constructorArgs2).length > 0) {
8212
8219
  return "implicit-constructor-with-args";
8213
8220
  }
8214
8221
  if ("instanceVariantRowValueId" in value && typeof value.instanceVariantRowValueId === "string" && typeof variantId !== "string") {
@@ -9089,14 +9096,14 @@ function decodePackedValueRow(row) {
9089
9096
  constructionRootId: isCollapseStampedInstanceRoot(row) ? row.id : null
9090
9097
  };
9091
9098
  const value = decodeContentField(row.value, "value", scope, children);
9092
- const constructorArgs = decodeContentField(
9099
+ const constructorArgs2 = decodeContentField(
9093
9100
  isLiteralValueContent(row) ? row.constructorArgs : void 0,
9094
9101
  "constructorArgs",
9095
9102
  scope,
9096
9103
  children
9097
9104
  );
9098
9105
  return {
9099
- row: withDecodedContent(row, value, constructorArgs),
9106
+ row: withDecodedContent(row, value, constructorArgs2),
9100
9107
  children,
9101
9108
  packedChildIdsByParentId: state.edges
9102
9109
  };
@@ -9158,13 +9165,13 @@ function encodePackedValueRow(args) {
9158
9165
  const pending = pendingPackedChildIds(scope);
9159
9166
  if (pending === null) return args.parent;
9160
9167
  const value = encodeContentField(args.parent.value, pending, scope);
9161
- const constructorArgs = encodeContentField(
9168
+ const constructorArgs2 = encodeContentField(
9162
9169
  isLiteralValueContent(args.parent) ? args.parent.constructorArgs : void 0,
9163
9170
  pending,
9164
9171
  scope
9165
9172
  );
9166
9173
  assertEveryChildPlaced(pending, scope);
9167
- return withDecodedContent(args.parent, value, constructorArgs);
9174
+ return withDecodedContent(args.parent, value, constructorArgs2);
9168
9175
  }
9169
9176
  function canonicalPackedChildId(args) {
9170
9177
  if (args.constructionRootId === null) return null;
@@ -9229,7 +9236,7 @@ function logicalChildRow(entry, id2, scope, children) {
9229
9236
  };
9230
9237
  if (isInitValueContent(entry)) return { ...rowFields, init: entry.init };
9231
9238
  const value = decodeContentField(entry.value, "value", scope, children);
9232
- const constructorArgs = decodeContentField(
9239
+ const constructorArgs2 = decodeContentField(
9233
9240
  entry.constructorArgs,
9234
9241
  "constructorArgs",
9235
9242
  scope,
@@ -9237,7 +9244,7 @@ function logicalChildRow(entry, id2, scope, children) {
9237
9244
  );
9238
9245
  return {
9239
9246
  ...rowFields,
9240
- ...literalContent(entry, value, constructorArgs)
9247
+ ...literalContent(entry, value, constructorArgs2)
9241
9248
  };
9242
9249
  }
9243
9250
  function packedEntryLogicalId(entry, label, constructionRootId) {
@@ -9391,7 +9398,7 @@ function encodeEnvelope(childId, position, pending, scope) {
9391
9398
  [PACKED_VALUE_ENTRY_KEY]: packedEntry(child2, null, null, storedId)
9392
9399
  };
9393
9400
  const value = encodeContentField(child2.value, childPending, childScope);
9394
- const constructorArgs = encodeContentField(
9401
+ const constructorArgs2 = encodeContentField(
9395
9402
  isLiteralValueContent(child2) ? child2.constructorArgs : void 0,
9396
9403
  childPending,
9397
9404
  childScope
@@ -9401,12 +9408,12 @@ function encodeEnvelope(childId, position, pending, scope) {
9401
9408
  [PACKED_VALUE_ENTRY_KEY]: packedEntry(
9402
9409
  child2,
9403
9410
  value,
9404
- constructorArgs,
9411
+ constructorArgs2,
9405
9412
  storedId
9406
9413
  )
9407
9414
  };
9408
9415
  }
9409
- function packedEntry(child2, value, constructorArgs, storedId) {
9416
+ function packedEntry(child2, value, constructorArgs2, storedId) {
9410
9417
  const identity2 = storedId === void 0 ? {} : { id: storedId };
9411
9418
  const trailer = {
9412
9419
  ...child2.genericBindings === void 0 ? {} : { genericBindings: child2.genericBindings },
@@ -9419,11 +9426,11 @@ function packedEntry(child2, value, constructorArgs, storedId) {
9419
9426
  }
9420
9427
  return {
9421
9428
  ...identity2,
9422
- ...literalContent(child2, value, constructorArgs),
9429
+ ...literalContent(child2, value, constructorArgs2),
9423
9430
  ...trailer
9424
9431
  };
9425
9432
  }
9426
- function literalContent(content, value, constructorArgs) {
9433
+ function literalContent(content, value, constructorArgs2) {
9427
9434
  if (!isLiteralValueContent(content)) {
9428
9435
  throw new PackedValueEncodingError(
9429
9436
  `Value container has no literal "value" to encode.`
@@ -9434,12 +9441,12 @@ function literalContent(content, value, constructorArgs) {
9434
9441
  value: value === null ? content.value : value.content,
9435
9442
  ...Object.hasOwn(content, "classId") ? { classId: content.classId } : {},
9436
9443
  ...provenance,
9437
- ...constructorArgs === null ? {} : { constructorArgs: asConstructorArgs(constructorArgs.content) }
9444
+ ...constructorArgs2 === null ? {} : { constructorArgs: asConstructorArgs(constructorArgs2.content) }
9438
9445
  };
9439
9446
  }
9440
- function withDecodedContent(row, value, constructorArgs) {
9441
- if (value === null && constructorArgs === null) return row;
9442
- return { ...row, ...literalContent(row, value, constructorArgs) };
9447
+ function withDecodedContent(row, value, constructorArgs2) {
9448
+ if (value === null && constructorArgs2 === null) return row;
9449
+ return { ...row, ...literalContent(row, value, constructorArgs2) };
9443
9450
  }
9444
9451
  function asConstructorArgs(content) {
9445
9452
  if (content === null) return null;
@@ -14206,7 +14213,8 @@ var init_neoflow_graph_parser = __esm({
14206
14213
  this.baseOffset + valueStartToken.start,
14207
14214
  this.baseOffset + end.end
14208
14215
  ),
14209
- range: this.absoluteRange(start, end)
14216
+ range: this.absoluteRange(start, end),
14217
+ valueRange: this.absoluteRange(valueStartToken, end)
14210
14218
  });
14211
14219
  }
14212
14220
  if (!this.eat(",") && !this.at(")")) {
@@ -14405,6 +14413,12 @@ var init_neoflow_graph_parser = __esm({
14405
14413
  name: name.text,
14406
14414
  nameRange: this.absoluteRange(name, name),
14407
14415
  initializer,
14416
+ initializerRange: {
14417
+ start: this.source.positionAt(
14418
+ equalsOffset + this.source.text.slice(equalsOffset, this.baseOffset + last.start).indexOf(initializer)
14419
+ ),
14420
+ end: this.source.positionAt(this.baseOffset + last.start)
14421
+ },
14408
14422
  range: this.absoluteRange(first, last)
14409
14423
  });
14410
14424
  } else {
@@ -15804,7 +15818,9 @@ var init_project_source_parser = __esm({
15804
15818
  const type = this.parseType();
15805
15819
  const name = this.expectName("global name");
15806
15820
  this.expect("=");
15821
+ const initializerStart = this.cursor;
15807
15822
  const initializer = this.captureInitializer();
15823
+ const dialogueGroup = type.name === "DialogueGroup" ? this.parseDialogueGroupBody(initializerStart, initializer) : void 0;
15808
15824
  this.reportNestedTypes(initializer);
15809
15825
  return {
15810
15826
  kind: "global",
@@ -15813,9 +15829,53 @@ var init_project_source_parser = __esm({
15813
15829
  name: name.text,
15814
15830
  nameRange: name.range,
15815
15831
  initializer,
15832
+ ...dialogueGroup ? { dialogueGroup } : {},
15816
15833
  range: rangeFrom(start, this.previous())
15817
15834
  };
15818
15835
  }
15836
+ parseDialogueGroupBody(start, initializer) {
15837
+ const end = this.cursor;
15838
+ let depth = 0;
15839
+ let open = -1;
15840
+ for (let index = start; index < end; index++) {
15841
+ const text = this.tokens[index].text;
15842
+ if (text === "(" || text === "[") depth++;
15843
+ else if (text === ")" || text === "]") depth--;
15844
+ else if (text === "{" && depth === 0) {
15845
+ open = index;
15846
+ break;
15847
+ }
15848
+ }
15849
+ if (open < 0) return void 0;
15850
+ const functions = [];
15851
+ this.cursor = open + 1;
15852
+ try {
15853
+ while (!this.done() && !this.at("}") && !this.at("when") && this.cursor < end) {
15854
+ const before = this.cursor;
15855
+ try {
15856
+ const member = this.parseMember("DialogueGroup", "class");
15857
+ if (member?.kind === "function") functions.push(member);
15858
+ } catch (error) {
15859
+ this.report(error);
15860
+ this.recoverMember();
15861
+ }
15862
+ if (this.cursor === before) this.cursor++;
15863
+ }
15864
+ } finally {
15865
+ this.cursor = end;
15866
+ }
15867
+ const openToken = this.tokens[open];
15868
+ return {
15869
+ constructor: {
15870
+ text: this.source.text.slice(
15871
+ this.tokens[start].start,
15872
+ openToken.start
15873
+ ),
15874
+ range: { start: initializer.range.start, end: openToken.range.start }
15875
+ },
15876
+ functions
15877
+ };
15878
+ }
15819
15879
  parseGenericParameters() {
15820
15880
  this.expect("<");
15821
15881
  const parameters = [];
@@ -20490,7 +20550,7 @@ function optionalTestConfig(value) {
20490
20550
  `"${NEO_CONFIG_FILE}" field "test.${unknown}" is not recognized.`
20491
20551
  );
20492
20552
  }
20493
- const stringArray2 = (field) => {
20553
+ const stringArray3 = (field) => {
20494
20554
  const entry = config[field];
20495
20555
  if (entry === void 0) return void 0;
20496
20556
  if (!Array.isArray(entry) || entry.some((item) => typeof item !== "string" || item.length === 0)) {
@@ -20510,8 +20570,8 @@ function optionalTestConfig(value) {
20510
20570
  }
20511
20571
  return entry;
20512
20572
  };
20513
- const include = stringArray2("include");
20514
- const exclude = stringArray2("exclude");
20573
+ const include = stringArray3("include");
20574
+ const exclude = stringArray3("exclude");
20515
20575
  const invalidInclude = include?.find(
20516
20576
  (pattern) => !pattern.endsWith(".spec.neo")
20517
20577
  );
@@ -22528,6 +22588,197 @@ var init_project_source_ignore = __esm({
22528
22588
  }
22529
22589
  });
22530
22590
 
22591
+ // ../packages/neoscript-language/src/dialogue-group-paths.ts
22592
+ var DialogueGroupPaths, EMPTY_OPTIONS, EMPTY_GROUPS;
22593
+ var init_dialogue_group_paths = __esm({
22594
+ "../packages/neoscript-language/src/dialogue-group-paths.ts"() {
22595
+ "use strict";
22596
+ init_generated_csharp_identifiers();
22597
+ DialogueGroupPaths = class {
22598
+ constructor(groups, priorities, defaultPriorityId) {
22599
+ this.defaultPriorityId = defaultPriorityId;
22600
+ for (const group of groups) {
22601
+ this.byId.set(group.id, group);
22602
+ this.bySymbol.set(group.symbol, group);
22603
+ const children = this.children.get(group.parentId) ?? /* @__PURE__ */ new Map();
22604
+ const name = generatedCSharpTypeName(group.name, "DialogueGroup");
22605
+ children.set(name, children.has(name) ? null : group);
22606
+ this.children.set(group.parentId, children);
22607
+ }
22608
+ for (const [id2, options] of priorities)
22609
+ this.priorities.set(
22610
+ id2,
22611
+ new Map(options.map((option) => [option.name, option]))
22612
+ );
22613
+ }
22614
+ defaultPriorityId;
22615
+ byId = /* @__PURE__ */ new Map();
22616
+ bySymbol = /* @__PURE__ */ new Map();
22617
+ children = /* @__PURE__ */ new Map();
22618
+ priorities = /* @__PURE__ */ new Map();
22619
+ group(path) {
22620
+ const first = path[0];
22621
+ if (!first) return void 0;
22622
+ let group = this.bySymbol.get(first) ?? this.children.get(null)?.get(first) ?? void 0;
22623
+ for (let i2 = 1; group && i2 < path.length; i2++)
22624
+ group = this.children.get(group.id)?.get(path[i2]) ?? void 0;
22625
+ return group;
22626
+ }
22627
+ priorityOptions(group) {
22628
+ return this.priorities.get(
22629
+ group.priorityGroupId ?? this.defaultPriorityId ?? ""
22630
+ ) ?? EMPTY_OPTIONS;
22631
+ }
22632
+ childGroups(group) {
22633
+ return this.children.get(group.id) ?? EMPTY_GROUPS;
22634
+ }
22635
+ failure(path) {
22636
+ if (!this.group(path.slice(0, 1)))
22637
+ return `Unknown dialogue group ${path[0] ?? ""}.`;
22638
+ const parentPath = path.slice(0, -1);
22639
+ const parent = this.group(parentPath);
22640
+ if (!parent) return `Unknown dialogue group ${parentPath.join(".")}.`;
22641
+ if (this.group(path) && this.priorityOptions(parent).has(path.at(-1)))
22642
+ return `Ambiguous dialogue group and priority option ${path.join(".")}. Use the group's local symbol or explicit references.`;
22643
+ return `Unknown priority option ${path.join(".")}.`;
22644
+ }
22645
+ resolve(path) {
22646
+ const group = this.group(path);
22647
+ const parent = path.length > 1 ? this.group(path.slice(0, -1)) : void 0;
22648
+ const option = parent && this.priorityOptions(parent).get(path.at(-1));
22649
+ if (group && option) return void 0;
22650
+ if (group) return { group, option: null };
22651
+ return parent && option ? { group: parent, option } : void 0;
22652
+ }
22653
+ };
22654
+ EMPTY_OPTIONS = /* @__PURE__ */ new Map();
22655
+ EMPTY_GROUPS = /* @__PURE__ */ new Map();
22656
+ }
22657
+ });
22658
+
22659
+ // ../packages/neoscript-language/src/project-source-dialogue-groups.ts
22660
+ function sourceDialogueGroups(source) {
22661
+ const cached = catalogs.get(source.documents);
22662
+ if (cached) return cached;
22663
+ const symbols = /* @__PURE__ */ new Map();
22664
+ const globals = /* @__PURE__ */ new Map();
22665
+ const options = /* @__PURE__ */ new Map();
22666
+ for (const symbol of source.symbols) {
22667
+ if (symbol.kind !== "global") continue;
22668
+ if (symbol.detail !== "DialogueGroup" && symbol.detail !== "PriorityGroup")
22669
+ continue;
22670
+ const id2 = symbol.id ?? `${symbol.location.uri}#${symbol.name}`;
22671
+ globals.set(symbol.name, id2);
22672
+ symbols.set(id2, symbol);
22673
+ }
22674
+ for (const symbol of source.symbols) {
22675
+ if (symbol.kind !== "graphChild" || symbol.detail !== "PriorityOption")
22676
+ continue;
22677
+ const owner = globals.get(symbol.ownerName ?? "");
22678
+ if (!owner) continue;
22679
+ const id2 = symbol.id ?? `${owner}.${symbol.name}`;
22680
+ symbols.set(id2, symbol);
22681
+ const entries = options.get(owner) ?? [];
22682
+ entries.push({ id: id2, name: symbol.name });
22683
+ options.set(owner, entries);
22684
+ }
22685
+ const groups = [];
22686
+ let defaultPriorityId = null;
22687
+ for (const document of source.documents.values()) {
22688
+ for (const declaration of document.declarations) {
22689
+ if (declaration.kind !== "global") continue;
22690
+ const type = declaration.type.name;
22691
+ if (type !== "DialogueGroup" && type !== "Project") continue;
22692
+ const args = constructorArgs(
22693
+ declaration.dialogueGroup?.constructor.text ?? declaration.initializer.text
22694
+ );
22695
+ if (type === "Project") {
22696
+ defaultPriorityId = referenceId(
22697
+ args.get("defaultPriorityGroup"),
22698
+ globals
22699
+ );
22700
+ continue;
22701
+ }
22702
+ const id2 = globals.get(declaration.name);
22703
+ if (!id2) continue;
22704
+ const name = args.get("name");
22705
+ groups.push({
22706
+ id: id2,
22707
+ symbol: declaration.name,
22708
+ name: name?.kind === "litString" ? name.value : declaration.name,
22709
+ parentId: referenceId(args.get("parent"), globals),
22710
+ priorityGroupId: referenceId(args.get("priorityGroup"), globals)
22711
+ });
22712
+ }
22713
+ }
22714
+ const result = {
22715
+ paths: new DialogueGroupPaths(groups, options, defaultPriorityId),
22716
+ symbols
22717
+ };
22718
+ catalogs.set(source.documents, result);
22719
+ return result;
22720
+ }
22721
+ function constructorArgs(text) {
22722
+ try {
22723
+ const expression = parseExpression(text);
22724
+ if (expression.kind !== "new") return /* @__PURE__ */ new Map();
22725
+ const args = /* @__PURE__ */ new Map();
22726
+ expression.args.forEach((arg, index) => {
22727
+ const name = expression.argumentNames?.[index];
22728
+ if (name) args.set(name, arg);
22729
+ });
22730
+ return args;
22731
+ } catch {
22732
+ return /* @__PURE__ */ new Map();
22733
+ }
22734
+ }
22735
+ function referenceId(expression, symbols) {
22736
+ if (expression?.kind === "ident") return symbols.get(expression.name) ?? null;
22737
+ if (expression?.kind === "call" && expression.callee.kind === "ident" && expression.callee.name === "Reference") {
22738
+ const id2 = expression.args[0];
22739
+ if (id2?.kind === "litString") return id2.value;
22740
+ }
22741
+ return null;
22742
+ }
22743
+ function validateDialogueGroupPaths(source) {
22744
+ const diagnostics = [];
22745
+ let catalog;
22746
+ for (const [uri, document] of source.documents) {
22747
+ for (const declaration of document.declarations) {
22748
+ if (declaration.kind !== "class") continue;
22749
+ for (const member of declaration.members) {
22750
+ if (member.kind !== "field" || member.type.name !== "Trigger") continue;
22751
+ const arg = member.flowInitializer?.arguments.find(
22752
+ (argument2) => argument2.name === "group"
22753
+ );
22754
+ if (!arg) continue;
22755
+ const path = arg.text.trim().split(/\s*\.\s*/u);
22756
+ if (path.length < 2 || path.some((segment) => !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(segment)))
22757
+ continue;
22758
+ catalog ??= sourceDialogueGroups(source);
22759
+ if (catalog.paths.resolve(path)) continue;
22760
+ diagnostics.push({
22761
+ uri,
22762
+ severity: "error",
22763
+ code: "neoflow-lowering",
22764
+ message: catalog.paths.failure(path),
22765
+ range: arg.valueRange ?? arg.range
22766
+ });
22767
+ }
22768
+ }
22769
+ }
22770
+ return diagnostics;
22771
+ }
22772
+ var catalogs;
22773
+ var init_project_source_dialogue_groups = __esm({
22774
+ "../packages/neoscript-language/src/project-source-dialogue-groups.ts"() {
22775
+ "use strict";
22776
+ init_dialogue_group_paths();
22777
+ init_executable_parser();
22778
+ catalogs = /* @__PURE__ */ new WeakMap();
22779
+ }
22780
+ });
22781
+
22531
22782
  // ../packages/neoscript-language/src/project-source-tokens.ts
22532
22783
  function rangeContains(range2, position) {
22533
22784
  return positionCompare(range2.start, position) <= 0 && positionCompare(position, range2.end) <= 0;
@@ -23195,7 +23446,7 @@ var init_project = __esm({
23195
23446
  });
23196
23447
 
23197
23448
  // ../packages/neoscript-language/src/source-map.ts
23198
- function createNeoScriptSourceMap(code, fileText, range2, source) {
23449
+ function createNeoScriptSourceMap(code, fileText, range2, source, thisAlias) {
23199
23450
  const text = typeof fileText === "string" ? new SourceText(fileText) : fileText;
23200
23451
  const start = text.offsetAt(range2.start);
23201
23452
  const end = text.offsetAt(range2.end);
@@ -23218,7 +23469,8 @@ function createNeoScriptSourceMap(code, fileText, range2, source) {
23218
23469
  for (let i2 = first; i2 < last; i2++) {
23219
23470
  const body = canonical[i2];
23220
23471
  const file = authored[i2 - first];
23221
- if (body.kind !== file.kind || body.raw !== file.raw) return void 0;
23472
+ if (body.kind !== file.kind || body.raw !== file.raw && !(body.kind === "identifier" && body.text === "this" && file.text === thisAlias))
23473
+ return void 0;
23222
23474
  const at3 = position(file.start);
23223
23475
  positions.push([
23224
23476
  body.range.start.line + 1,
@@ -26062,6 +26314,7 @@ var init_strict_resolver = __esm({
26062
26314
  tryMutationContexts = [];
26063
26315
  functionControlBoundaries = [];
26064
26316
  debugSource;
26317
+ inferredExpressionReturnType;
26065
26318
  initialScope() {
26066
26319
  const scope = new Scope(null, this.options.onFlowScope !== void 0);
26067
26320
  scope.define(
@@ -26266,6 +26519,23 @@ var init_strict_resolver = __esm({
26266
26519
  this.context.kind === "action" || this.context.kind === "setter" || this.context.kind === "constructor" || isVoid(this.context.returnType),
26267
26520
  describeUnitKind(this.context.kind)
26268
26521
  );
26522
+ if (this.options.inferExpressionReturnType) {
26523
+ if (this.context.kind !== "getter")
26524
+ throw new CompileError(
26525
+ "Expression inference requires a getter.",
26526
+ body.pos
26527
+ );
26528
+ if (statements.length !== 1)
26529
+ throw new CompileError(
26530
+ "Expression inference requires one return expression.",
26531
+ body.pos
26532
+ );
26533
+ if (statements[0]?.kind !== "return" || statements[0].expr === null)
26534
+ throw new CompileError(
26535
+ "Expression inference requires a returned value.",
26536
+ body.pos
26537
+ );
26538
+ }
26269
26539
  const instructions = this.resolveStatements(statements, scope);
26270
26540
  if ((this.context.kind === "function" || this.context.kind === "getter" || this.context.kind === "condition" || this.context.kind === "initializer") && !isVoid(this.context.returnType) && !instructionsTerminate(instructions)) {
26271
26541
  throw new CompileError(
@@ -26282,7 +26552,10 @@ var init_strict_resolver = __esm({
26282
26552
  source: this.debugSource,
26283
26553
  parameters,
26284
26554
  instructions,
26285
- typeInfo: toWireType(returnType, this.project)
26555
+ typeInfo: toWireType(
26556
+ this.inferredExpressionReturnType ?? returnType,
26557
+ this.project
26558
+ )
26286
26559
  };
26287
26560
  } finally {
26288
26561
  this.expectedReturnStack.pop();
@@ -27084,10 +27357,11 @@ var init_strict_resolver = __esm({
27084
27357
  }
27085
27358
  const inference = this.lambdaReturnInference.at(-1);
27086
27359
  const inferring = inference?.depth === this.lambdaDepth;
27360
+ const inferExpression = this.options.inferExpressionReturnType && this.lambdaDepth === 0;
27087
27361
  const value = this.resolveExpression(
27088
27362
  statement.expr,
27089
27363
  scope,
27090
- inferring ? void 0 : expected
27364
+ inferring || inferExpression ? void 0 : expected
27091
27365
  );
27092
27366
  if (inferring) {
27093
27367
  inference.returns.push({
@@ -27107,12 +27381,21 @@ var init_strict_resolver = __esm({
27107
27381
  statement.pos
27108
27382
  );
27109
27383
  }
27110
- this.requireAssignable(
27111
- value.type,
27112
- expected,
27113
- statement.expr.pos,
27114
- "return"
27115
- );
27384
+ if (inferExpression) {
27385
+ if (isVoid(value.type))
27386
+ throw new CompileError(
27387
+ "A text expression must return a value, not void.",
27388
+ statement.expr.pos
27389
+ );
27390
+ this.inferredExpressionReturnType = value.type;
27391
+ } else {
27392
+ this.requireAssignable(
27393
+ value.type,
27394
+ expected,
27395
+ statement.expr.pos,
27396
+ "return"
27397
+ );
27398
+ }
27116
27399
  return {
27117
27400
  type: "return" /* Return */,
27118
27401
  pointer: value.pointer
@@ -40091,6 +40374,14 @@ function referenceTypeAssignable(actual, expected, environment) {
40091
40374
  )
40092
40375
  );
40093
40376
  }
40377
+ const actualType = environment.projectIndex.typeByName.get(actual.name);
40378
+ const expectedType = environment.projectIndex.typeByName.get(expected.name);
40379
+ if (actualType && expectedType?.kind === "interface")
40380
+ return isNeoScriptTypeAssignable(
40381
+ { kind: "named", typeId: actualType.id },
40382
+ { kind: "named", typeId: expectedType.id },
40383
+ environment.projectIndex
40384
+ );
40094
40385
  return classExtends(actual.name, expected.name, environment, /* @__PURE__ */ new Set());
40095
40386
  }
40096
40387
  function classExtends(actual, expected, environment, visited) {
@@ -40637,7 +40928,8 @@ function compileNeoScriptStrict(document, context, options = {}) {
40637
40928
  {
40638
40929
  source: options.source,
40639
40930
  onFlowScope: options.onFlowScope,
40640
- sourceUri: document.uri
40931
+ sourceUri: document.uri,
40932
+ inferExpressionReturnType: options.inferExpressionReturnType
40641
40933
  }
40642
40934
  ).compile(ast);
40643
40935
  const ir = attachDependencyManifest(
@@ -40965,13 +41257,60 @@ function isPrimitiveName(name) {
40965
41257
  }
40966
41258
  function compileProjectSourceBodies(documents) {
40967
41259
  const graph = buildProjectGraph(documents);
40968
- const projectIndex = createProjectIndex(graph.project);
41260
+ const groupContexts = dialogueGroupContexts(documents, graph);
41261
+ const project = {
41262
+ ...graph.project,
41263
+ types: [
41264
+ ...graph.project.types,
41265
+ ...[...groupContexts.values()].map((group) => group.contextType)
41266
+ ]
41267
+ };
41268
+ const projectIndex = createProjectIndex(project);
40969
41269
  const bodies = [];
40970
41270
  const contexts = [];
40971
41271
  const diagnostics = [];
40972
41272
  for (const [uri, document] of documents) {
40973
41273
  if (document.kind !== "definition") continue;
40974
41274
  for (const declaration of document.declarations) {
41275
+ if (declaration.kind === "global") {
41276
+ const group = groupContexts.get(declaration);
41277
+ if (group) {
41278
+ for (const member of declaration.dialogueGroup?.functions ?? []) {
41279
+ if (!member.body) continue;
41280
+ const expression = member.body.expression;
41281
+ compileBody({
41282
+ uri,
41283
+ document,
41284
+ owner: { declaration },
41285
+ memberName: member.name,
41286
+ declarationRange: member.nameRange,
41287
+ memberId: sourceIdentity2(
41288
+ member.annotations,
41289
+ `dialogue-group:${uri}:${declaration.name}:${member.name}`
41290
+ ),
41291
+ unit: "function",
41292
+ range: expression?.range ?? innerBodyRange(document.sourceText, member.body.range),
41293
+ ...expression ? { bodyMode: "expression" } : {},
41294
+ context: {
41295
+ project,
41296
+ kind: "function",
41297
+ returnType: { kind: "primitive", name: "bool" },
41298
+ ...group.thisType ? { thisClass: group.thisType } : {},
41299
+ dialogueContextType: {
41300
+ kind: "named",
41301
+ typeId: group.contextType.id
41302
+ },
41303
+ functionName: member.name
41304
+ },
41305
+ projectIndex,
41306
+ bodies,
41307
+ contexts,
41308
+ diagnostics
41309
+ });
41310
+ }
41311
+ }
41312
+ continue;
41313
+ }
40975
41314
  if (declaration.kind !== "class") continue;
40976
41315
  const owner = graph.declarationsByName.get(declaration.name);
40977
41316
  if (!owner) continue;
@@ -41003,7 +41342,7 @@ function compileProjectSourceBodies(documents) {
41003
41342
  unit: "constructor",
41004
41343
  range: innerBodyRange(document.sourceText, constructor2.body.range),
41005
41344
  context: {
41006
- project: graph.project,
41345
+ project,
41007
41346
  declaringType,
41008
41347
  thisClass: declaringType,
41009
41348
  implicitMemberAccess: true,
@@ -41038,7 +41377,7 @@ function compileProjectSourceBodies(documents) {
41038
41377
  unit: "init",
41039
41378
  range: innerBodyRange(document.sourceText, initBlock.body.range),
41040
41379
  context: {
41041
- project: graph.project,
41380
+ project,
41042
41381
  declaringType,
41043
41382
  thisClass: declaringType,
41044
41383
  implicitMemberAccess: true,
@@ -41065,7 +41404,7 @@ function compileProjectSourceBodies(documents) {
41065
41404
  if (!info) continue;
41066
41405
  const staticMember = member.modifiers.includes("static");
41067
41406
  const baseContext2 = {
41068
- project: graph.project,
41407
+ project,
41069
41408
  declaringType,
41070
41409
  ...staticMember ? {} : { thisClass: declaringType },
41071
41410
  returnType: sourceTypeRef(member.type, owner, graph.typeIdsByName),
@@ -41134,7 +41473,78 @@ function compileProjectSourceBodies(documents) {
41134
41473
  }
41135
41474
  }
41136
41475
  }
41137
- return { project: graph.project, bodies, contexts, diagnostics };
41476
+ return { project, bodies, contexts, diagnostics };
41477
+ }
41478
+ function dialogueGroupContexts(documents, graph) {
41479
+ const result = /* @__PURE__ */ new Map();
41480
+ let index;
41481
+ let membersByType;
41482
+ const collectionMembersByType = () => membersByType ??= new Map(
41483
+ graph.project.types.map((type) => [
41484
+ type.name,
41485
+ new Map(type.members.map((member) => [member.name, member]))
41486
+ ])
41487
+ );
41488
+ for (const [uri, document] of documents) {
41489
+ for (const declaration of document.declarations) {
41490
+ if (declaration.kind !== "global" || !declaration.dialogueGroup) continue;
41491
+ let thisType;
41492
+ try {
41493
+ const constructor2 = parseExpression(
41494
+ declaration.dialogueGroup.constructor.text
41495
+ );
41496
+ if (constructor2.kind === "new") {
41497
+ const kind = constructor2.args[constructor2.argumentNames?.indexOf("kind") ?? -1];
41498
+ const collection = constructor2.args[constructor2.argumentNames?.indexOf("collection") ?? -1];
41499
+ if (kind?.kind === "contextualEnum" && kind.name === "Lookup") {
41500
+ let member;
41501
+ if (collection?.kind === "member" && collection.receiver.kind === "ident") {
41502
+ member = collectionMembersByType().get(collection.receiver.name)?.get(collection.name);
41503
+ } else if (collection?.kind === "call" && collection.callee.kind === "ident" && collection.callee.name === "Reference") {
41504
+ const id3 = collection.args[collection.argumentNames?.indexOf("id") ?? -1];
41505
+ if (id3?.kind === "litString")
41506
+ member = (index ??= createProjectIndex(
41507
+ graph.project
41508
+ )).symbolById.get(id3.value);
41509
+ }
41510
+ let entry;
41511
+ if (member?.type.kind === "list") entry = member.type.elementType;
41512
+ if (member?.type.kind === "dictionary")
41513
+ entry = member.type.valueType;
41514
+ if (entry?.kind === "named")
41515
+ thisType = { ...entry, nullable: false };
41516
+ }
41517
+ }
41518
+ } catch {
41519
+ }
41520
+ const id2 = `dialogue-context:${uri}:${declaration.name}`;
41521
+ result.set(declaration, {
41522
+ ...thisType ? { thisType } : {},
41523
+ contextType: {
41524
+ id: id2,
41525
+ name: "DialogueContext",
41526
+ kind: "synthetic",
41527
+ members: [
41528
+ {
41529
+ id: `${id2}:primary`,
41530
+ name: "primary",
41531
+ kind: "property",
41532
+ type: { kind: "primitive", name: "unknown" },
41533
+ writable: false
41534
+ },
41535
+ {
41536
+ id: `${id2}:trigger`,
41537
+ name: "trigger",
41538
+ kind: "property",
41539
+ type: thisType ?? { kind: "primitive", name: "null" },
41540
+ writable: false
41541
+ }
41542
+ ]
41543
+ }
41544
+ });
41545
+ }
41546
+ }
41547
+ return result;
41138
41548
  }
41139
41549
  function compileBody(args) {
41140
41550
  args.contexts.push({
@@ -41938,6 +42348,7 @@ var init_project_source_script_compiler = __esm({
41938
42348
  "use strict";
41939
42349
  init_project_source_settlement();
41940
42350
  init_debug_info();
42351
+ init_executable_parser();
41941
42352
  init_compiler();
41942
42353
  init_declared_constructors();
41943
42354
  init_language_spec();
@@ -44085,6 +44496,7 @@ function analyzeNeoProjectSources(inputs, parsedDocuments = /* @__PURE__ */ new
44085
44496
  }
44086
44497
  }
44087
44498
  validateSymbolUniqueness(symbols, diagnostics);
44499
+ diagnostics.push(...validateDialogueGroupPaths({ documents, symbols }));
44088
44500
  diagnostics.push(...validateLocalValueInitializers(documents));
44089
44501
  diagnostics.push(...validateVariantDeclarations(documents));
44090
44502
  validateSystemAnnotationAuthoring(documents, diagnostics);
@@ -44706,6 +45118,7 @@ var BUILTIN_TYPE_NAMES, SYSTEM_RECORD_ID_PREFIX2, RFC_4122_UUID, QUARANTINED_LEG
44706
45118
  var init_project_source_analysis = __esm({
44707
45119
  "../packages/neoscript-language/src/project-source-analysis.ts"() {
44708
45120
  "use strict";
45121
+ init_project_source_dialogue_groups();
44709
45122
  init_project_local_values();
44710
45123
  init_language_spec();
44711
45124
  init_pending_id();
@@ -44950,7 +45363,9 @@ function memberManifest(uri, member) {
44950
45363
  modifiers: member.modifiers,
44951
45364
  annotations: manifestAnnotations(member.annotations),
44952
45365
  initializer: member.kind === "field" ? member.initializer?.text ?? null : null,
45366
+ ...member.kind === "field" && member.initializer ? { initializerSource: { uri, range: member.initializer.range } } : {},
44953
45367
  body: member.kind === "field" ? null : member.body?.text ?? null,
45368
+ ...member.kind !== "field" && member.body ? { bodySource: { uri, range: member.body.range } } : {},
44954
45369
  parameters: member.kind === "function" ? member.parameters.map(
44955
45370
  (parameter4) => manifestParameter(uri, parameter4)
44956
45371
  ) : []
@@ -44988,7 +45403,7 @@ function dialogueManifest(uri, declaration) {
44988
45403
  graphType: member.type.name,
44989
45404
  destination: member.flowInitializer?.body?.destination?.name ?? null,
44990
45405
  initializer: member.initializer?.text ?? "",
44991
- arguments: flowArguments(member.flowInitializer?.arguments ?? []),
45406
+ arguments: flowArguments(uri, member.flowInitializer?.arguments ?? []),
44992
45407
  content: member.flowInitializer?.body?.kind === "block" ? dialogueContent(uri, member.flowInitializer.body.content) : null
44993
45408
  }))
44994
45409
  };
@@ -44996,18 +45411,20 @@ function dialogueManifest(uri, declaration) {
44996
45411
  function dialogueContent(uri, content) {
44997
45412
  return {
44998
45413
  prose: content.prose.map((entry) => entry.text),
45414
+ proseSources: content.prose.map((entry) => ({ uri, range: entry.range })),
44999
45415
  bindings: content.bindings.map((binding) => ({
45000
45416
  name: binding.name,
45001
45417
  type: binding.typeText,
45002
45418
  primary: binding.primary,
45003
- initializer: binding.initializer
45419
+ initializer: binding.initializer,
45420
+ source: { uri, range: binding.initializerRange }
45004
45421
  })),
45005
45422
  children: content.children.map((child2) => ({
45006
45423
  ...identity(uri, child2.range, child2.annotations),
45007
45424
  name: child2.name,
45008
45425
  graphType: child2.graphType,
45009
45426
  destination: child2.initializer.body?.destination?.name ?? null,
45010
- arguments: flowArguments(child2.initializer.arguments),
45427
+ arguments: flowArguments(uri, child2.initializer.arguments),
45011
45428
  content: child2.initializer.body?.kind === "block" ? dialogueContent(uri, child2.initializer.body.content) : null
45012
45429
  })),
45013
45430
  statements: content.statements.map((statement) => ({
@@ -45017,10 +45434,11 @@ function dialogueContent(uri, content) {
45017
45434
  }))
45018
45435
  };
45019
45436
  }
45020
- function flowArguments(argumentsValue) {
45437
+ function flowArguments(uri, argumentsValue) {
45021
45438
  return argumentsValue.map((argument2) => ({
45022
45439
  ...argument2.name ? { name: argument2.name } : {},
45023
- expression: argument2.text
45440
+ expression: argument2.text,
45441
+ source: { uri, range: argument2.valueRange ?? argument2.range }
45024
45442
  }));
45025
45443
  }
45026
45444
  function manifestType(type) {
@@ -45389,9 +45807,13 @@ function assertMember(value, path) {
45389
45807
  "body",
45390
45808
  "parameters"
45391
45809
  ],
45392
- ["docsText"]
45810
+ ["docsText", "bodySource", "initializerSource"]
45393
45811
  );
45394
45812
  assertIdentity(member, path);
45813
+ if (member.initializerSource !== void 0)
45814
+ assertLocation(member.initializerSource, `${path}.initializerSource`);
45815
+ if (member.bodySource !== void 0)
45816
+ assertLocation(member.bodySource, `${path}.bodySource`);
45395
45817
  string(member.name, `${path}.name`);
45396
45818
  assertOptionalDocsText(member.docsText, `${path}.docsText`);
45397
45819
  assertType(member.type, `${path}.type`);
@@ -45508,14 +45930,30 @@ function assertDialogue(value, path) {
45508
45930
  }
45509
45931
  function assertDialogueContent(value, path) {
45510
45932
  const content = record(value, path);
45511
- exactKeys(content, path, ["prose", "bindings", "children", "statements"]);
45933
+ exactKeysWithOptional(
45934
+ content,
45935
+ path,
45936
+ ["prose", "bindings", "children", "statements"],
45937
+ ["proseSources"]
45938
+ );
45939
+ if (content.proseSources !== void 0)
45940
+ array(content.proseSources, `${path}.proseSources`).forEach(
45941
+ (entry, index) => assertLocation(entry, `${path}.proseSources[${index}]`)
45942
+ );
45512
45943
  array(content.prose, `${path}.prose`).forEach(
45513
45944
  (entry, index) => string(entry, `${path}.prose[${index}]`)
45514
45945
  );
45515
45946
  array(content.bindings, `${path}.bindings`).forEach((entry, index) => {
45516
45947
  const bindingPath = `${path}.bindings[${index}]`;
45517
45948
  const binding = record(entry, bindingPath);
45518
- exactKeys(binding, bindingPath, ["name", "type", "primary", "initializer"]);
45949
+ exactKeysWithOptional(
45950
+ binding,
45951
+ bindingPath,
45952
+ ["name", "type", "primary", "initializer"],
45953
+ ["source"]
45954
+ );
45955
+ if (binding.source !== void 0)
45956
+ assertLocation(binding.source, `${bindingPath}.source`);
45519
45957
  string(binding.name, `${bindingPath}.name`);
45520
45958
  string(binding.type, `${bindingPath}.type`);
45521
45959
  if (typeof binding.primary !== "boolean") {
@@ -45573,11 +46011,12 @@ function assertFlowArguments(value, path) {
45573
46011
  exactKeys(
45574
46012
  argument2,
45575
46013
  argumentPath,
45576
- Object.hasOwn(argument2, "name") ? ["name", "expression"] : ["expression"]
46014
+ Object.hasOwn(argument2, "name") ? ["name", "expression", "source"] : ["expression", "source"]
45577
46015
  );
45578
46016
  if (argument2.name !== void 0)
45579
46017
  string(argument2.name, `${argumentPath}.name`);
45580
46018
  string(argument2.expression, `${argumentPath}.expression`);
46019
+ assertLocation(argument2.source, `${argumentPath}.source`);
45581
46020
  });
45582
46021
  }
45583
46022
  function assertType(value, path) {
@@ -45759,7 +46198,7 @@ var init_registry = __esm({
45759
46198
  "../packages/manifest/schema-contract/registry.mjs"() {
45760
46199
  "use strict";
45761
46200
  PROJECT_SCHEMA_CONTRACT = Object.freeze({
45762
- cliVersion: "0.71.1",
46201
+ cliVersion: "0.71.3",
45763
46202
  projectFileUploadBatchSize: 32,
45764
46203
  documentRecords: {
45765
46204
  member: {
@@ -47181,6 +47620,127 @@ var init_registry = __esm({
47181
47620
  }
47182
47621
  });
47183
47622
 
47623
+ // ../packages/manifest/src/value-comparison.ts
47624
+ function isObjectRecord2(value) {
47625
+ return typeof value === "object" && value !== null && !Array.isArray(value);
47626
+ }
47627
+ function splitRecordFields(data, serverOwnedFields) {
47628
+ const fileFields = {};
47629
+ const volatileValues = {};
47630
+ for (const [key, value] of Object.entries(data)) {
47631
+ if (value === void 0) continue;
47632
+ if (serverOwnedFields.includes(key)) {
47633
+ volatileValues[key] = value;
47634
+ } else {
47635
+ fileFields[key] = value;
47636
+ }
47637
+ }
47638
+ return { fileFields, volatileValues };
47639
+ }
47640
+ function canonicallyEqual(left, right) {
47641
+ return canonicalStringify(left) === canonicalStringify(right);
47642
+ }
47643
+ function canonicalStringify(value) {
47644
+ return JSON.stringify(toCanonical(value));
47645
+ }
47646
+ function toCanonical(value) {
47647
+ if (value === null || value === void 0) return value ?? null;
47648
+ if (Array.isArray(value)) return value.map((item) => toCanonical(item));
47649
+ if (typeof value === "object") {
47650
+ const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
47651
+ const result = {};
47652
+ for (const [key, entryValue] of entries) {
47653
+ result[key] = toCanonical(entryValue);
47654
+ }
47655
+ return result;
47656
+ }
47657
+ return value;
47658
+ }
47659
+ function isUuidV4Id(id2) {
47660
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(
47661
+ id2
47662
+ );
47663
+ }
47664
+ var init_value_comparison = __esm({
47665
+ "../packages/manifest/src/value-comparison.ts"() {
47666
+ "use strict";
47667
+ }
47668
+ });
47669
+
47670
+ // src/project-source/dialogue-group-symbols.ts
47671
+ function authoredDialogueGroupSymbols(analysis) {
47672
+ return new Map(
47673
+ analysis?.dialogueGroups.globals.filter((global) => global.type.name === "DialogueGroup").map((global) => [
47674
+ global.id ?? `__pending__:dialogue-group:${encodeURIComponent(global.source.uri)}:${global.source.range.start.line}:${global.source.range.start.character}:${encodeURIComponent(global.name)}`,
47675
+ global.name
47676
+ ])
47677
+ );
47678
+ }
47679
+ function emittedDialogueGroupSymbols(records2, local = /* @__PURE__ */ new Map(), reservedNames = []) {
47680
+ const result = /* @__PURE__ */ new Map();
47681
+ const used = /* @__PURE__ */ new Set([
47682
+ "project",
47683
+ "localization",
47684
+ "images",
47685
+ "audioclips",
47686
+ "root",
47687
+ "projectrelations"
47688
+ ]);
47689
+ for (const name of reservedNames) used.add(name.toLowerCase());
47690
+ const groups = [];
47691
+ const nextSuffix = /* @__PURE__ */ new Map();
47692
+ for (const record7 of records2.values()) {
47693
+ if (record7.deleted || !isObjectRecord2(record7.data)) continue;
47694
+ if (record7.recordKind === "dialogue-group") {
47695
+ groups.push(record7);
47696
+ continue;
47697
+ }
47698
+ const name = record7.recordKind === "dialogue" ? record7.data.sourceName : record7.data.name;
47699
+ if (GLOBAL_RECORD_KINDS.has(record7.recordKind) && typeof name === "string")
47700
+ used.add(name.toLowerCase());
47701
+ }
47702
+ for (const record7 of groups) {
47703
+ const symbol = local.get(record7.recordId);
47704
+ if (symbol && isValidNeoProjectIdentifier(symbol)) {
47705
+ if (used.has(symbol.toLowerCase()))
47706
+ throw new Error(`Duplicate local dialogue group symbol ${symbol}.`);
47707
+ result.set(record7.recordId, symbol);
47708
+ used.add(symbol.toLowerCase());
47709
+ }
47710
+ }
47711
+ for (const group of groups) {
47712
+ if (result.has(group.recordId) || !isObjectRecord2(group.data)) continue;
47713
+ const name = typeof group.data.name === "string" ? group.data.name : "DialogueGroup";
47714
+ const candidate = isValidNeoProjectIdentifier(name) ? name : generatedCSharpTypeName(name, "DialogueGroup");
47715
+ let symbol = candidate;
47716
+ let suffix = nextSuffix.get(candidate.toLowerCase()) ?? 2;
47717
+ while (used.has(symbol.toLowerCase()) || !isValidNeoProjectIdentifier(symbol))
47718
+ symbol = `${candidate}${suffix++}`;
47719
+ nextSuffix.set(candidate.toLowerCase(), suffix);
47720
+ used.add(symbol.toLowerCase());
47721
+ result.set(group.recordId, symbol);
47722
+ }
47723
+ return result;
47724
+ }
47725
+ var GLOBAL_RECORD_KINDS;
47726
+ var init_dialogue_group_symbols = __esm({
47727
+ "src/project-source/dialogue-group-symbols.ts"() {
47728
+ "use strict";
47729
+ init_value_comparison();
47730
+ init_project_source_identifiers();
47731
+ init_generated_csharp_identifiers();
47732
+ GLOBAL_RECORD_KINDS = /* @__PURE__ */ new Set([
47733
+ "class",
47734
+ "interface",
47735
+ "enum",
47736
+ "priority-group",
47737
+ "unity-texture-template",
47738
+ "unity-audio-clip-template",
47739
+ "dialogue"
47740
+ ]);
47741
+ }
47742
+ });
47743
+
47184
47744
  // src/project-sync/source-diagnostics.ts
47185
47745
  function isPullRecoveryDiagnosticCode(code) {
47186
47746
  return code !== void 0 && PULL_RECOVERY_DIAGNOSTIC_CODES.has(code);
@@ -47208,7 +47768,7 @@ var init_source_diagnostics = __esm({
47208
47768
  "neoflow-incomplete-draft"
47209
47769
  ]);
47210
47770
  SchemaSourceError = class extends Error {
47211
- constructor(detail, file, line, column, code, severity = "error") {
47771
+ constructor(detail, file, line, column, code, severity = "error", range2) {
47212
47772
  super(`${file}:${line}:${column} \u2014 ${detail}`);
47213
47773
  this.detail = detail;
47214
47774
  this.file = file;
@@ -47216,6 +47776,7 @@ var init_source_diagnostics = __esm({
47216
47776
  this.column = column;
47217
47777
  this.code = code;
47218
47778
  this.severity = severity;
47779
+ this.range = range2;
47219
47780
  this.name = "SchemaSourceError";
47220
47781
  }
47221
47782
  detail;
@@ -47224,6 +47785,7 @@ var init_source_diagnostics = __esm({
47224
47785
  column;
47225
47786
  code;
47226
47787
  severity;
47788
+ range;
47227
47789
  };
47228
47790
  }
47229
47791
  });
@@ -47352,53 +47914,6 @@ var init_names = __esm({
47352
47914
  }
47353
47915
  });
47354
47916
 
47355
- // ../packages/manifest/src/value-comparison.ts
47356
- function isObjectRecord2(value) {
47357
- return typeof value === "object" && value !== null && !Array.isArray(value);
47358
- }
47359
- function splitRecordFields(data, serverOwnedFields) {
47360
- const fileFields = {};
47361
- const volatileValues = {};
47362
- for (const [key, value] of Object.entries(data)) {
47363
- if (value === void 0) continue;
47364
- if (serverOwnedFields.includes(key)) {
47365
- volatileValues[key] = value;
47366
- } else {
47367
- fileFields[key] = value;
47368
- }
47369
- }
47370
- return { fileFields, volatileValues };
47371
- }
47372
- function canonicallyEqual(left, right) {
47373
- return canonicalStringify(left) === canonicalStringify(right);
47374
- }
47375
- function canonicalStringify(value) {
47376
- return JSON.stringify(toCanonical(value));
47377
- }
47378
- function toCanonical(value) {
47379
- if (value === null || value === void 0) return value ?? null;
47380
- if (Array.isArray(value)) return value.map((item) => toCanonical(item));
47381
- if (typeof value === "object") {
47382
- const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== void 0).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
47383
- const result = {};
47384
- for (const [key, entryValue] of entries) {
47385
- result[key] = toCanonical(entryValue);
47386
- }
47387
- return result;
47388
- }
47389
- return value;
47390
- }
47391
- function isUuidV4Id(id2) {
47392
- return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u.test(
47393
- id2
47394
- );
47395
- }
47396
- var init_value_comparison = __esm({
47397
- "../packages/manifest/src/value-comparison.ts"() {
47398
- "use strict";
47399
- }
47400
- });
47401
-
47402
47917
  // src/project-sync/migration-files.ts
47403
47918
  function migrationFileName(order, name) {
47404
47919
  const slug = sanitizeCsIdentifier(name).replace(/_/g, "-").toLowerCase();
@@ -57633,6 +58148,8 @@ function isDialogueLogicCompileTextVariableContext(value) {
57633
58148
  if (!isNSPointer(v.pointer)) return false;
57634
58149
  if (typeof v.sourcePath !== "string") return false;
57635
58150
  if (!isNSTypeInfo(v.typeInfo)) return false;
58151
+ if (v.sourceInline !== void 0 && typeof v.sourceInline !== "boolean")
58152
+ return false;
57636
58153
  if (typeof v.variableId !== "string") return false;
57637
58154
  return isOptionalNullableString2(v.optionId);
57638
58155
  }
@@ -61530,7 +62047,7 @@ function resolveQualifiedMemberId(context, expression) {
61530
62047
  const match = /^([A-Za-z_][A-Za-z0-9_]*)\.([A-Za-z_][A-Za-z0-9_]*)$/.exec(
61531
62048
  expression.trim()
61532
62049
  );
61533
- if (!match) return referenceId(expression);
62050
+ if (!match) return referenceId2(expression);
61534
62051
  const classId = context.classIdsByName.get(match[1]);
61535
62052
  if (!classId) return null;
61536
62053
  return effectiveMemberIdByName(context, classId, match[2]);
@@ -61661,7 +62178,7 @@ function templateSymbolArgument(context, settings, ownerClass, declaration) {
61661
62178
  }
61662
62179
  return templateId;
61663
62180
  }
61664
- function referenceId(raw) {
62181
+ function referenceId2(raw) {
61665
62182
  const parsed = parseReferenceArgument(raw);
61666
62183
  if (parsed === null || parsed.kind === "none") return null;
61667
62184
  return parsed.kind === "id" ? parsed.value : `${PENDING_ID_PREFIX}root-path:${parsed.value}`;
@@ -61825,7 +62342,7 @@ function lowerVariantDefault(context, expression, expected, path) {
61825
62342
  };
61826
62343
  }
61827
62344
  function lowerVariantBindingReference(context, expression, path) {
61828
- const id2 = referenceId(expressionSource(expression));
62345
+ const id2 = referenceId2(expressionSource(expression));
61829
62346
  if (id2 === null) {
61830
62347
  throw new Error(
61831
62348
  `${path}.Bind requires Reference(id: ...) or Reference(root....).`
@@ -62696,7 +63213,7 @@ function emitSupplementalProjectSourcesV4(records2, binaryPaths, options = {}) {
62696
63213
  const textureNames = namesById(live, "unity-texture-template");
62697
63214
  const audioNames = namesById(live, "unity-audio-clip-template");
62698
63215
  const priorityNames = namesById(live, "priority-group");
62699
- const dialogueNames = namesById(live, "dialogue-group");
63216
+ const dialogueNames = options.dialogueGroupSymbols ?? emittedDialogueGroupSymbols(records2);
62700
63217
  const uiLogicResolver = supplementalUILogicResolver(live);
62701
63218
  const files = [];
62702
63219
  const memberContext = {
@@ -62738,7 +63255,7 @@ function emitSupplementalProjectSourcesV4(records2, binaryPaths, options = {}) {
62738
63255
  (candidate) => candidate.recordKind === "dialogue-group"
62739
63256
  )) {
62740
63257
  const data = recordData(record7);
62741
- const name = requiredName2(data, record7);
63258
+ const name = dialogueNames.get(record7.recordId);
62742
63259
  files.push({
62743
63260
  path: defaultDeclarationPathV4("DialogueGroups", name, record7.recordId),
62744
63261
  content: emitDialogueGroup(
@@ -62882,6 +63399,8 @@ function emitDialogueGroup(data, recordId, name, priorityNames, dialogueNames, u
62882
63399
  assertProjectIdentifier2(name, "dialogue group");
62883
63400
  const kind = data.type === 1 ? "Lookup" : data.type === 2 ? "Folder" : "Standard";
62884
63401
  const args = [["kind", `.${kind}`]];
63402
+ if (data.name !== name && typeof data.name === "string")
63403
+ args.push(["name", quote2(data.name)]);
62885
63404
  const priority = reference(
62886
63405
  data.priorityGroupIdOverride,
62887
63406
  priorityNames,
@@ -63108,6 +63627,13 @@ function dialogueGroupType(name, args) {
63108
63627
  throw new Error(`Unknown dialogue group kind .${kind.name}.`);
63109
63628
  return type;
63110
63629
  }
63630
+ function dialogueGroupDisplayName(expression, symbol) {
63631
+ if (expression?.kind !== "litString" || expression.value.trim().length === 0)
63632
+ throw new Error(
63633
+ `DialogueGroup ${symbol} name must be a non-empty string literal.`
63634
+ );
63635
+ return expression.value;
63636
+ }
63111
63637
  function lowerDialogueGroup(baseValue, global, priorityIds, dialogueIds, uiLogicResolver, memberContext) {
63112
63638
  const base = optionalBase(baseValue);
63113
63639
  const baseWithoutLookup = { ...base };
@@ -63134,7 +63660,7 @@ function lowerDialogueGroup(baseValue, global, priorityIds, dialogueIds, uiLogic
63134
63660
  collectionMemberId = resolveOptionalReference(collection, /* @__PURE__ */ new Map());
63135
63661
  }
63136
63662
  const collectionValue = args.get("collectionValue");
63137
- const collectionValueId = collectionValue === void 0 || collectionValue.kind === "litNull" ? null : referenceId(collectionValue);
63663
+ const collectionValueId = collectionValue === void 0 || collectionValue.kind === "litNull" ? null : referenceId2(collectionValue);
63138
63664
  if (collectionValue !== void 0 && collectionValue.kind !== "litNull" && collectionValueId === null) {
63139
63665
  throw new Error(
63140
63666
  `Lookup dialogue group ${global.name} requires collectionValue: Reference(root.Assets.Member), Reference(id: ...), or null.`
@@ -63143,7 +63669,7 @@ function lowerDialogueGroup(baseValue, global, priorityIds, dialogueIds, uiLogic
63143
63669
  return {
63144
63670
  ...baseWithoutLookup,
63145
63671
  id: globalId(global, "dialogue-group"),
63146
- name: global.name,
63672
+ name: args.has("name") ? dialogueGroupDisplayName(args.get("name"), global.name) : global.name,
63147
63673
  type,
63148
63674
  parentDialogueGroupId: resolveOptionalReference(
63149
63675
  args.get("parent"),
@@ -63717,6 +64243,7 @@ var PRIORITY_OPTION_PATTERN;
63717
64243
  var init_supplemental_records = __esm({
63718
64244
  "src/project-source/supplemental-records.ts"() {
63719
64245
  "use strict";
64246
+ init_dialogue_group_symbols();
63720
64247
  init_source_diagnostics();
63721
64248
  init_project_source_identifiers();
63722
64249
  init_lexer();
@@ -63751,6 +64278,18 @@ function sourceNameTokens(value) {
63751
64278
  const ascii = value.normalize("NFKD").replace(new RegExp("\\p{Mark}", "gu"), "").replace(/[\u0027\u2019]/gu, "");
63752
64279
  return (ascii.match(/[A-Za-z0-9]+/gu) ?? []).map((token) => `${token[0]?.toUpperCase() ?? ""}${token.slice(1)}`).join("");
63753
64280
  }
64281
+ function isDefaultDialogueSourceName(value) {
64282
+ return /^(?:Dialogue|Node|Option|Outcome|Value)_[0-9a-f_]{8,}$/iu.test(value) || /^NeoFunction_[0-9a-f]{16,}$/iu.test(value) || /^(?:Actions?|Conditions?|Dialogue|Node|Option|Outcome|Text|TextValue|Value)[0-9]+(?:_[0-9]+)?$/iu.test(
64283
+ value
64284
+ );
64285
+ }
64286
+ function inferredDialogueDisplayName(sourceName, kind) {
64287
+ if (!isDefaultDialogueSourceName(sourceName)) return sourceName;
64288
+ const family = /^[A-Za-z]+/u.exec(sourceName)?.[0]?.toLowerCase();
64289
+ if (family === kind.toLowerCase()) return null;
64290
+ const bodyNode = kind === "Text" || kind === "Actions" || kind === "Conditions";
64291
+ return bodyNode && family === "node" ? null : sourceName;
64292
+ }
63754
64293
  var DialogueSourceNameAllocator;
63755
64294
  var init_dialogue_source_names = __esm({
63756
64295
  "../src/models/dialogue/dialogue-source-names.ts"() {
@@ -64010,11 +64549,6 @@ function keptSourceName(value) {
64010
64549
  if (!isDialogueSourceIdentifier(value)) return null;
64011
64550
  return isDefaultDialogueSourceName(value) ? null : value;
64012
64551
  }
64013
- function isDefaultDialogueSourceName(value) {
64014
- return /^(?:Dialogue|Node|Option|Outcome|Value)_[0-9a-f_]{8,}$/iu.test(value) || /^NeoFunction_[0-9a-f]{16,}$/iu.test(value) || /^(?:Actions?|Conditions?|Dialogue|Node|Option|Outcome|Text|TextValue|Value)[0-9]+(?:_[0-9]+)?$/iu.test(
64015
- value
64016
- );
64017
- }
64018
64552
  function linkedValueRecords(rawLinks, owner) {
64019
64553
  if (!Array.isArray(rawLinks)) return [];
64020
64554
  return rawLinks.map((rawLink, index) => {
@@ -64245,7 +64779,7 @@ function optionalMeaningfulString(value) {
64245
64779
  function recordKey(record7) {
64246
64780
  return `${record7.recordKind}:${record7.recordId}`;
64247
64781
  }
64248
- function emitDialogueProjectSourcesV4(records2) {
64782
+ function emitDialogueProjectSourcesV4(records2, groupSymbols) {
64249
64783
  const live = [...records2.values()].filter((record7) => !record7.deleted);
64250
64784
  const dialogues = live.filter((record7) => record7.recordKind === "dialogue");
64251
64785
  if (dialogues.length === 0) return [];
@@ -64262,10 +64796,22 @@ function emitDialogueProjectSourcesV4(records2) {
64262
64796
  );
64263
64797
  const mainLocale = localization ? optionalString2(recordData2(localization).mainLocale) ?? "en-US" : "en-US";
64264
64798
  const values = new ValuePlacementIndex(live);
64265
- const dialogueGroupNames = namesById2(live, "dialogue-group");
64799
+ const dialogueGroupNames = groupSymbols ?? emittedDialogueGroupSymbols(records2);
64266
64800
  const memberNames = validNamesById(live, "member");
64267
64801
  const staticMemberExpressions = staticMemberExpressionsById(live);
64268
64802
  const enumOptionNames2 = enumOptionNamesById(live);
64803
+ const groupChildNames = /* @__PURE__ */ new Map();
64804
+ for (const record7 of live) {
64805
+ if (record7.recordKind !== "dialogue-group") continue;
64806
+ const data = recordData2(record7);
64807
+ const parentId = optionalString2(data.parentDialogueGroupId);
64808
+ if (!parentId) continue;
64809
+ const names = groupChildNames.get(parentId) ?? /* @__PURE__ */ new Set();
64810
+ names.add(
64811
+ generatedCSharpTypeName(stringField(data, "name"), "DialogueGroup")
64812
+ );
64813
+ groupChildNames.set(parentId, names);
64814
+ }
64269
64815
  const priorityOptionNames = /* @__PURE__ */ new Map();
64270
64816
  for (const record7 of live.filter(
64271
64817
  (candidate) => candidate.recordKind === "priority-group"
@@ -64296,6 +64842,7 @@ function emitDialogueProjectSourcesV4(records2) {
64296
64842
  localizedTexts,
64297
64843
  mainLocale,
64298
64844
  dialogueGroupNames,
64845
+ groupChildNames,
64299
64846
  priorityOptionNames,
64300
64847
  memberNames,
64301
64848
  staticMemberExpressions,
@@ -64350,6 +64897,7 @@ function emitDialogueProjectSourcesV4(records2) {
64350
64897
  localizedTexts,
64351
64898
  mainLocale,
64352
64899
  dialogueGroupNames,
64900
+ groupChildNames,
64353
64901
  priorityOptionNames,
64354
64902
  memberNames,
64355
64903
  staticMemberExpressions,
@@ -64394,6 +64942,7 @@ function emitDialogue(args) {
64394
64942
  localizedTexts: args.localizedTexts,
64395
64943
  mainLocale: args.mainLocale,
64396
64944
  dialogueGroupNames: args.dialogueGroupNames,
64945
+ groupChildNames: args.groupChildNames,
64397
64946
  priorityOptionNames: args.priorityOptionNames,
64398
64947
  memberNames: args.memberNames,
64399
64948
  staticMemberExpressions: args.staticMemberExpressions,
@@ -64402,7 +64951,7 @@ function emitDialogue(args) {
64402
64951
  const localizedTextIds = /* @__PURE__ */ new Set();
64403
64952
  const settings = [];
64404
64953
  const displayName = optionalString2(args.dialogue.name);
64405
- if (displayName !== null) settings.push(["name", quote3(displayName)]);
64954
+ emitDisplayName(settings, displayName, args.className, "Dialogue");
64406
64955
  const descriptionId = optionalString2(args.dialogue.description);
64407
64956
  if (descriptionId) {
64408
64957
  settings.push([
@@ -64473,7 +65022,7 @@ function emitTrigger(context, node) {
64473
65022
  const optionId = optionalString2(priority.priorityOptionId);
64474
65023
  const groupName = groupId ? context.dialogueGroupNames.get(groupId) : void 0;
64475
65024
  const optionName = optionId ? context.priorityOptionNames.get(optionId) : void 0;
64476
- if (groupName && optionName)
65025
+ if (groupName && optionName && !context.groupChildNames.get(groupId)?.has(optionName))
64477
65026
  args.push(["group", `${groupName}.${optionName}`]);
64478
65027
  else if (groupId) {
64479
65028
  args.push(["group", `Reference<DialogueGroup>(id: ${quote3(groupId)})`]);
@@ -64511,8 +65060,7 @@ function emitTextNode(context, node) {
64511
65060
  const id2 = stringField(node, "id");
64512
65061
  const symbol = requiredMap(context.nodeNames, id2, "dialogue node");
64513
65062
  const args = [];
64514
- const name = optionalString2(node.name);
64515
- if (name) args.push(["name", quote3(name)]);
65063
+ emitDisplayName(args, optionalString2(node.name), symbol, "Text");
64516
65064
  const textId = optionalString2(node.text);
64517
65065
  const nodeBindings = allocateBindings(node.linkedValues, context.values);
64518
65066
  assertNoBindingShadow(context.bindings, nodeBindings);
@@ -64575,8 +65123,7 @@ ${lines.map((line) => indentNeoSource(line, 2)).join("\n\n")}
64575
65123
  function emitOption(context, option, symbol, nodeBindings, prosePrimaryAlias) {
64576
65124
  const id2 = stringField(option, "id");
64577
65125
  const args = [];
64578
- const name = optionalString2(option.name);
64579
- if (name) args.push(["name", quote3(name)]);
65126
+ emitDisplayName(args, optionalString2(option.name), symbol, "Option");
64580
65127
  const settings = isObjectRecord2(option.settings) ? option.settings : null;
64581
65128
  const visible = conditionUses(context, settings?.conditions);
64582
65129
  const selectable = conditionUses(context, settings?.selectableConditions);
@@ -64611,8 +65158,7 @@ function emitActionsNode(context, node) {
64611
65158
  const id2 = stringField(node, "id");
64612
65159
  const symbol = requiredMap(context.nodeNames, id2, "dialogue node");
64613
65160
  const args = [];
64614
- const name = optionalString2(node.name);
64615
- if (name) args.push(["name", quote3(name)]);
65161
+ emitDisplayName(args, optionalString2(node.name), symbol, "Actions");
64616
65162
  const actions = Array.isArray(node.actions) ? node.actions : [];
64617
65163
  const lines = [];
64618
65164
  const nodeBindings = allocateBindings(node.linkedValues, context.values);
@@ -64689,8 +65235,7 @@ function emitConditionsNode(context, node) {
64689
65235
  const id2 = stringField(node, "id");
64690
65236
  const symbol = requiredMap(context.nodeNames, id2, "dialogue node");
64691
65237
  const args = [];
64692
- const name = optionalString2(node.name);
64693
- if (name) args.push(["name", quote3(name)]);
65238
+ emitDisplayName(args, optionalString2(node.name), symbol, "Conditions");
64694
65239
  const lines = emitNodeBindings(context, node);
64695
65240
  const outcomes = Array.isArray(node.outcomes) ? node.outcomes : [];
64696
65241
  const names = new UniqueNames();
@@ -64700,10 +65245,12 @@ function emitConditionsNode(context, node) {
64700
65245
  const outcomeName = names.claim(sourceIdentifier(raw, "sourceName"));
64701
65246
  const uses = conditionUses(context, raw.conditions);
64702
65247
  const outcomeArgs = uses.length > 0 ? [["when", emitUseList(uses)]] : [];
64703
- const outcomeDisplayName = optionalString2(raw.name);
64704
- if (outcomeDisplayName !== null && outcomeDisplayName !== outcomeName) {
64705
- outcomeArgs.unshift(["name", quote3(outcomeDisplayName)]);
64706
- }
65248
+ emitDisplayName(
65249
+ outcomeArgs,
65250
+ optionalString2(raw.name),
65251
+ outcomeName,
65252
+ "Outcome"
65253
+ );
64707
65254
  const destination = destinationName(
64708
65255
  context,
64709
65256
  raw.toNodeId,
@@ -65038,14 +65585,6 @@ function allocateBindings(rawLinks, placements) {
65038
65585
  });
65039
65586
  return result;
65040
65587
  }
65041
- function namesById2(records2, kind) {
65042
- return new Map(
65043
- records2.filter((record7) => record7.recordKind === kind).map((record7) => [
65044
- record7.recordId,
65045
- sourceIdentifier(recordData2(record7), "name")
65046
- ])
65047
- );
65048
- }
65049
65588
  function validNamesById(records2, kind) {
65050
65589
  return new Map(
65051
65590
  records2.flatMap((record7) => {
@@ -65171,10 +65710,19 @@ function requiredMap(map, id2, label) {
65171
65710
  function quote3(value) {
65172
65711
  return quoteNeoString(value);
65173
65712
  }
65713
+ function emitDisplayName(args, name, symbol, kind) {
65714
+ const empty2 = kind === "Dialogue" || kind === "Outcome" ? "" : null;
65715
+ const stored = name ?? empty2;
65716
+ const inferred = inferredDialogueDisplayName(symbol, kind) ?? empty2;
65717
+ if (stored !== inferred)
65718
+ args.unshift(["name", stored === null ? "null" : quote3(stored)]);
65719
+ }
65174
65720
  var PERSISTED_VARIABLE_PATH, DIALOGUE_SYSTEM_TYPE_NAMES, ValuePlacementIndex, UniqueNames;
65175
65721
  var init_dialogue_sources = __esm({
65176
65722
  "src/project-source/dialogue-sources.ts"() {
65177
65723
  "use strict";
65724
+ init_generated_csharp_identifiers();
65725
+ init_dialogue_group_symbols();
65178
65726
  init_language_spec();
65179
65727
  init_dialogue_source_names();
65180
65728
  init_dialogue_source_identifiers();
@@ -65451,6 +65999,898 @@ var init_dialogue_sources = __esm({
65451
65999
  }
65452
66000
  });
65453
66001
 
66002
+ // ../src/models/classes/constructor-parameter-settlement.ts
66003
+ function createConstructorSettlementResolver(view) {
66004
+ const classesById = new Map(
66005
+ view.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
66006
+ );
66007
+ const membersById = new Map(
66008
+ view.members.map((member) => [member.id, member])
66009
+ );
66010
+ const constructorsById = new Map(
66011
+ (view.constructors ?? []).map((constructor2) => [
66012
+ constructor2.id,
66013
+ constructor2
66014
+ ])
66015
+ );
66016
+ const directResultByClassAndParameter = /* @__PURE__ */ new Map();
66017
+ const recordedResultByConstructorAndParameter = /* @__PURE__ */ new Map();
66018
+ const directSettlement = (classId, parameterName) => {
66019
+ const cacheKey = `${classId}\0${parameterName}`;
66020
+ if (directResultByClassAndParameter.has(cacheKey)) {
66021
+ return directResultByClassAndParameter.get(cacheKey) ?? null;
66022
+ }
66023
+ const visited = /* @__PURE__ */ new Set();
66024
+ let currentId = classId;
66025
+ while (currentId !== null && !visited.has(currentId)) {
66026
+ visited.add(currentId);
66027
+ const schemaClass2 = classesById.get(currentId);
66028
+ if (schemaClass2 === void 0) break;
66029
+ for (const [schemaKey, memberId] of Object.entries(
66030
+ schemaClass2.schema ?? {}
66031
+ )) {
66032
+ if (typeof memberId !== "string") continue;
66033
+ const member = membersById.get(memberId);
66034
+ const defaultRecord = asRecord(member?.defaultValue);
66035
+ const initRecord = asRecord(defaultRecord?.init);
66036
+ if (initRecord !== null && typeof initRecord.code === "string" && initRecord.code.trim() === parameterName) {
66037
+ const result = { schemaKey, memberId };
66038
+ directResultByClassAndParameter.set(cacheKey, result);
66039
+ return result;
66040
+ }
66041
+ }
66042
+ currentId = schemaClass2.extendsClassId ?? null;
66043
+ }
66044
+ directResultByClassAndParameter.set(cacheKey, null);
66045
+ return null;
66046
+ };
66047
+ const memberIdForSchemaKey = (classId, schemaKey) => {
66048
+ const visited = /* @__PURE__ */ new Set();
66049
+ let currentId = classId;
66050
+ while (currentId !== null && !visited.has(currentId)) {
66051
+ visited.add(currentId);
66052
+ const schemaClass2 = classesById.get(currentId);
66053
+ if (schemaClass2 === void 0) return null;
66054
+ const memberId = schemaClass2.schema?.[schemaKey];
66055
+ if (typeof memberId === "string") return memberId;
66056
+ currentId = schemaClass2.extendsClassId ?? null;
66057
+ }
66058
+ return null;
66059
+ };
66060
+ const recordedSettlement = (classId, parameterName, constructorId, resolving) => {
66061
+ const cacheKey = `${classId}\0${constructorId}\0${parameterName}`;
66062
+ if (recordedResultByConstructorAndParameter.has(cacheKey)) {
66063
+ return recordedResultByConstructorAndParameter.get(cacheKey) ?? null;
66064
+ }
66065
+ if (resolving.has(cacheKey)) return null;
66066
+ const constructor2 = constructorsById.get(constructorId);
66067
+ if (constructor2?.classId !== classId) {
66068
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
66069
+ return null;
66070
+ }
66071
+ const direct = directSettlement(classId, parameterName);
66072
+ if (direct !== null) {
66073
+ recordedResultByConstructorAndParameter.set(cacheKey, direct);
66074
+ return direct;
66075
+ }
66076
+ const schemaClass2 = classesById.get(classId);
66077
+ const baseClassId = schemaClass2?.extendsClassId;
66078
+ if (typeof baseClassId !== "string") {
66079
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
66080
+ return null;
66081
+ }
66082
+ for (const field of constructor2.baseInitializerFields ?? []) {
66083
+ const record7 = asRecord(field);
66084
+ if (typeof record7?.name !== "string" || typeof record7.code !== "string" || record7.code.trim() !== parameterName) {
66085
+ continue;
66086
+ }
66087
+ const memberId = memberIdForSchemaKey(baseClassId, record7.name);
66088
+ if (memberId !== null) {
66089
+ const result = { schemaKey: record7.name, memberId };
66090
+ recordedResultByConstructorAndParameter.set(cacheKey, result);
66091
+ return result;
66092
+ }
66093
+ }
66094
+ const baseConstructorId = classesById.get(baseClassId)?.requiredConstructorId;
66095
+ if (typeof baseConstructorId !== "string") {
66096
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
66097
+ return null;
66098
+ }
66099
+ resolving.add(cacheKey);
66100
+ for (const argument2 of constructor2.baseArguments ?? []) {
66101
+ const record7 = asRecord(argument2);
66102
+ if (typeof record7?.name !== "string" || typeof record7.code !== "string" || record7.code.trim() !== parameterName) {
66103
+ continue;
66104
+ }
66105
+ const result = recordedSettlement(
66106
+ baseClassId,
66107
+ record7.name,
66108
+ baseConstructorId,
66109
+ resolving
66110
+ );
66111
+ resolving.delete(cacheKey);
66112
+ recordedResultByConstructorAndParameter.set(cacheKey, result);
66113
+ return result;
66114
+ }
66115
+ resolving.delete(cacheKey);
66116
+ recordedResultByConstructorAndParameter.set(cacheKey, null);
66117
+ return null;
66118
+ };
66119
+ return (classId, parameterName, constructorId) => constructorId === void 0 ? directSettlement(classId, parameterName) : recordedSettlement(classId, parameterName, constructorId, /* @__PURE__ */ new Set());
66120
+ }
66121
+ function constructorSettledSchemaEntry(view, classId, parameterName, constructorId) {
66122
+ return createConstructorSettlementResolver(view)(
66123
+ classId,
66124
+ parameterName,
66125
+ constructorId
66126
+ );
66127
+ }
66128
+ function asRecord(value) {
66129
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
66130
+ return null;
66131
+ }
66132
+ return value;
66133
+ }
66134
+ var init_constructor_parameter_settlement = __esm({
66135
+ "../src/models/classes/constructor-parameter-settlement.ts"() {
66136
+ "use strict";
66137
+ }
66138
+ });
66139
+
66140
+ // ../src/database/neo-script-derived-bodies.ts
66141
+ function cloneAndStripClientDerivedBodies(change) {
66142
+ if (change.operation === "delete" || change.nextData === void 0) {
66143
+ return { ...change };
66144
+ }
66145
+ return {
66146
+ ...change,
66147
+ nextData: stripClientDerivedBodies(change.recordKind, change.nextData)
66148
+ };
66149
+ }
66150
+ function stripClientDerivedBodies(recordKind, nextData) {
66151
+ const record7 = asRecord2(nextData);
66152
+ return record7 === null ? nextData : strippedClone(recordKind, record7);
66153
+ }
66154
+ function hasPendingNeoScriptDerivation(recordKind, data) {
66155
+ const record7 = asRecord2(data);
66156
+ if (record7 === null) return false;
66157
+ return collectDerivedBodySites(recordKind, record7).some(
66158
+ (site) => site.authored && !(site.key in site.container)
66159
+ );
66160
+ }
66161
+ function strippedClone(recordKind, record7) {
66162
+ const next = structuredClone(record7);
66163
+ const container = asRecord2(next);
66164
+ if (container === null) return next;
66165
+ for (const site of collectDerivedBodySites(recordKind, container)) {
66166
+ delete site.container[site.key];
66167
+ }
66168
+ return next;
66169
+ }
66170
+ function collectDerivedBodySites(recordKind, record7) {
66171
+ const sites = [];
66172
+ if (recordKind === "migration") {
66173
+ sites.push({
66174
+ container: record7,
66175
+ key: "action",
66176
+ authored: typeof record7.code === "string"
66177
+ });
66178
+ return sites;
66179
+ }
66180
+ if (recordKind === "dialogue-group") {
66181
+ collectConditionSites(record7.conditions, sites);
66182
+ return sites;
66183
+ }
66184
+ if (recordKind === "dialogue-node") {
66185
+ collectDialogueNodeSites(record7, sites);
66186
+ return sites;
66187
+ }
66188
+ if (recordKind === "constructor") {
66189
+ sites.push({ container: record7, key: "action", authored: true });
66190
+ sites.push({
66191
+ container: record7,
66192
+ key: "compiledBaseArguments",
66193
+ authored: false
66194
+ });
66195
+ sites.push({
66196
+ container: record7,
66197
+ key: "compiledBaseInitializerFields",
66198
+ authored: false
66199
+ });
66200
+ return sites;
66201
+ }
66202
+ if (recordKind === "value") {
66203
+ collectValueBodySites(record7, sites);
66204
+ return sites;
66205
+ }
66206
+ if (recordKind !== "member") return sites;
66207
+ if (record7.kind === 10 /* NSProperty */) {
66208
+ sites.push({
66209
+ container: record7,
66210
+ key: "getter",
66211
+ authored: typeof record7.code === "string"
66212
+ });
66213
+ sites.push({
66214
+ container: record7,
66215
+ key: "setter",
66216
+ authored: typeof record7.setterCode === "string"
66217
+ });
66218
+ }
66219
+ if (record7.kind === 23 /* NSFunction */) {
66220
+ sites.push({
66221
+ container: record7,
66222
+ key: "action",
66223
+ authored: typeof record7.code === "string"
66224
+ });
66225
+ }
66226
+ if (record7.kind === 25 /* NSDelegate */) {
66227
+ collectDelegateClosureSite(asRecord2(record7.defaultValue), sites, false);
66228
+ }
66229
+ collectInitializerSite(asRecord2(record7.defaultValue), sites);
66230
+ return sites;
66231
+ }
66232
+ function collectValueBodySites(record7, sites) {
66233
+ collectInitializerSite(record7, sites);
66234
+ collectDelegateClosureSite(record7, sites, true);
66235
+ collectInlineDelegateArgumentSites(record7, sites);
66236
+ for (const container of [record7.value, record7.constructorArgs]) {
66237
+ if (container === null || typeof container !== "object") continue;
66238
+ for (const candidate of Object.values(container)) {
66239
+ if (!isPackedValueEnvelope(candidate)) continue;
66240
+ const child2 = asRecord2(candidate[PACKED_VALUE_ENTRY_KEY]);
66241
+ if (child2 !== null) collectValueBodySites(child2, sites);
66242
+ }
66243
+ }
66244
+ }
66245
+ function collectDialogueNodeSites(node, sites) {
66246
+ collectConditionSites(node.conditions, sites);
66247
+ collectTextVariableSites(node.variables, sites);
66248
+ if (Array.isArray(node.actions)) {
66249
+ for (const actionValue2 of node.actions) {
66250
+ const logic = asRecord2(asRecord2(actionValue2)?.logic);
66251
+ if (logic === null) continue;
66252
+ if (logic.type !== 1 /* Code */) continue;
66253
+ if (typeof logic.code !== "string") continue;
66254
+ sites.push({ container: logic, key: "action", authored: true });
66255
+ }
66256
+ }
66257
+ if (Array.isArray(node.outcomes)) {
66258
+ for (const outcomeValue of node.outcomes) {
66259
+ collectConditionSites(asRecord2(outcomeValue)?.conditions, sites);
66260
+ }
66261
+ }
66262
+ const options = asRecord2(node.optionSettings)?.options;
66263
+ if (!Array.isArray(options)) return;
66264
+ for (const optionValue of options) {
66265
+ const option = asRecord2(optionValue);
66266
+ if (option === null) continue;
66267
+ collectTextVariableSites(option.variables, sites);
66268
+ const settings = asRecord2(option.settings);
66269
+ if (settings === null) continue;
66270
+ collectConditionSites(settings.conditions, sites);
66271
+ collectConditionSites(settings.selectableConditions, sites);
66272
+ }
66273
+ }
66274
+ function collectConditionSites(value, sites) {
66275
+ if (!Array.isArray(value)) return;
66276
+ for (const conditionValue of value) {
66277
+ const condition = asRecord2(conditionValue);
66278
+ if (condition === null) continue;
66279
+ if (condition.type !== 1 /* Code */) continue;
66280
+ if (typeof condition.code !== "string") continue;
66281
+ sites.push({ container: condition, key: "getter", authored: true });
66282
+ }
66283
+ }
66284
+ function collectTextVariableSites(value, sites) {
66285
+ const variables = asRecord2(value);
66286
+ if (variables === null) return;
66287
+ for (const variableValue of Object.values(variables)) {
66288
+ const variable2 = asRecord2(variableValue);
66289
+ if (variable2 === null) continue;
66290
+ sites.push({ container: variable2, key: "getter", authored: true });
66291
+ }
66292
+ }
66293
+ function collectDelegateClosureSite(container, sites, authored) {
66294
+ const delegate = asRecord2(container?.value);
66295
+ if (delegate === null) return;
66296
+ if (typeof delegate.code !== "string") return;
66297
+ sites.push({ container: delegate, key: "action", authored });
66298
+ }
66299
+ function collectInlineDelegateArgumentSites(record7, sites) {
66300
+ const constructorArgs2 = asRecord2(record7.constructorArgs);
66301
+ if (constructorArgs2 === null) return;
66302
+ for (const argument2 of Object.values(constructorArgs2)) {
66303
+ const closure = asRecord2(argument2);
66304
+ if (closure === null) continue;
66305
+ if (typeof closure.code !== "string") continue;
66306
+ sites.push({ container: closure, key: "action", authored: true });
66307
+ }
66308
+ }
66309
+ function collectInitializerSite(container, sites) {
66310
+ const init = asRecord2(container?.init);
66311
+ if (init === null) return;
66312
+ sites.push({ container: init, key: "compiled", authored: true });
66313
+ }
66314
+ function stripDerivedBodies(member) {
66315
+ return strippedClone("member", member);
66316
+ }
66317
+ function stripConstructorDerivedBodies(constructorRecord) {
66318
+ return strippedClone("constructor", constructorRecord);
66319
+ }
66320
+ function stripMigrationAction(migration) {
66321
+ return strippedClone("migration", migration);
66322
+ }
66323
+ function stampUILogicBody(logic, bodyKey) {
66324
+ if (logic?.type !== 0 /* UI */) return false;
66325
+ const body = asRecord2(logic[bodyKey]);
66326
+ if (body === null) return false;
66327
+ if (body.compilerRevision === NEOSCRIPT_COMPILER_REVISION) return false;
66328
+ body.compilerRevision = NEOSCRIPT_COMPILER_REVISION;
66329
+ return true;
66330
+ }
66331
+ function stampUILogicBodies(recordKind, data) {
66332
+ const record7 = asRecord2(data);
66333
+ if (record7 === null) return false;
66334
+ if (recordKind === "dialogue-group") {
66335
+ return stampConditionList(record7.conditions);
66336
+ }
66337
+ if (recordKind !== "dialogue-node") return false;
66338
+ let changed = stampConditionList(record7.conditions);
66339
+ if (Array.isArray(record7.actions)) {
66340
+ for (const actionValue2 of record7.actions) {
66341
+ const logic = asRecord2(asRecord2(actionValue2)?.logic);
66342
+ changed = stampUILogicBody(logic, "action") || changed;
66343
+ }
66344
+ }
66345
+ if (Array.isArray(record7.outcomes)) {
66346
+ for (const outcomeValue of record7.outcomes) {
66347
+ changed = stampConditionList(asRecord2(outcomeValue)?.conditions) || changed;
66348
+ }
66349
+ }
66350
+ const options = asRecord2(record7.optionSettings)?.options;
66351
+ if (Array.isArray(options)) {
66352
+ for (const optionValue of options) {
66353
+ const settings = asRecord2(asRecord2(optionValue)?.settings);
66354
+ if (settings === null) continue;
66355
+ changed = stampConditionList(settings.conditions) || changed;
66356
+ changed = stampConditionList(settings.selectableConditions) || changed;
66357
+ }
66358
+ }
66359
+ return changed;
66360
+ }
66361
+ function stampConditionList(value) {
66362
+ if (!Array.isArray(value)) return false;
66363
+ let changed = false;
66364
+ for (const conditionValue of value) {
66365
+ changed = stampUILogicBody(asRecord2(conditionValue), "getter") || changed;
66366
+ }
66367
+ return changed;
66368
+ }
66369
+ function asRecord2(value) {
66370
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
66371
+ return null;
66372
+ }
66373
+ return value;
66374
+ }
66375
+ var init_neo_script_derived_bodies = __esm({
66376
+ "../src/database/neo-script-derived-bodies.ts"() {
66377
+ "use strict";
66378
+ init_members();
66379
+ init_logic_types();
66380
+ init_strict_ir();
66381
+ init_packed_value_encoding();
66382
+ }
66383
+ });
66384
+
66385
+ // src/project-source/stored-value-placements.ts
66386
+ function storedValueRowsByIdV4(records2) {
66387
+ const stored = /* @__PURE__ */ new Map();
66388
+ let packed = false;
66389
+ for (const record7 of records2) {
66390
+ if (record7.deleted === true) continue;
66391
+ if (record7.recordKind !== "value") continue;
66392
+ if (!isObjectRecord2(record7.data)) continue;
66393
+ stored.set(record7.recordId, record7.data);
66394
+ packed ||= rowCarriesPackedValueContent(record7.data);
66395
+ }
66396
+ if (!packed) return stored;
66397
+ const logical = /* @__PURE__ */ new Map();
66398
+ for (const [valueId, row] of stored) {
66399
+ if (!rowCarriesPackedValueContent(row)) {
66400
+ logical.set(valueId, row);
66401
+ continue;
66402
+ }
66403
+ const authoredRow = stripClientDerivedBodies("value", row);
66404
+ if (!isMemberValue(authoredRow)) {
66405
+ throw new PackedValueEncodingError(
66406
+ `Stored value row "${valueId}" packs a child but is not a well-formed value row, so its packed payload cannot be expanded.`
66407
+ );
66408
+ }
66409
+ const decoded = decodePackedValueRow(authoredRow);
66410
+ logical.set(valueId, { ...decoded.row });
66411
+ for (const child2 of decoded.children) {
66412
+ logical.set(child2.id, { ...child2 });
66413
+ }
66414
+ }
66415
+ return logical;
66416
+ }
66417
+ function buildStoredValuePlacementIndexV4(records2, logicalValues) {
66418
+ const live = [...records2].filter((record7) => record7.deleted !== true);
66419
+ const values = logicalValues ?? storedValueRowsByIdV4(live);
66420
+ const classes = [];
66421
+ const members = [];
66422
+ const memberDataById = /* @__PURE__ */ new Map();
66423
+ const constructors = /* @__PURE__ */ new Map();
66424
+ const variantTargetClassByRootValueId = /* @__PURE__ */ new Map();
66425
+ for (const record7 of live) {
66426
+ if (!isObjectRecord2(record7.data)) continue;
66427
+ if (record7.recordKind === "value") continue;
66428
+ if (record7.recordKind === "class") {
66429
+ classes.push({
66430
+ id: record7.recordId,
66431
+ ...isStringRecord3(record7.data.schema) ? { schema: record7.data.schema } : {},
66432
+ ...typeof record7.data.extendsClassId === "string" || record7.data.extendsClassId === null ? { extendsClassId: record7.data.extendsClassId } : {},
66433
+ ...typeof record7.data.requiredConstructorId === "string" ? { requiredConstructorId: record7.data.requiredConstructorId } : {},
66434
+ ...Array.isArray(record7.data.genericParams) ? {
66435
+ genericParamIds: record7.data.genericParams.flatMap(
66436
+ (entry) => isObjectRecord2(entry) && typeof entry.id === "string" ? [entry.id] : []
66437
+ )
66438
+ } : {}
66439
+ });
66440
+ } else if (record7.recordKind === "member") {
66441
+ memberDataById.set(record7.recordId, record7.data);
66442
+ members.push({
66443
+ id: record7.recordId,
66444
+ ...record7.data.defaultValue === void 0 ? {} : { defaultValue: record7.data.defaultValue }
66445
+ });
66446
+ } else if (record7.recordKind === "constructor") {
66447
+ constructors.set(record7.recordId, record7.data);
66448
+ } else if (record7.recordKind === "variant" && typeof record7.data.valueId === "string" && typeof record7.data.classId === "string") {
66449
+ variantTargetClassByRootValueId.set(
66450
+ record7.data.valueId,
66451
+ record7.data.classId
66452
+ );
66453
+ }
66454
+ }
66455
+ const classesById = new Map(
66456
+ classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
66457
+ );
66458
+ const resolveSettlement = createConstructorSettlementResolver({
66459
+ classes,
66460
+ constructors: [...constructors].flatMap(
66461
+ ([id2, constructor2]) => typeof constructor2.classId === "string" ? [
66462
+ {
66463
+ id: id2,
66464
+ classId: constructor2.classId,
66465
+ ...Array.isArray(constructor2.baseArguments) ? { baseArguments: constructor2.baseArguments } : {},
66466
+ ...Array.isArray(constructor2.baseInitializerFields) ? {
66467
+ baseInitializerFields: constructor2.baseInitializerFields
66468
+ } : {}
66469
+ }
66470
+ ] : []
66471
+ ),
66472
+ members
66473
+ });
66474
+ const memberIdForSchemaKey = (classId, schemaKey) => {
66475
+ const visited = /* @__PURE__ */ new Set();
66476
+ let cursor = classId;
66477
+ while (cursor !== null && !visited.has(cursor)) {
66478
+ visited.add(cursor);
66479
+ const schemaClass2 = classesById.get(cursor);
66480
+ if (schemaClass2 === void 0) return null;
66481
+ const memberId = schemaClass2.schema?.[schemaKey];
66482
+ if (typeof memberId === "string") return memberId;
66483
+ cursor = schemaClass2.extendsClassId ?? null;
66484
+ }
66485
+ return null;
66486
+ };
66487
+ const childrenByParentValueId = /* @__PURE__ */ new Map();
66488
+ const placementByChildValueId = /* @__PURE__ */ new Map();
66489
+ const add = (edge) => {
66490
+ const children = childrenByParentValueId.get(edge.parentValueId) ?? /* @__PURE__ */ new Map();
66491
+ if (children.has(edge.schemaKey)) return;
66492
+ children.set(edge.schemaKey, edge);
66493
+ childrenByParentValueId.set(edge.parentValueId, children);
66494
+ if (!placementByChildValueId.has(edge.childValueId)) {
66495
+ placementByChildValueId.set(edge.childValueId, edge);
66496
+ }
66497
+ };
66498
+ for (const [parentValueId, value] of values) {
66499
+ const classId = typeof value.classId === "string" ? value.classId : null;
66500
+ const body = value.value;
66501
+ if (isObjectRecord2(body)) {
66502
+ for (const [schemaKey, childValueId2] of Object.entries(body)) {
66503
+ if (typeof childValueId2 !== "string" || !values.has(childValueId2)) {
66504
+ continue;
66505
+ }
66506
+ add({
66507
+ childValueId: childValueId2,
66508
+ memberId: classId === null ? null : memberIdForSchemaKey(classId, schemaKey),
66509
+ parentValueId,
66510
+ schemaKey,
66511
+ source: "body"
66512
+ });
66513
+ }
66514
+ }
66515
+ const constructorId = value.instanceConstructorId;
66516
+ const constructorArgs2 = value.constructorArgs;
66517
+ if (classId === null || typeof constructorId !== "string" || !isObjectRecord2(constructorArgs2)) {
66518
+ continue;
66519
+ }
66520
+ const constructor2 = constructors.get(constructorId);
66521
+ const parameters = constructor2?.argumentTypes;
66522
+ if (constructor2 === void 0 || constructor2.classId !== classId || !Array.isArray(parameters)) {
66523
+ continue;
66524
+ }
66525
+ for (const [index, parameter4] of parameters.entries()) {
66526
+ if (!isObjectRecord2(parameter4) || typeof parameter4.name !== "string") {
66527
+ continue;
66528
+ }
66529
+ const settled = resolveSettlement(classId, parameter4.name, constructorId);
66530
+ if (settled === null) continue;
66531
+ if (isObjectRecord2(body) && Object.hasOwn(body, settled.schemaKey)) {
66532
+ continue;
66533
+ }
66534
+ const parameterId = constructorActionParameterId(constructor2, index);
66535
+ const childValueId2 = constructorArgs2[parameterId];
66536
+ if (typeof childValueId2 !== "string" || !values.has(childValueId2) || !memberStoresAggregate(
66537
+ memberDataById.get(settled.memberId),
66538
+ value,
66539
+ memberDataById,
66540
+ parentValueId,
66541
+ classesById,
66542
+ variantTargetClassByRootValueId
66543
+ )) {
66544
+ continue;
66545
+ }
66546
+ add({
66547
+ childValueId: childValueId2,
66548
+ memberId: settled.memberId,
66549
+ parentValueId,
66550
+ schemaKey: settled.schemaKey,
66551
+ source: "constructor"
66552
+ });
66553
+ }
66554
+ }
66555
+ return { childrenByParentValueId, placementByChildValueId };
66556
+ }
66557
+ function memberStoresAggregate(member, parent, membersById, parentValueId, classesById, variantTargetClassByRootValueId, visitedMemberIds = /* @__PURE__ */ new Set()) {
66558
+ const kind = member?.kind;
66559
+ if (kind === 5 /* Dictionary */ || kind === 6 /* List */ || kind === 7 /* Class */ || kind === "dictionary" || kind === "list" || kind === "class") {
66560
+ return true;
66561
+ }
66562
+ if (kind !== 21 /* Generic */ && kind !== "generic") return false;
66563
+ const memberId = typeof member?.id === "string" ? member.id : null;
66564
+ if (memberId !== null && visitedMemberIds.has(memberId)) return false;
66565
+ const genericParamId = member?.genericParamId;
66566
+ const bindings = parent.genericBindings;
66567
+ if (typeof genericParamId === "string" && isObjectRecord2(bindings)) {
66568
+ const bindingMemberId = bindings[genericParamId];
66569
+ if (typeof bindingMemberId === "string") {
66570
+ return memberStoresAggregate(
66571
+ membersById.get(bindingMemberId),
66572
+ parent,
66573
+ membersById,
66574
+ parentValueId,
66575
+ classesById,
66576
+ variantTargetClassByRootValueId,
66577
+ /* @__PURE__ */ new Set([
66578
+ ...visitedMemberIds,
66579
+ ...memberId === null ? [] : [memberId]
66580
+ ])
66581
+ );
66582
+ }
66583
+ }
66584
+ const parentClassId = parent.classId;
66585
+ const variantTargetClassId = variantTargetClassByRootValueId.get(parentValueId);
66586
+ if (typeof parentClassId === "string" && typeof variantTargetClassId === "string" && classesById.get(parentClassId)?.genericParamIds?.[0] === genericParamId && classesById.has(variantTargetClassId)) {
66587
+ return true;
66588
+ }
66589
+ return false;
66590
+ }
66591
+ function isStringRecord3(value) {
66592
+ return isObjectRecord2(value) && Object.values(value).every((entry) => typeof entry === "string");
66593
+ }
66594
+ var init_stored_value_placements = __esm({
66595
+ "src/project-source/stored-value-placements.ts"() {
66596
+ "use strict";
66597
+ init_constructors2();
66598
+ init_constructor_parameter_settlement();
66599
+ init_members();
66600
+ init_neo_script_derived_bodies();
66601
+ init_value_comparison();
66602
+ }
66603
+ });
66604
+
66605
+ // src/project-source/reference-target-types.ts
66606
+ function stringArray2(value) {
66607
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
66608
+ }
66609
+ var ReferenceTargetTypes;
66610
+ var init_reference_target_types = __esm({
66611
+ "src/project-source/reference-target-types.ts"() {
66612
+ "use strict";
66613
+ init_value_graph();
66614
+ init_project();
66615
+ init_codecs();
66616
+ init_document_adapters();
66617
+ init_members();
66618
+ init_projection();
66619
+ init_value_comparison();
66620
+ init_stored_value_placements();
66621
+ ReferenceTargetTypes = class {
66622
+ constructor(state, seeds = /* @__PURE__ */ new Map(), pendingRows = [], manifest) {
66623
+ this.state = state;
66624
+ this.manifest = manifest;
66625
+ for (const [memberId, seed] of seeds) {
66626
+ if (seed.valueId)
66627
+ this.overlay.set(seed.valueId, {
66628
+ id: seed.valueId,
66629
+ memberId,
66630
+ ...encodeStoredValueNode(seed)
66631
+ });
66632
+ for (const row of seed.values ?? [])
66633
+ this.overlay.set(row.id, {
66634
+ id: row.id,
66635
+ memberId: row.memberId,
66636
+ ...encodeStoredValueRowFields(row)
66637
+ });
66638
+ }
66639
+ for (const row of pendingRows)
66640
+ this.overlay.set(row.id, {
66641
+ id: row.id,
66642
+ memberId: row.memberId,
66643
+ ...encodeStoredValueRowFields(row)
66644
+ });
66645
+ const types = [];
66646
+ this.manifestMembers = manifest && new Map(manifest.members.map((member) => [member.id, member]));
66647
+ if (manifest) {
66648
+ for (const type of manifest.classes) {
66649
+ this.classes.set(type.id, type);
66650
+ types.push({
66651
+ id: type.id,
66652
+ name: type.name,
66653
+ kind: "class",
66654
+ members: [],
66655
+ baseTypeIds: type.extendsClassId ? [type.extendsClassId] : [],
66656
+ interfaceTypeIds: type.implementsInterfaceIds
66657
+ });
66658
+ }
66659
+ for (const type of manifest.interfaces)
66660
+ types.push({
66661
+ id: type.id,
66662
+ name: type.name,
66663
+ kind: "interface",
66664
+ members: [],
66665
+ baseTypeIds: type.extendsInterfaceIds
66666
+ });
66667
+ for (const type of manifest.enums)
66668
+ types.push({ id: type.id, name: type.name, kind: "enum", members: [] });
66669
+ } else {
66670
+ for (const record7 of Object.values(state)) {
66671
+ if (record7.recordKind !== "class" && record7.recordKind !== "interface" && record7.recordKind !== "enum")
66672
+ continue;
66673
+ const data = effectiveRecordData(record7);
66674
+ if (!isObjectRecord2(data) || typeof data.name !== "string") continue;
66675
+ if (record7.recordKind === "class")
66676
+ this.classes.set(record7.recordId, data);
66677
+ types.push({
66678
+ id: record7.recordId,
66679
+ name: data.name,
66680
+ kind: record7.recordKind,
66681
+ members: [],
66682
+ baseTypeIds: typeof data.extendsClassId === "string" ? [data.extendsClassId] : stringArray2(data.extendsInterfaceIds),
66683
+ interfaceTypeIds: stringArray2(data.implementsInterfaceIds)
66684
+ });
66685
+ }
66686
+ }
66687
+ this.project = createProjectIndex({
66688
+ version: 1,
66689
+ types,
66690
+ globals: [],
66691
+ roots: []
66692
+ });
66693
+ }
66694
+ state;
66695
+ manifest;
66696
+ classes = /* @__PURE__ */ new Map();
66697
+ schemaMembers = /* @__PURE__ */ new Map();
66698
+ members = /* @__PURE__ */ new Map();
66699
+ overlay = /* @__PURE__ */ new Map();
66700
+ manifestMembers;
66701
+ directOwners;
66702
+ orderedParents;
66703
+ values;
66704
+ placements;
66705
+ records;
66706
+ project;
66707
+ targetTypes = /* @__PURE__ */ new Map();
66708
+ ownerCache = /* @__PURE__ */ new Map();
66709
+ compatibility = /* @__PURE__ */ new Map();
66710
+ stored(kind, id2) {
66711
+ const record7 = this.state[`${kind}:${id2}`];
66712
+ const data = record7 && effectiveRecordData(record7);
66713
+ return isObjectRecord2(data) ? data : void 0;
66714
+ }
66715
+ member(id2) {
66716
+ const cached = this.members.get(id2);
66717
+ if (cached !== void 0) return cached ?? void 0;
66718
+ const base = this.stored("member", id2);
66719
+ const authored = this.manifestMembers?.get(id2);
66720
+ const data = authored ? memberToDocument(
66721
+ authored,
66722
+ base,
66723
+ this.manifestMembers?.get(authored.overrideOf ?? "")
66724
+ ) : base;
66725
+ this.members.set(id2, data ?? null);
66726
+ return data;
66727
+ }
66728
+ buildRecords() {
66729
+ const records2 = new Map(
66730
+ Object.values(this.state).map((record7) => [
66731
+ `${record7.recordKind}:${record7.recordId}`,
66732
+ {
66733
+ recordKind: record7.recordKind,
66734
+ recordId: record7.recordId,
66735
+ data: effectiveRecordData(record7)
66736
+ }
66737
+ ])
66738
+ );
66739
+ if (this.manifest)
66740
+ for (const record7 of projectSchemaManifestToDocuments(this.manifest, {
66741
+ baseRecord: (kind, id2) => {
66742
+ const data = this.stored(kind, id2);
66743
+ return data ? { recordKind: kind, recordId: id2, data } : null;
66744
+ }
66745
+ }))
66746
+ records2.set(`${record7.recordKind}:${record7.recordId}`, record7);
66747
+ for (const [id2, data] of this.overlay)
66748
+ records2.set(`value:${id2}`, { recordKind: "value", recordId: id2, data });
66749
+ return [...records2.values()];
66750
+ }
66751
+ readValues() {
66752
+ return this.values ??= storedValueRowsByIdV4(
66753
+ this.records ??= this.buildRecords()
66754
+ );
66755
+ }
66756
+ value(id2) {
66757
+ return this.overlay.get(id2) ?? this.stored("value", id2) ?? this.readValues().get(id2);
66758
+ }
66759
+ readPlacements() {
66760
+ return this.placements ??= buildStoredValuePlacementIndexV4(
66761
+ this.records ??= this.buildRecords(),
66762
+ this.readValues()
66763
+ );
66764
+ }
66765
+ readDirectOwners() {
66766
+ if (this.directOwners) return this.directOwners;
66767
+ const owners = /* @__PURE__ */ new Map();
66768
+ const ids = this.manifestMembers?.keys() ?? Object.values(this.state).filter((record7) => record7.recordKind === "member").map((record7) => record7.recordId);
66769
+ for (const id2 of ids) {
66770
+ const member = this.stored("member", id2);
66771
+ if (typeof member?.valueId === "string") owners.set(member.valueId, id2);
66772
+ }
66773
+ return this.directOwners = owners;
66774
+ }
66775
+ readOrderedParents() {
66776
+ if (this.orderedParents) return this.orderedParents;
66777
+ const parents = /* @__PURE__ */ new Map();
66778
+ const values = this.readValues();
66779
+ for (const [id2, row] of values) {
66780
+ if (!Array.isArray(row.value)) continue;
66781
+ for (const child2 of row.value) {
66782
+ if (typeof child2 !== "string" || !values.has(child2)) continue;
66783
+ const entries = parents.get(child2) ?? [];
66784
+ entries.push(id2);
66785
+ parents.set(child2, entries);
66786
+ }
66787
+ }
66788
+ return this.orderedParents = parents;
66789
+ }
66790
+ assertAssignable(valueId, expectedName, label) {
66791
+ let target = this.targetTypes.get(valueId);
66792
+ if (!target) {
66793
+ const value = this.value(valueId);
66794
+ const owner = value && typeof value.classId !== "string" ? this.owner(valueId, /* @__PURE__ */ new Set()) : void 0;
66795
+ const typeId = typeof value?.classId === "string" ? value.classId : owner?.classId ?? owner?.enumId;
66796
+ target = {
66797
+ exists: value !== void 0,
66798
+ typeId: typeof typeId === "string" ? typeId : void 0
66799
+ };
66800
+ this.targetTypes.set(valueId, target);
66801
+ }
66802
+ if (!target.exists)
66803
+ throw new Error(
66804
+ `${label} references unresolved value ${JSON.stringify(valueId)}.`
66805
+ );
66806
+ const classId = target.typeId;
66807
+ const actual = typeof classId === "string" ? this.project.typeById.get(classId) : void 0;
66808
+ const expected = this.project.typeByName.get(expectedName);
66809
+ if (!expected)
66810
+ throw new Error(`${label} has unknown target type ${expectedName}.`);
66811
+ const key = `${actual?.id}:${expected.id}`;
66812
+ let compatible = this.compatibility.get(key);
66813
+ if (compatible === void 0) {
66814
+ compatible = actual !== void 0 && isNeoScriptTypeAssignable(
66815
+ { kind: "named", typeId: actual.id },
66816
+ { kind: "named", typeId: expected.id },
66817
+ this.project
66818
+ );
66819
+ this.compatibility.set(key, compatible);
66820
+ }
66821
+ if (!compatible)
66822
+ throw new Error(
66823
+ `${label} target ${JSON.stringify(valueId)} has type ${actual?.name ?? "non-class value"}; expected ${expectedName}.`
66824
+ );
66825
+ }
66826
+ collectionEntryTypeName(collectionId) {
66827
+ const collection = this.member(collectionId);
66828
+ if (collection?.kind !== 6 /* List */ && collection?.kind !== 5 /* Dictionary */)
66829
+ return null;
66830
+ const entry = typeof collection.entryMemberId === "string" ? this.member(collection.entryMemberId) : void 0;
66831
+ return typeof entry?.classId === "string" ? this.project.typeById.get(entry.classId)?.name ?? null : null;
66832
+ }
66833
+ schemaMember(classId, key) {
66834
+ const cacheKey = `${classId}:${key}`;
66835
+ const cached = this.schemaMembers.get(cacheKey);
66836
+ if (cached !== void 0) return cached;
66837
+ const visited = /* @__PURE__ */ new Set();
66838
+ let current = classId;
66839
+ while (current && !visited.has(current)) {
66840
+ visited.add(current);
66841
+ const declaration = this.classes.get(current);
66842
+ const id2 = isObjectRecord2(declaration?.schema) ? declaration.schema[key] : void 0;
66843
+ if (typeof id2 === "string") {
66844
+ this.schemaMembers.set(cacheKey, id2);
66845
+ return id2;
66846
+ }
66847
+ current = typeof declaration?.extendsClassId === "string" ? declaration.extendsClassId : void 0;
66848
+ }
66849
+ this.schemaMembers.set(cacheKey, null);
66850
+ return null;
66851
+ }
66852
+ owner(valueId, visiting) {
66853
+ const cached = this.ownerCache.get(valueId);
66854
+ if (cached !== void 0)
66855
+ return cached === null ? void 0 : this.member(cached);
66856
+ if (visiting.has(valueId)) return void 0;
66857
+ visiting.add(valueId);
66858
+ const row = this.value(valueId);
66859
+ let memberId = typeof row?.memberId === "string" ? row.memberId : this.readDirectOwners().get(valueId);
66860
+ if (!memberId)
66861
+ memberId = this.readPlacements().placementByChildValueId.get(valueId)?.memberId;
66862
+ if (!memberId) {
66863
+ const placement = this.readPlacements().placementByChildValueId.get(valueId);
66864
+ const row2 = this.value(valueId);
66865
+ const parentId = placement?.parentValueId ?? (typeof row2?.containerId === "string" ? row2.containerId : void 0);
66866
+ const parent = parentId ? this.owner(parentId, visiting) : void 0;
66867
+ if (parent?.kind === 6 /* List */ || parent?.kind === 5 /* Dictionary */) {
66868
+ if (typeof parent.entryMemberId === "string")
66869
+ memberId = parent.entryMemberId;
66870
+ } else if (placement && parentId) {
66871
+ const parentValue = this.value(parentId);
66872
+ const classId = typeof parentValue?.classId === "string" ? parentValue.classId : parent?.classId;
66873
+ if (typeof classId === "string")
66874
+ memberId = this.schemaMember(classId, placement.schemaKey);
66875
+ }
66876
+ }
66877
+ if (!memberId) {
66878
+ for (const parentId of this.readOrderedParents().get(valueId) ?? []) {
66879
+ const parent = this.owner(parentId, visiting);
66880
+ if (parent?.kind === 6 /* List */ && typeof parent.entryMemberId === "string") {
66881
+ memberId = parent.entryMemberId;
66882
+ break;
66883
+ }
66884
+ }
66885
+ }
66886
+ visiting.delete(valueId);
66887
+ this.ownerCache.set(valueId, memberId ?? null);
66888
+ return memberId ? this.member(memberId) : void 0;
66889
+ }
66890
+ };
66891
+ }
66892
+ });
66893
+
65454
66894
  // ../packages/neoscript-language/src/document-scaffold.ts
65455
66895
  var init_document_scaffold = __esm({
65456
66896
  "../packages/neoscript-language/src/document-scaffold.ts"() {
@@ -69080,144 +70520,6 @@ var init_initializer_dependencies = __esm({
69080
70520
  }
69081
70521
  });
69082
70522
 
69083
- // ../src/models/classes/constructor-parameter-settlement.ts
69084
- function createConstructorSettlementResolver(view) {
69085
- const classesById = new Map(
69086
- view.classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
69087
- );
69088
- const membersById = new Map(
69089
- view.members.map((member) => [member.id, member])
69090
- );
69091
- const constructorsById = new Map(
69092
- (view.constructors ?? []).map((constructor2) => [
69093
- constructor2.id,
69094
- constructor2
69095
- ])
69096
- );
69097
- const directResultByClassAndParameter = /* @__PURE__ */ new Map();
69098
- const recordedResultByConstructorAndParameter = /* @__PURE__ */ new Map();
69099
- const directSettlement = (classId, parameterName) => {
69100
- const cacheKey = `${classId}\0${parameterName}`;
69101
- if (directResultByClassAndParameter.has(cacheKey)) {
69102
- return directResultByClassAndParameter.get(cacheKey) ?? null;
69103
- }
69104
- const visited = /* @__PURE__ */ new Set();
69105
- let currentId = classId;
69106
- while (currentId !== null && !visited.has(currentId)) {
69107
- visited.add(currentId);
69108
- const schemaClass2 = classesById.get(currentId);
69109
- if (schemaClass2 === void 0) break;
69110
- for (const [schemaKey, memberId] of Object.entries(
69111
- schemaClass2.schema ?? {}
69112
- )) {
69113
- if (typeof memberId !== "string") continue;
69114
- const member = membersById.get(memberId);
69115
- const defaultRecord = asRecord(member?.defaultValue);
69116
- const initRecord = asRecord(defaultRecord?.init);
69117
- if (initRecord !== null && typeof initRecord.code === "string" && initRecord.code.trim() === parameterName) {
69118
- const result = { schemaKey, memberId };
69119
- directResultByClassAndParameter.set(cacheKey, result);
69120
- return result;
69121
- }
69122
- }
69123
- currentId = schemaClass2.extendsClassId ?? null;
69124
- }
69125
- directResultByClassAndParameter.set(cacheKey, null);
69126
- return null;
69127
- };
69128
- const memberIdForSchemaKey = (classId, schemaKey) => {
69129
- const visited = /* @__PURE__ */ new Set();
69130
- let currentId = classId;
69131
- while (currentId !== null && !visited.has(currentId)) {
69132
- visited.add(currentId);
69133
- const schemaClass2 = classesById.get(currentId);
69134
- if (schemaClass2 === void 0) return null;
69135
- const memberId = schemaClass2.schema?.[schemaKey];
69136
- if (typeof memberId === "string") return memberId;
69137
- currentId = schemaClass2.extendsClassId ?? null;
69138
- }
69139
- return null;
69140
- };
69141
- const recordedSettlement = (classId, parameterName, constructorId, resolving) => {
69142
- const cacheKey = `${classId}\0${constructorId}\0${parameterName}`;
69143
- if (recordedResultByConstructorAndParameter.has(cacheKey)) {
69144
- return recordedResultByConstructorAndParameter.get(cacheKey) ?? null;
69145
- }
69146
- if (resolving.has(cacheKey)) return null;
69147
- const constructor2 = constructorsById.get(constructorId);
69148
- if (constructor2?.classId !== classId) {
69149
- recordedResultByConstructorAndParameter.set(cacheKey, null);
69150
- return null;
69151
- }
69152
- const direct = directSettlement(classId, parameterName);
69153
- if (direct !== null) {
69154
- recordedResultByConstructorAndParameter.set(cacheKey, direct);
69155
- return direct;
69156
- }
69157
- const schemaClass2 = classesById.get(classId);
69158
- const baseClassId = schemaClass2?.extendsClassId;
69159
- if (typeof baseClassId !== "string") {
69160
- recordedResultByConstructorAndParameter.set(cacheKey, null);
69161
- return null;
69162
- }
69163
- for (const field of constructor2.baseInitializerFields ?? []) {
69164
- const record7 = asRecord(field);
69165
- if (typeof record7?.name !== "string" || typeof record7.code !== "string" || record7.code.trim() !== parameterName) {
69166
- continue;
69167
- }
69168
- const memberId = memberIdForSchemaKey(baseClassId, record7.name);
69169
- if (memberId !== null) {
69170
- const result = { schemaKey: record7.name, memberId };
69171
- recordedResultByConstructorAndParameter.set(cacheKey, result);
69172
- return result;
69173
- }
69174
- }
69175
- const baseConstructorId = classesById.get(baseClassId)?.requiredConstructorId;
69176
- if (typeof baseConstructorId !== "string") {
69177
- recordedResultByConstructorAndParameter.set(cacheKey, null);
69178
- return null;
69179
- }
69180
- resolving.add(cacheKey);
69181
- for (const argument2 of constructor2.baseArguments ?? []) {
69182
- const record7 = asRecord(argument2);
69183
- if (typeof record7?.name !== "string" || typeof record7.code !== "string" || record7.code.trim() !== parameterName) {
69184
- continue;
69185
- }
69186
- const result = recordedSettlement(
69187
- baseClassId,
69188
- record7.name,
69189
- baseConstructorId,
69190
- resolving
69191
- );
69192
- resolving.delete(cacheKey);
69193
- recordedResultByConstructorAndParameter.set(cacheKey, result);
69194
- return result;
69195
- }
69196
- resolving.delete(cacheKey);
69197
- recordedResultByConstructorAndParameter.set(cacheKey, null);
69198
- return null;
69199
- };
69200
- return (classId, parameterName, constructorId) => constructorId === void 0 ? directSettlement(classId, parameterName) : recordedSettlement(classId, parameterName, constructorId, /* @__PURE__ */ new Set());
69201
- }
69202
- function constructorSettledSchemaEntry(view, classId, parameterName, constructorId) {
69203
- return createConstructorSettlementResolver(view)(
69204
- classId,
69205
- parameterName,
69206
- constructorId
69207
- );
69208
- }
69209
- function asRecord(value) {
69210
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
69211
- return null;
69212
- }
69213
- return value;
69214
- }
69215
- var init_constructor_parameter_settlement = __esm({
69216
- "../src/models/classes/constructor-parameter-settlement.ts"() {
69217
- "use strict";
69218
- }
69219
- });
69220
-
69221
70523
  // ../src/models/members/lookup-declared-type.ts
69222
70524
  function lookupDeclaredTypeInfo(member, collectionTypeInfo) {
69223
70525
  if (collectionTypeInfo === null) return null;
@@ -70117,7 +71419,7 @@ function collectSoftOwnedConstructorArgumentValueIds(index, ownerValueId, preser
70117
71419
  collectTypedRow(childId, typeInfo.entryTypeInfo);
70118
71420
  }
70119
71421
  }
70120
- } else if (typeInfo.type === 5 /* Dictionary */ && isStringRecord3(row.value)) {
71422
+ } else if (typeInfo.type === 5 /* Dictionary */ && isStringRecord4(row.value)) {
70121
71423
  for (const childId of Object.values(row.value)) {
70122
71424
  collectTypedRow(childId, typeInfo.entryTypeInfo);
70123
71425
  }
@@ -70139,7 +71441,7 @@ function collectSoftOwnedConstructorArgumentValueIds(index, ownerValueId, preser
70139
71441
  collectNestedConstructorArguments(valueId);
70140
71442
  };
70141
71443
  const collectClassChildren = (row, typeInfo) => {
70142
- if (!isStringRecord3(row.value)) return;
71444
+ if (!isStringRecord4(row.value)) return;
70143
71445
  const effectiveClassId = row.classId ?? (typeInfo.type === 7 /* Class */ ? typeInfo.classId : void 0);
70144
71446
  if (effectiveClassId === void 0) return;
70145
71447
  const env = rowGenericEnvironment(index.document, row);
@@ -70214,7 +71516,7 @@ function tryMemberTypeInfo(document, rawMember, env) {
70214
71516
  function isAggregateTypeInfo(typeInfo) {
70215
71517
  return typeInfo.type === 7 /* Class */ || typeInfo.type === 22 /* Interface */ || typeInfo.type === 6 /* List */ || typeInfo.type === 5 /* Dictionary */;
70216
71518
  }
70217
- function isStringRecord3(value) {
71519
+ function isStringRecord4(value) {
70218
71520
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
70219
71521
  return false;
70220
71522
  }
@@ -70445,7 +71747,7 @@ var init_constructor_argument_ownership = __esm({
70445
71747
  }
70446
71748
  }
70447
71749
  const parameterTypes = this.constructorParameterTypes(row);
70448
- const constructorArgs = row.constructorArgs === void 0 || row.constructorArgs === null ? row.constructorArgs : Object.fromEntries(
71750
+ const constructorArgs2 = row.constructorArgs === void 0 || row.constructorArgs === null ? row.constructorArgs : Object.fromEntries(
70449
71751
  Object.entries(row.constructorArgs).map(
70450
71752
  ([parameterId, argument2]) => {
70451
71753
  const typeInfo = parameterTypes.get(parameterId);
@@ -70462,7 +71764,7 @@ var init_constructor_argument_ownership = __esm({
70462
71764
  value,
70463
71765
  ...typeof row.containerId !== "string" ? {} : { containerId: rewriteId(row.containerId) },
70464
71766
  ...row.sourceValueId === void 0 ? {} : { sourceValueId: rewriteId(row.sourceValueId) },
70465
- ...constructorArgs === void 0 ? {} : { constructorArgs }
71767
+ ...constructorArgs2 === void 0 ? {} : { constructorArgs: constructorArgs2 }
70466
71768
  };
70467
71769
  }
70468
71770
  collectSoftOwnedRows(ownerValueId, preservedValueIds) {
@@ -70636,7 +71938,7 @@ function createStoredValuePlacementTraversal(args, trackReferences = false) {
70636
71938
  if (isMemberClassBase(member)) {
70637
71939
  const classId = value.classId ?? member.classId;
70638
71940
  appendPlacement(mutablePlacementsByClassId, classId, placement);
70639
- if (!isLiteralValueContent(value) || !isStringRecord4(value.value)) {
71941
+ if (!isLiteralValueContent(value) || !isStringRecord5(value.value)) {
70640
71942
  continue;
70641
71943
  }
70642
71944
  const settledChildrenBySchemaKey = /* @__PURE__ */ new Map();
@@ -70682,7 +71984,7 @@ function createStoredValuePlacementTraversal(args, trackReferences = false) {
70682
71984
  const entryMember = membersById.get(member.entryMemberId);
70683
71985
  if (entryMember === void 0) continue;
70684
71986
  if (isMemberDictionaryBase(member)) {
70685
- if (!isStringRecord4(value.value)) continue;
71987
+ if (!isStringRecord5(value.value)) continue;
70686
71988
  for (const [key, childValueId2] of Object.entries(value.value)) {
70687
71989
  queue.push({
70688
71990
  memberId: entryMember.id,
@@ -70891,7 +72193,7 @@ function appendPlacement(index, key, placement) {
70891
72193
  placements.push(placement);
70892
72194
  }
70893
72195
  }
70894
- function isStringRecord4(value) {
72196
+ function isStringRecord5(value) {
70895
72197
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
70896
72198
  return false;
70897
72199
  }
@@ -82089,9 +83391,9 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
82089
83391
  }
82090
83392
  deleteRuntimeSessionValue(ctx, rootRow.id);
82091
83393
  ctx.__executionState?.constructorGroups.delete(rootRow.id);
82092
- const constructorArgs = typeof result.value === "object" && result.value !== null ? ctx.__constructedArgumentsByValue.get(result.value) ?? rootRow.constructorArgs ?? void 0 : void 0;
83394
+ const constructorArgs2 = typeof result.value === "object" && result.value !== null ? ctx.__constructedArgumentsByValue.get(result.value) ?? rootRow.constructorArgs ?? void 0 : void 0;
82093
83395
  const provenance = pickInstanceProvenance({
82094
- constructorArgs,
83396
+ constructorArgs: constructorArgs2,
82095
83397
  instanceConstructorId: rootRow.instanceConstructorId,
82096
83398
  instanceVariantId: rootRow.instanceVariantId,
82097
83399
  instanceVariantRowValueId: rootRow.instanceVariantRowValueId
@@ -84185,12 +85487,12 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
84185
85487
  }
84186
85488
  }
84187
85489
  if (isLiteralValueContent(sourceRow) && sourceRow.constructorArgs !== void 0 && sourceRow.constructorArgs !== null) {
84188
- const constructorArgs = { ...sourceRow.constructorArgs };
85490
+ const constructorArgs2 = { ...sourceRow.constructorArgs };
84189
85491
  for (const argument2 of ownedConstructorArgumentValues(sourceRow, ctx)) {
84190
85492
  if (argument2.parameterId === void 0) continue;
84191
85493
  const alreadyCloned = clonedBySourceId.get(argument2.id);
84192
85494
  if (alreadyCloned !== void 0) {
84193
- constructorArgs[argument2.parameterId] = alreadyCloned.id;
85495
+ constructorArgs2[argument2.parameterId] = alreadyCloned.id;
84194
85496
  continue;
84195
85497
  }
84196
85498
  const argumentRow = evalValueById(
@@ -84204,14 +85506,14 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
84204
85506
  continue;
84205
85507
  }
84206
85508
  if (constructorArgumentReferenceCount(argument2.id) !== 1) continue;
84207
- constructorArgs[argument2.parameterId] = cloneRow2(
85509
+ constructorArgs2[argument2.parameterId] = cloneRow2(
84208
85510
  argumentRow,
84209
85511
  null,
84210
85512
  void 0,
84211
85513
  argument2.typeInfo
84212
85514
  ).id;
84213
85515
  }
84214
- clone.constructorArgs = constructorArgs;
85516
+ clone.constructorArgs = constructorArgs2;
84215
85517
  }
84216
85518
  if (typeof clone.value === "object" && clone.value !== null && clone.value !== sourceRow.value) {
84217
85519
  const sourceRowValue = sourceRow.value;
@@ -85254,13 +86556,13 @@ function evaluateMemberInitializer(args) {
85254
86556
  args.createdValues.push(row);
85255
86557
  }
85256
86558
  if (rootRow === null) return { value: result.value, classId: null };
85257
- const constructorArgs = (typeof result.value === "object" && result.value !== null ? ctx.__constructedArgumentsByValue?.get(result.value) : void 0) ?? // An implicit `new()` records its empty args on the row rather than in
86559
+ const constructorArgs2 = (typeof result.value === "object" && result.value !== null ? ctx.__constructedArgumentsByValue?.get(result.value) : void 0) ?? // An implicit `new()` records its empty args on the row rather than in
85258
86560
  // the declared-constructor argument map; the pair must survive either
85259
86561
  // origin or the recipe reads as an unrecorded overload.
85260
86562
  rootRow.constructorArgs ?? void 0;
85261
86563
  const pinnedRootSchemaKeys = typeof result.value === "object" && result.value !== null ? ctx.__constructedFieldSchemaKeysByValue?.get(result.value) : void 0;
85262
86564
  const provenance = pickInstanceProvenance({
85263
- constructorArgs,
86565
+ constructorArgs: constructorArgs2,
85264
86566
  instanceConstructorId: rootRow.instanceConstructorId,
85265
86567
  instanceVariantId: rootRow.instanceVariantId,
85266
86568
  instanceVariantRowValueId: rootRow.instanceVariantRowValueId
@@ -89415,6 +90717,20 @@ function compileNSGetter(code, ctx) {
89415
90717
  ctx.source
89416
90718
  );
89417
90719
  }
90720
+ function compileNSInferredExpressionGetter(code, ctx) {
90721
+ const compiled = compileStrict(
90722
+ code,
90723
+ createContext(ctx, {
90724
+ scriptKind: "getter",
90725
+ dialogueContext: ctx.dialogueContext
90726
+ }),
90727
+ ctx.source,
90728
+ true
90729
+ );
90730
+ if (!isNSGetter(compiled))
90731
+ throw new Error("Expression compiler did not produce a getter.");
90732
+ return compiled;
90733
+ }
89418
90734
  function compileNSVoidBody(code, ctx) {
89419
90735
  const context = createContext(ctx, {
89420
90736
  scriptKind: "action",
@@ -89513,9 +90829,10 @@ function withInitializerSourcePosition(error) {
89513
90829
  error.unit
89514
90830
  );
89515
90831
  }
89516
- function compileStrict(code, context, sourceInfo) {
90832
+ function compileStrict(code, context, sourceInfo, inferExpressionReturnType = false) {
89517
90833
  const source = sourceInfo?.code === code ? sourceInfo.source : void 0;
89518
90834
  const cacheKey = JSON.stringify({
90835
+ inferExpressionReturnType,
89519
90836
  code,
89520
90837
  source,
89521
90838
  projectIdentity: compilationProjectIdentity(context.project),
@@ -89548,7 +90865,11 @@ function compileStrict(code, context, sourceInfo) {
89548
90865
  text: code
89549
90866
  },
89550
90867
  context,
89551
- { projectIndex: compilationProjectIndex(context.project), source }
90868
+ {
90869
+ projectIndex: compilationProjectIndex(context.project),
90870
+ source,
90871
+ inferExpressionReturnType
90872
+ }
89552
90873
  );
89553
90874
  if (result.diagnostics.length) {
89554
90875
  const error = result.diagnostics[0];
@@ -89619,6 +90940,7 @@ var init_compile = __esm({
89619
90940
  "../src/database/neoscript/compile.ts"() {
89620
90941
  "use strict";
89621
90942
  init_runtime_source();
90943
+ init_neoscript_guards();
89622
90944
  init_compiler();
89623
90945
  init_strict_compile_error();
89624
90946
  init_project();
@@ -90047,7 +91369,7 @@ function createTypedValueNormalizer(reader, document, childrenByContainerId, par
90047
91369
  } else {
90048
91370
  value = normalizeLiteral(row.value);
90049
91371
  }
90050
- } else if (typeInfo.type === 5 /* Dictionary */ && isStringRecord5(row.value)) {
91372
+ } else if (typeInfo.type === 5 /* Dictionary */ && isStringRecord6(row.value)) {
90051
91373
  const entries = /* @__PURE__ */ Object.create(null);
90052
91374
  for (const [key, childId] of Object.entries(row.value)) {
90053
91375
  entries[key] = normalizeTypedRow(
@@ -90123,12 +91445,12 @@ function createTypedValueNormalizer(reader, document, childrenByContainerId, par
90123
91445
  };
90124
91446
  function carriesSemanticConstructorArguments(row) {
90125
91447
  if (!isLiteralValueContent(row)) return false;
90126
- const constructorArgs = row.constructorArgs;
90127
- if (constructorArgs === void 0 || constructorArgs === null) return false;
90128
- return typeof row.instanceConstructorId === "string" || Object.keys(constructorArgs).length > 0;
91448
+ const constructorArgs2 = row.constructorArgs;
91449
+ if (constructorArgs2 === void 0 || constructorArgs2 === null) return false;
91450
+ return typeof row.instanceConstructorId === "string" || Object.keys(constructorArgs2).length > 0;
90129
91451
  }
90130
91452
  const normalizeClassValue = (row, typeInfo, env) => {
90131
- if (!isStringRecord5(row.value)) return normalizeLiteral(row.value);
91453
+ if (!isStringRecord6(row.value)) return normalizeLiteral(row.value);
90132
91454
  const effectiveClassId = row.classId ?? (typeInfo.type === 7 /* Class */ ? typeInfo.classId : void 0);
90133
91455
  if (effectiveClassId === void 0) return normalizeLiteral(row.value);
90134
91456
  const merged = mergeInstanceSurfaceSchema(
@@ -90181,10 +91503,10 @@ function createTypedValueNormalizer(reader, document, childrenByContainerId, par
90181
91503
  }
90182
91504
  return result;
90183
91505
  };
90184
- function normalizeConstructorArgs(constructorArgs, root) {
91506
+ function normalizeConstructorArgs(constructorArgs2, root) {
90185
91507
  const parameterTypes = parameterTypesForRow(root);
90186
91508
  const result = /* @__PURE__ */ Object.create(null);
90187
- for (const [parameterId, value] of Object.entries(constructorArgs)) {
91509
+ for (const [parameterId, value] of Object.entries(constructorArgs2)) {
90188
91510
  const typeInfo = parameterTypes.get(parameterId);
90189
91511
  if (typeInfo === void 0) {
90190
91512
  result[parameterId] = normalizeLiteral(value);
@@ -90198,7 +91520,7 @@ function createTypedValueNormalizer(reader, document, childrenByContainerId, par
90198
91520
  }
90199
91521
  return { normalizeConstructorArgs, normalizeTypedRow };
90200
91522
  }
90201
- function isStringRecord5(value) {
91523
+ function isStringRecord6(value) {
90202
91524
  return typeof value === "object" && value !== null && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
90203
91525
  }
90204
91526
  function isAggregateTypeInfo2(type) {
@@ -90448,7 +91770,7 @@ var init_effective_value_reader = __esm({
90448
91770
  const row = this.rawRow(valueId);
90449
91771
  if (row === void 0) return void 0;
90450
91772
  const classId = row.classId ?? (typeInfo?.type === 7 /* Class */ ? typeInfo.classId : void 0) ?? (isMemberClassBase(placement) ? placement.classId : void 0);
90451
- if (classId === void 0 || row.value === null || !isStringRecord5(row.value))
91773
+ if (classId === void 0 || row.value === null || !isStringRecord6(row.value))
90452
91774
  return row;
90453
91775
  if (this.resolvedRoots.has(valueId)) return row;
90454
91776
  if (this.mode(valueId) === "partial") return row;
@@ -90818,6 +92140,7 @@ __export(compiler_adapter_exports, {
90818
92140
  compileNSConstructor: () => compileNSConstructor,
90819
92141
  compileNSFunction: () => compileNSFunction,
90820
92142
  compileNSGetter: () => compileNSGetter,
92143
+ compileNSInferredExpressionGetter: () => compileNSInferredExpressionGetter,
90821
92144
  compileNSInitializer: () => compileNSInitializer,
90822
92145
  compileNSSetter: () => compileNSSetter,
90823
92146
  compileNSVoidBody: () => compileNSVoidBody,
@@ -93967,251 +95290,6 @@ var init_localized_text_create_envelope = __esm({
93967
95290
  }
93968
95291
  });
93969
95292
 
93970
- // ../src/database/neo-script-derived-bodies.ts
93971
- function cloneAndStripClientDerivedBodies(change) {
93972
- if (change.operation === "delete" || change.nextData === void 0) {
93973
- return { ...change };
93974
- }
93975
- return {
93976
- ...change,
93977
- nextData: stripClientDerivedBodies(change.recordKind, change.nextData)
93978
- };
93979
- }
93980
- function stripClientDerivedBodies(recordKind, nextData) {
93981
- const record7 = asRecord2(nextData);
93982
- return record7 === null ? nextData : strippedClone(recordKind, record7);
93983
- }
93984
- function hasPendingNeoScriptDerivation(recordKind, data) {
93985
- const record7 = asRecord2(data);
93986
- if (record7 === null) return false;
93987
- return collectDerivedBodySites(recordKind, record7).some(
93988
- (site) => site.authored && !(site.key in site.container)
93989
- );
93990
- }
93991
- function strippedClone(recordKind, record7) {
93992
- const next = structuredClone(record7);
93993
- const container = asRecord2(next);
93994
- if (container === null) return next;
93995
- for (const site of collectDerivedBodySites(recordKind, container)) {
93996
- delete site.container[site.key];
93997
- }
93998
- return next;
93999
- }
94000
- function collectDerivedBodySites(recordKind, record7) {
94001
- const sites = [];
94002
- if (recordKind === "migration") {
94003
- sites.push({
94004
- container: record7,
94005
- key: "action",
94006
- authored: typeof record7.code === "string"
94007
- });
94008
- return sites;
94009
- }
94010
- if (recordKind === "dialogue-group") {
94011
- collectConditionSites(record7.conditions, sites);
94012
- return sites;
94013
- }
94014
- if (recordKind === "dialogue-node") {
94015
- collectDialogueNodeSites(record7, sites);
94016
- return sites;
94017
- }
94018
- if (recordKind === "constructor") {
94019
- sites.push({ container: record7, key: "action", authored: true });
94020
- sites.push({
94021
- container: record7,
94022
- key: "compiledBaseArguments",
94023
- authored: false
94024
- });
94025
- sites.push({
94026
- container: record7,
94027
- key: "compiledBaseInitializerFields",
94028
- authored: false
94029
- });
94030
- return sites;
94031
- }
94032
- if (recordKind === "value") {
94033
- collectValueBodySites(record7, sites);
94034
- return sites;
94035
- }
94036
- if (recordKind !== "member") return sites;
94037
- if (record7.kind === 10 /* NSProperty */) {
94038
- sites.push({
94039
- container: record7,
94040
- key: "getter",
94041
- authored: typeof record7.code === "string"
94042
- });
94043
- sites.push({
94044
- container: record7,
94045
- key: "setter",
94046
- authored: typeof record7.setterCode === "string"
94047
- });
94048
- }
94049
- if (record7.kind === 23 /* NSFunction */) {
94050
- sites.push({
94051
- container: record7,
94052
- key: "action",
94053
- authored: typeof record7.code === "string"
94054
- });
94055
- }
94056
- if (record7.kind === 25 /* NSDelegate */) {
94057
- collectDelegateClosureSite(asRecord2(record7.defaultValue), sites, false);
94058
- }
94059
- collectInitializerSite(asRecord2(record7.defaultValue), sites);
94060
- return sites;
94061
- }
94062
- function collectValueBodySites(record7, sites) {
94063
- collectInitializerSite(record7, sites);
94064
- collectDelegateClosureSite(record7, sites, true);
94065
- collectInlineDelegateArgumentSites(record7, sites);
94066
- for (const container of [record7.value, record7.constructorArgs]) {
94067
- if (container === null || typeof container !== "object") continue;
94068
- for (const candidate of Object.values(container)) {
94069
- if (!isPackedValueEnvelope(candidate)) continue;
94070
- const child2 = asRecord2(candidate[PACKED_VALUE_ENTRY_KEY]);
94071
- if (child2 !== null) collectValueBodySites(child2, sites);
94072
- }
94073
- }
94074
- }
94075
- function collectDialogueNodeSites(node, sites) {
94076
- collectConditionSites(node.conditions, sites);
94077
- collectTextVariableSites(node.variables, sites);
94078
- if (Array.isArray(node.actions)) {
94079
- for (const actionValue2 of node.actions) {
94080
- const logic = asRecord2(asRecord2(actionValue2)?.logic);
94081
- if (logic === null) continue;
94082
- if (logic.type !== 1 /* Code */) continue;
94083
- if (typeof logic.code !== "string") continue;
94084
- sites.push({ container: logic, key: "action", authored: true });
94085
- }
94086
- }
94087
- if (Array.isArray(node.outcomes)) {
94088
- for (const outcomeValue of node.outcomes) {
94089
- collectConditionSites(asRecord2(outcomeValue)?.conditions, sites);
94090
- }
94091
- }
94092
- const options = asRecord2(node.optionSettings)?.options;
94093
- if (!Array.isArray(options)) return;
94094
- for (const optionValue of options) {
94095
- const option = asRecord2(optionValue);
94096
- if (option === null) continue;
94097
- collectTextVariableSites(option.variables, sites);
94098
- const settings = asRecord2(option.settings);
94099
- if (settings === null) continue;
94100
- collectConditionSites(settings.conditions, sites);
94101
- collectConditionSites(settings.selectableConditions, sites);
94102
- }
94103
- }
94104
- function collectConditionSites(value, sites) {
94105
- if (!Array.isArray(value)) return;
94106
- for (const conditionValue of value) {
94107
- const condition = asRecord2(conditionValue);
94108
- if (condition === null) continue;
94109
- if (condition.type !== 1 /* Code */) continue;
94110
- if (typeof condition.code !== "string") continue;
94111
- sites.push({ container: condition, key: "getter", authored: true });
94112
- }
94113
- }
94114
- function collectTextVariableSites(value, sites) {
94115
- const variables = asRecord2(value);
94116
- if (variables === null) return;
94117
- for (const variableValue of Object.values(variables)) {
94118
- const variable2 = asRecord2(variableValue);
94119
- if (variable2 === null) continue;
94120
- sites.push({ container: variable2, key: "getter", authored: true });
94121
- }
94122
- }
94123
- function collectDelegateClosureSite(container, sites, authored) {
94124
- const delegate = asRecord2(container?.value);
94125
- if (delegate === null) return;
94126
- if (typeof delegate.code !== "string") return;
94127
- sites.push({ container: delegate, key: "action", authored });
94128
- }
94129
- function collectInlineDelegateArgumentSites(record7, sites) {
94130
- const constructorArgs = asRecord2(record7.constructorArgs);
94131
- if (constructorArgs === null) return;
94132
- for (const argument2 of Object.values(constructorArgs)) {
94133
- const closure = asRecord2(argument2);
94134
- if (closure === null) continue;
94135
- if (typeof closure.code !== "string") continue;
94136
- sites.push({ container: closure, key: "action", authored: true });
94137
- }
94138
- }
94139
- function collectInitializerSite(container, sites) {
94140
- const init = asRecord2(container?.init);
94141
- if (init === null) return;
94142
- sites.push({ container: init, key: "compiled", authored: true });
94143
- }
94144
- function stripDerivedBodies(member) {
94145
- return strippedClone("member", member);
94146
- }
94147
- function stripConstructorDerivedBodies(constructorRecord) {
94148
- return strippedClone("constructor", constructorRecord);
94149
- }
94150
- function stripMigrationAction(migration) {
94151
- return strippedClone("migration", migration);
94152
- }
94153
- function stampUILogicBody(logic, bodyKey) {
94154
- if (logic?.type !== 0 /* UI */) return false;
94155
- const body = asRecord2(logic[bodyKey]);
94156
- if (body === null) return false;
94157
- if (body.compilerRevision === NEOSCRIPT_COMPILER_REVISION) return false;
94158
- body.compilerRevision = NEOSCRIPT_COMPILER_REVISION;
94159
- return true;
94160
- }
94161
- function stampUILogicBodies(recordKind, data) {
94162
- const record7 = asRecord2(data);
94163
- if (record7 === null) return false;
94164
- if (recordKind === "dialogue-group") {
94165
- return stampConditionList(record7.conditions);
94166
- }
94167
- if (recordKind !== "dialogue-node") return false;
94168
- let changed = stampConditionList(record7.conditions);
94169
- if (Array.isArray(record7.actions)) {
94170
- for (const actionValue2 of record7.actions) {
94171
- const logic = asRecord2(asRecord2(actionValue2)?.logic);
94172
- changed = stampUILogicBody(logic, "action") || changed;
94173
- }
94174
- }
94175
- if (Array.isArray(record7.outcomes)) {
94176
- for (const outcomeValue of record7.outcomes) {
94177
- changed = stampConditionList(asRecord2(outcomeValue)?.conditions) || changed;
94178
- }
94179
- }
94180
- const options = asRecord2(record7.optionSettings)?.options;
94181
- if (Array.isArray(options)) {
94182
- for (const optionValue of options) {
94183
- const settings = asRecord2(asRecord2(optionValue)?.settings);
94184
- if (settings === null) continue;
94185
- changed = stampConditionList(settings.conditions) || changed;
94186
- changed = stampConditionList(settings.selectableConditions) || changed;
94187
- }
94188
- }
94189
- return changed;
94190
- }
94191
- function stampConditionList(value) {
94192
- if (!Array.isArray(value)) return false;
94193
- let changed = false;
94194
- for (const conditionValue of value) {
94195
- changed = stampUILogicBody(asRecord2(conditionValue), "getter") || changed;
94196
- }
94197
- return changed;
94198
- }
94199
- function asRecord2(value) {
94200
- if (typeof value !== "object" || value === null || Array.isArray(value)) {
94201
- return null;
94202
- }
94203
- return value;
94204
- }
94205
- var init_neo_script_derived_bodies = __esm({
94206
- "../src/database/neo-script-derived-bodies.ts"() {
94207
- "use strict";
94208
- init_members();
94209
- init_logic_types();
94210
- init_strict_ir();
94211
- init_packed_value_encoding();
94212
- }
94213
- });
94214
-
94215
95293
  // ../src/database/neo-script-recompile-scope.ts
94216
95294
  function memberNeoScriptContractChanged(current, next) {
94217
95295
  return canonicalJsonStringify(neoScriptMemberContractProjection(current)) !== canonicalJsonStringify(neoScriptMemberContractProjection(next));
@@ -94936,9 +96014,9 @@ function constructorOwners(document) {
94936
96014
  (document.constructors ?? []).map((record7) => record7.id)
94937
96015
  );
94938
96016
  for (const schemaClass2 of document.classes) {
94939
- for (const referenceId3 of collectCompilerReferenceIds(schemaClass2)) {
94940
- if (constructorIds.has(referenceId3)) {
94941
- owners.set(referenceId3, schemaClass2.id);
96017
+ for (const referenceId4 of collectCompilerReferenceIds(schemaClass2)) {
96018
+ if (constructorIds.has(referenceId4)) {
96019
+ owners.set(referenceId4, schemaClass2.id);
94942
96020
  }
94943
96021
  }
94944
96022
  }
@@ -98966,10 +100044,10 @@ function extractProjectSnapshotDerivedEdges(source) {
98966
100044
  })
98967
100045
  });
98968
100046
  }
98969
- const constructorArgs = record7 === null ? null : asRecord3(record7.constructorArgs);
100047
+ const constructorArgs2 = record7 === null ? null : asRecord3(record7.constructorArgs);
98970
100048
  return {
98971
100049
  edges: [...edges.values()].sort(compareEdges),
98972
- complete: constructorArgs === null || Object.keys(constructorArgs).length === 0 || source.constructorAggregateEdges !== void 0
100050
+ complete: constructorArgs2 === null || Object.keys(constructorArgs2).length === 0 || source.constructorAggregateEdges !== void 0
98973
100051
  };
98974
100052
  }
98975
100053
  function addStampBindingEdges(genericBindings, add) {
@@ -101812,14 +102890,14 @@ function findParentValues(valueId, values) {
101812
102890
  }
101813
102891
  continue;
101814
102892
  }
101815
- if (!isStringRecord6(value.value)) continue;
102893
+ if (!isStringRecord7(value.value)) continue;
101816
102894
  for (const [key, childValueId2] of Object.entries(value.value)) {
101817
102895
  if (childValueId2 === valueId) parents.push({ value, key });
101818
102896
  }
101819
102897
  }
101820
102898
  return parents;
101821
102899
  }
101822
- function isStringRecord6(value) {
102900
+ function isStringRecord7(value) {
101823
102901
  if (typeof value !== "object") return false;
101824
102902
  if (value === null) return false;
101825
102903
  if (Array.isArray(value)) return false;
@@ -101996,9 +103074,16 @@ function compileDialogueLogicWithProjectData(request, projectData) {
101996
103074
  node: request.node,
101997
103075
  returnTypeInfo: sourceBacked ? request.textVariable.typeInfo : { type: 3 /* String */, required: true }
101998
103076
  });
103077
+ if (!sourceBacked)
103078
+ return {
103079
+ target: 2 /* TextVariable */,
103080
+ getter: compileTextVariableGetter(ctx2, request.textVariable)
103081
+ };
103082
+ const getter = request.textVariable.sourceInline ? compileNSInferredExpressionGetter(request.code, ctx2) : compileNSGetter(request.code, ctx2);
101999
103083
  return {
102000
103084
  target: 2 /* TextVariable */,
102001
- getter: sourceBacked ? stringifyCompiledTextGetter(compileNSGetter(request.code, ctx2)) : compileTextVariableGetter(ctx2, request.textVariable)
103085
+ getter: stringifyCompiledTextGetter(getter),
103086
+ sourceTypeInfo: getter.typeInfo
102002
103087
  };
102003
103088
  }
102004
103089
  if (request.dialogueGroup) {
@@ -102771,7 +103856,8 @@ function recompileDialogueNode(args) {
102771
103856
  (message) => ({
102772
103857
  target: 1 /* Action */,
102773
103858
  action: makeThrowBody(message, VOID_ACTION_TYPE_INFO)
102774
- })
103859
+ }),
103860
+ typeof logic.sourceFunctionId === "string" ? { id: logic.sourceFunctionId, code: logic.code } : void 0
102775
103861
  );
102776
103862
  if (!compiled.ok) continue;
102777
103863
  const response = compiled.value;
@@ -102861,7 +103947,8 @@ function recompileConditionList(value, context) {
102861
103947
  (message) => ({
102862
103948
  target: 0 /* Condition */,
102863
103949
  getter: makeThrowBody(message, BOOL_TYPE_INFO)
102864
- })
103950
+ }),
103951
+ typeof condition.sourceFunctionId === "string" ? { id: condition.sourceFunctionId, code: condition.code } : void 0
102865
103952
  );
102866
103953
  if (!compiled.ok) continue;
102867
103954
  const response = compiled.value;
@@ -102890,6 +103977,7 @@ function recompileTextVariables(value, context) {
102890
103977
  dialogue: context.dialogue,
102891
103978
  node: context.node,
102892
103979
  textVariable: {
103980
+ sourceInline: variable2.sourceInline === true,
102893
103981
  nodeId: context.nodeId,
102894
103982
  optionId: context.optionId,
102895
103983
  pointer: variable2.pointer,
@@ -102907,7 +103995,14 @@ function recompileTextVariables(value, context) {
102907
103995
  (message) => ({
102908
103996
  target: 2 /* TextVariable */,
102909
103997
  getter: makeThrowBody(message, STRING_TYPE_INFO)
102910
- })
103998
+ }),
103999
+ {
104000
+ id: variable2.sourceInline === true ? variableId : requiredString2(
104001
+ variable2.sourceFunctionId ?? variableId,
104002
+ "text source function id"
104003
+ ),
104004
+ code: typeof variable2.code === "string" ? variable2.code : ""
104005
+ }
102911
104006
  );
102912
104007
  if (!compiled.ok) continue;
102913
104008
  const response = compiled.value;
@@ -102915,6 +104010,7 @@ function recompileTextVariables(value, context) {
102915
104010
  throw new Error("Dialogue text-variable compilation returned code IR.");
102916
104011
  }
102917
104012
  variable2.getter = response.getter;
104013
+ if (response.sourceTypeInfo) variable2.typeInfo = response.sourceTypeInfo;
102918
104014
  changed = true;
102919
104015
  }
102920
104016
  return changed;
@@ -102933,7 +104029,7 @@ function buildDialogueContext(dialogue, nodes) {
102933
104029
  }
102934
104030
  };
102935
104031
  }
102936
- function compileSourceUnit(label, compile, onSourceRejection, compileErrorFallback) {
104032
+ function compileSourceUnit(label, compile, onSourceRejection, compileErrorFallback, body) {
102937
104033
  try {
102938
104034
  return { ok: true, value: compile() };
102939
104035
  } catch (error) {
@@ -102945,6 +104041,8 @@ function compileSourceUnit(label, compile, onSourceRejection, compileErrorFallba
102945
104041
  }
102946
104042
  return { ok: false };
102947
104043
  }
104044
+ if (error instanceof CompileError && body)
104045
+ throw new SourceBodyCompileError(label, body.id, body.code, error);
102948
104046
  throw new Error(`Cannot recompile ${label}: ${message}`, { cause: error });
102949
104047
  }
102950
104048
  }
@@ -102986,7 +104084,7 @@ function asObject(value) {
102986
104084
  function cloneObject(value) {
102987
104085
  return structuredClone(value);
102988
104086
  }
102989
- var VOID_ACTION_TYPE_INFO, BOOL_TYPE_INFO, STRING_TYPE_INFO;
104087
+ var SourceBodyCompileError, VOID_ACTION_TYPE_INFO, BOOL_TYPE_INFO, STRING_TYPE_INFO;
102990
104088
  var init_general_function_call_ir_source_recompile = __esm({
102991
104089
  "../src/database/general-function-call-ir-source-recompile.ts"() {
102992
104090
  "use strict";
@@ -103006,6 +104104,22 @@ var init_general_function_call_ir_source_recompile = __esm({
103006
104104
  init_dialogue_node_index();
103007
104105
  init_strict_ir();
103008
104106
  init_neo_script_derived_bodies();
104107
+ SourceBodyCompileError = class extends Error {
104108
+ constructor(sourceLabel, bodyId, code, compileError) {
104109
+ super(`Cannot recompile ${sourceLabel}: ${compileError.message}`, {
104110
+ cause: compileError
104111
+ });
104112
+ this.sourceLabel = sourceLabel;
104113
+ this.bodyId = bodyId;
104114
+ this.code = code;
104115
+ this.compileError = compileError;
104116
+ this.name = "SourceBodyCompileError";
104117
+ }
104118
+ sourceLabel;
104119
+ bodyId;
104120
+ code;
104121
+ compileError;
104122
+ };
103009
104123
  VOID_ACTION_TYPE_INFO = {
103010
104124
  type: 0 /* Null */,
103011
104125
  required: true
@@ -104642,9 +105756,9 @@ function assertNumberRange(member, value, path) {
104642
105756
  }
104643
105757
  }
104644
105758
  function stringRecord3(value) {
104645
- return isStringRecord7(value) ? value : null;
105759
+ return isStringRecord8(value) ? value : null;
104646
105760
  }
104647
- function isStringRecord7(value) {
105761
+ function isStringRecord8(value) {
104648
105762
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
104649
105763
  return false;
104650
105764
  }
@@ -106220,10 +107334,10 @@ function attachPreparedConstructorAggregateEdges(prepared, document) {
106220
107334
  );
106221
107335
  if (valueChanges.length === 0) return;
106222
107336
  const needsGraph = valueChanges.some((change) => {
106223
- const constructorArgs = asRecord4(
107337
+ const constructorArgs2 = asRecord4(
106224
107338
  asRecord4(change.nextData)?.constructorArgs
106225
107339
  );
106226
- return constructorArgs !== null && Object.keys(constructorArgs).length > 0;
107340
+ return constructorArgs2 !== null && Object.keys(constructorArgs2).length > 0;
106227
107341
  });
106228
107342
  const changedValueRows = /* @__PURE__ */ new Map();
106229
107343
  if (needsGraph) {
@@ -108761,16 +109875,16 @@ function collectDelegateSweepRows(args) {
108761
109875
  }
108762
109876
  function inlineDelegateSweepRow(value) {
108763
109877
  if (!isMemberValue(value) || !isLiteralValueContent(value)) return null;
108764
- const constructorArgs = asRecord4(
109878
+ const constructorArgs2 = asRecord4(
108765
109879
  value.constructorArgs
108766
109880
  );
108767
- if (constructorArgs === null) return null;
109881
+ if (constructorArgs2 === null) return null;
108768
109882
  let sourceArgs = null;
108769
- for (const [key, argument2] of Object.entries(constructorArgs)) {
109883
+ for (const [key, argument2] of Object.entries(constructorArgs2)) {
108770
109884
  const closure = asRecord4(argument2);
108771
109885
  if (typeof closure?.code !== "string") continue;
108772
109886
  if (!("action" in closure)) continue;
108773
- sourceArgs ??= { ...constructorArgs };
109887
+ sourceArgs ??= { ...constructorArgs2 };
108774
109888
  sourceArgs[key] = { code: closure.code };
108775
109889
  }
108776
109890
  return sourceArgs === null ? null : { ...value, constructorArgs: sourceArgs };
@@ -108784,11 +109898,11 @@ function delegateValueRow(value) {
108784
109898
  }
108785
109899
  function inlineDelegateArgumentRow(value) {
108786
109900
  if (!isMemberValue(value) || !isLiteralValueContent(value)) return null;
108787
- const constructorArgs = asRecord4(
109901
+ const constructorArgs2 = asRecord4(
108788
109902
  value.constructorArgs
108789
109903
  );
108790
- if (constructorArgs === null) return null;
108791
- for (const argument2 of Object.values(constructorArgs)) {
109904
+ if (constructorArgs2 === null) return null;
109905
+ for (const argument2 of Object.values(constructorArgs2)) {
108792
109906
  if (isUncompiledInlineDelegateArgument(argument2)) {
108793
109907
  return value;
108794
109908
  }
@@ -108803,8 +109917,8 @@ function isUncompiledInlineDelegateArgument(argument2) {
108803
109917
  }
108804
109918
  function compileInlineDelegateConstructorArguments(args) {
108805
109919
  const { document, row, ownerMember, rootOwner } = args;
108806
- const constructorArgs = asRecord4(row.constructorArgs);
108807
- if (constructorArgs === null) {
109920
+ const constructorArgs2 = asRecord4(row.constructorArgs);
109921
+ if (constructorArgs2 === null) {
108808
109922
  throw new Error(
108809
109923
  `Value "${row.id}" was collected for inline delegate compilation without constructor arguments.`
108810
109924
  );
@@ -108847,8 +109961,8 @@ function compileInlineDelegateConstructorArguments(args) {
108847
109961
  document.classes
108848
109962
  );
108849
109963
  const thisClass = findSchemaPlacement(rootOwner?.id ?? "", document.classes)?.ownerClass ?? null;
108850
- const compiled = { ...constructorArgs };
108851
- for (const [argumentKey, argument2] of Object.entries(constructorArgs)) {
109964
+ const compiled = { ...constructorArgs2 };
109965
+ for (const [argumentKey, argument2] of Object.entries(constructorArgs2)) {
108852
109966
  if (!isUncompiledInlineDelegateArgument(argument2)) continue;
108853
109967
  const match = /^__arg_(\d+)__$/.exec(argumentKey);
108854
109968
  if (match === null) {
@@ -114744,12 +115858,7 @@ function schemaKeyToMemberName(schemaKey) {
114744
115858
  return generatedCSharpMemberNameForSchemaKey(schemaKey);
114745
115859
  }
114746
115860
  function toCSharpTypeName(value, fallback) {
114747
- const parts = value.match(/[A-Za-z0-9]+/g) ?? [];
114748
- const joined = parts.map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join("");
114749
- const candidate = joined.length > 0 ? joined : fallback;
114750
- const safe = /^[0-9]/.test(candidate) ? `_${candidate}` : candidate;
114751
- if (isCSharpReservedKeyword(safe)) return `${safe}Type`;
114752
- return safe;
115861
+ return generatedCSharpTypeName(value, fallback);
114753
115862
  }
114754
115863
  var init_csharp_identifiers = __esm({
114755
115864
  "../src/models/exports/unity-codegen/csharp-identifiers.ts"() {
@@ -117676,7 +118785,7 @@ function collectProjectDocumentTileGridReferenceBlockers(args) {
117676
118785
  ownerValue: gridValue,
117677
118786
  keyCandidates: root.keyCandidates
117678
118787
  });
117679
- for (const referenceId3 of referenceIds) {
118788
+ for (const referenceId4 of referenceIds) {
117680
118789
  pushWorldReferenceDeleteBlockers({
117681
118790
  graph: args.graph,
117682
118791
  deletedClassIds: args.deletedClassIds,
@@ -117685,7 +118794,7 @@ function collectProjectDocumentTileGridReferenceBlockers(args) {
117685
118794
  gridValueId: gridValue.id,
117686
118795
  location: `${root.locationLabel} on grid "${gridValue.id}"`,
117687
118796
  referenceKind: root.referenceKind,
117688
- referencedValueId: referenceId3
118797
+ referencedValueId: referenceId4
117689
118798
  });
117690
118799
  }
117691
118800
  }
@@ -117805,7 +118914,7 @@ function toWorldReferenceClassRecord(value) {
117805
118914
  return {
117806
118915
  id: id2,
117807
118916
  extendsClassId: nullableStringField(value, "extendsClassId"),
117808
- schema: isStringRecord8(value.schema) ? value.schema : void 0,
118917
+ schema: isStringRecord9(value.schema) ? value.schema : void 0,
117809
118918
  system: isPlainRecord7(value.system) ? value.system : null
117810
118919
  };
117811
118920
  }
@@ -117823,7 +118932,7 @@ function worldReferenceValueClassId(value) {
117823
118932
  if (value === void 0) return null;
117824
118933
  return typeof value.classId === "string" && value.classId.length > 0 ? value.classId : null;
117825
118934
  }
117826
- function isStringRecord8(value) {
118935
+ function isStringRecord9(value) {
117827
118936
  if (!isPlainRecord7(value)) return false;
117828
118937
  return Object.values(value).every((entry) => typeof entry === "string");
117829
118938
  }
@@ -122368,7 +123477,7 @@ function lowerReferenceValue(expression) {
122368
123477
  if (target?.kind === "litString") return target.value;
122369
123478
  const path = target === void 0 ? null : dottedPath(target);
122370
123479
  if (path === null || !path.startsWith("root.")) return null;
122371
- return referenceId(`Reference(${path})`);
123480
+ return referenceId2(`Reference(${path})`);
122372
123481
  }
122373
123482
  function dottedPath(expression) {
122374
123483
  const parts = [];
@@ -122839,7 +123948,8 @@ function builtinTextVariableMember(receiver, name) {
122839
123948
  }
122840
123949
  return null;
122841
123950
  }
122842
- function lowerDialogueProjectSourcesV4(state, analysis) {
123951
+ function lowerDialogueProjectSourcesV4(state, analysis, options = {}) {
123952
+ const sourceCapture = options.sourceCapture;
122843
123953
  const result = [];
122844
123954
  const mainLocale = readMainLocale(state);
122845
123955
  const dialogueGroups = analysis.dialogueGroups.globals.filter(
@@ -122852,98 +123962,167 @@ function lowerDialogueProjectSourcesV4(state, analysis) {
122852
123962
  ).map((global) => dialogueGroupIds.get(global.name))
122853
123963
  );
122854
123964
  const priorityGroupsById = recordsById(state, "priority-group");
123965
+ const groupPaths = new DialogueGroupPaths(
123966
+ dialogueGroups.map((global) => {
123967
+ const id2 = dialogueGroupIds.get(global.name);
123968
+ const data = baseData2(state, "dialogue-group", id2);
123969
+ return {
123970
+ id: id2,
123971
+ symbol: global.name,
123972
+ name: typeof data.name === "string" ? data.name : global.name,
123973
+ parentId: nullableString4(data.parentDialogueGroupId),
123974
+ priorityGroupId: nullableString4(data.priorityGroupIdOverride)
123975
+ };
123976
+ }),
123977
+ [...priorityGroupsById].map(
123978
+ ([id2, data]) => [
123979
+ id2,
123980
+ (Array.isArray(data.options) ? data.options : []).flatMap(
123981
+ (option) => isObjectRecord2(option) && typeof option.id === "string" && typeof option.name === "string" ? [{ id: option.id, name: option.name }] : []
123982
+ )
123983
+ ]
123984
+ ),
123985
+ defaultPriorityGroupId(state)
123986
+ );
122855
123987
  const sourceSchema = new SourceSchemaIndex(analysis);
122856
123988
  const valueSymbols = indexValueSymbols(state, analysis);
122857
123989
  const nodesByDialogueId = dialogueNodesByDialogueId(state);
123990
+ let referenceTypeIndex;
123991
+ const referenceTypes = () => referenceTypeIndex ??= new ReferenceTargetTypes(
123992
+ state,
123993
+ options.authoredValueSeeds,
123994
+ [],
123995
+ options.manifest
123996
+ );
122858
123997
  for (const dialogue of analysis.dialogues.dialogues) {
122859
- const dialogueId = sourceId2(dialogue, "dialogue", dialogue.name);
122860
- const baseDialogue = baseData2(state, "dialogue", dialogueId);
122861
- const nodesById = nodesByDialogueId.get(dialogueId) ?? /* @__PURE__ */ new Map();
122862
- const memberIdsByName = new Map(
122863
- dialogue.members.map((member) => [
122864
- member.name,
122865
- sourceId2(member, "dialogue-node", member.name)
122866
- ])
122867
- );
122868
- const functionsByName = new Map(
122869
- dialogue.functions.map((fn) => [fn.name, fn])
122870
- );
122871
- const context = {
122872
- state,
122873
- dialogue,
122874
- dialogueId,
122875
- baseDialogue,
122876
- nodesById,
122877
- memberIdsByName,
122878
- functionsByName,
122879
- existingLogic: indexExistingLogic(nodesById.values()),
122880
- mainLocale,
122881
- dialogueGroupIds,
122882
- lookupDialogueGroupIds,
122883
- priorityGroupsById,
122884
- valueSymbols,
122885
- sourceSchema,
122886
- dialogueBindingTypes: new Map(
122887
- dialogue.bindings.map((binding) => [binding.name, binding.type])
122888
- ),
122889
- dialogueLinks: Array.isArray(baseDialogue.linkedValues) ? baseDialogue.linkedValues.filter(isObjectRecord2) : [],
122890
- dialoguePrimaryValueId: nullableString4(baseDialogue.primaryLinkedValueId),
122891
- sourcePrimaryAlias: primaryBindingName(dialogue.bindings)
122892
- };
122893
- const trigger = dialogue.members.find(
122894
- (member) => member.graphType === "Trigger"
122895
- );
122896
- if (!trigger)
122897
- throw new Error(`Dialogue ${dialogue.name} requires Trigger.`);
122898
- const settings = annotationArguments(dialogue.annotations, "settings");
122899
- const linked = lowerBindings(
122900
- context,
122901
- dialogue.bindings,
122902
- baseDialogue.linkedValues
122903
- );
122904
- const primary = primaryValueId(dialogue.bindings, linked);
122905
- const graphContext = {
122906
- ...context,
122907
- dialogueLinks: linked,
122908
- dialoguePrimaryValueId: primary
122909
- };
122910
- const description = lowerDialogueDescription(
122911
- context,
122912
- settings.get("description"),
122913
- result
122914
- );
122915
- result.push(
122916
- reconstructed2(
122917
- "dialogue",
123998
+ try {
123999
+ const dialogueId = sourceId2(dialogue, "dialogue", dialogue.name);
124000
+ const baseDialogue = baseData2(state, "dialogue", dialogueId);
124001
+ const nodesById = nodesByDialogueId.get(dialogueId) ?? /* @__PURE__ */ new Map();
124002
+ const memberIdsByName = new Map(
124003
+ dialogue.members.map((member) => [
124004
+ member.name,
124005
+ sourceId2(member, "dialogue-node", member.name)
124006
+ ])
124007
+ );
124008
+ const functionsByName = new Map(
124009
+ dialogue.functions.map((fn) => [fn.name, fn])
124010
+ );
124011
+ const context = {
124012
+ groupPaths,
124013
+ sourceCapture,
124014
+ referenceTypes,
124015
+ state,
124016
+ dialogue,
122918
124017
  dialogueId,
122919
- {
122920
- ...baseDialogue,
122921
- id: dialogueId,
122922
- sourceName: dialogue.name,
122923
- name: literalString(settings.get("name")) ?? stringOr(baseDialogue.name, dialogue.name),
122924
- description,
122925
- settings: {
122926
- ...isObjectRecord2(baseDialogue.settings) ? baseDialogue.settings : {},
122927
- defaultSaveOptionChoices: literalBoolean(settings.get("saveOptionChoices")) ?? booleanOr(
122928
- isObjectRecord2(baseDialogue.settings) ? baseDialogue.settings.defaultSaveOptionChoices : void 0,
122929
- true
122930
- )
124018
+ baseDialogue,
124019
+ nodesById,
124020
+ memberIdsByName,
124021
+ functionsByName,
124022
+ existingLogic: indexExistingLogic(nodesById.values()),
124023
+ mainLocale,
124024
+ dialogueGroupIds,
124025
+ lookupDialogueGroupIds,
124026
+ priorityGroupsById,
124027
+ valueSymbols,
124028
+ sourceSchema,
124029
+ dialogueBindingTypes: new Map(
124030
+ dialogue.bindings.map((binding) => [binding.name, binding.type])
124031
+ ),
124032
+ dialogueLinks: Array.isArray(baseDialogue.linkedValues) ? baseDialogue.linkedValues.filter(isObjectRecord2) : [],
124033
+ dialoguePrimaryValueId: nullableString4(
124034
+ baseDialogue.primaryLinkedValueId
124035
+ ),
124036
+ sourcePrimaryAlias: primaryBindingName(dialogue.bindings)
124037
+ };
124038
+ const trigger = dialogue.members.find(
124039
+ (member) => member.graphType === "Trigger"
124040
+ );
124041
+ if (!trigger)
124042
+ throw new Error(`Dialogue ${dialogue.name} requires Trigger.`);
124043
+ const settings = annotationArguments(dialogue.annotations, "settings");
124044
+ const linked = lowerBindings(
124045
+ context,
124046
+ dialogue.bindings,
124047
+ baseDialogue.linkedValues
124048
+ );
124049
+ const primary = primaryValueId(dialogue.bindings, linked);
124050
+ const graphContext = {
124051
+ ...context,
124052
+ dialogueLinks: linked,
124053
+ dialoguePrimaryValueId: primary
124054
+ };
124055
+ const description = lowerDialogueDescription(
124056
+ context,
124057
+ settings.get("description"),
124058
+ result
124059
+ );
124060
+ result.push(
124061
+ reconstructed2(
124062
+ "dialogue",
124063
+ dialogueId,
124064
+ {
124065
+ ...baseDialogue,
124066
+ id: dialogueId,
124067
+ sourceName: dialogue.name,
124068
+ name: authoredDisplayName(
124069
+ settings.get("name"),
124070
+ dialogue.name,
124071
+ "Dialogue"
124072
+ ) ?? "",
124073
+ description,
124074
+ settings: {
124075
+ ...isObjectRecord2(baseDialogue.settings) ? baseDialogue.settings : {},
124076
+ defaultSaveOptionChoices: literalBoolean(settings.get("saveOptionChoices")) ?? booleanOr(
124077
+ isObjectRecord2(baseDialogue.settings) ? baseDialogue.settings.defaultSaveOptionChoices : void 0,
124078
+ true
124079
+ )
124080
+ },
124081
+ linkedValues: linked,
124082
+ primaryLinkedValueId: primary,
124083
+ triggerNodeId: sourceId2(trigger, "dialogue-node", trigger.name)
122931
124084
  },
122932
- linkedValues: linked,
122933
- primaryLinkedValueId: primary,
122934
- triggerNodeId: sourceId2(trigger, "dialogue-node", trigger.name)
122935
- },
122936
- dialogue
122937
- )
122938
- );
122939
- dialogue.members.forEach((member, index) => {
122940
- const lowered = lowerGraphMember(graphContext, member, index);
122941
- result.push(...lowered);
122942
- });
124085
+ dialogue
124086
+ )
124087
+ );
124088
+ dialogue.members.forEach((member, index) => {
124089
+ try {
124090
+ result.push(
124091
+ ...lowerGraphMember(
124092
+ {
124093
+ ...graphContext,
124094
+ sourceOwnerName: `${dialogue.name}.${member.name}`
124095
+ },
124096
+ member,
124097
+ index
124098
+ )
124099
+ );
124100
+ } catch (error) {
124101
+ throw dialogueSourceError(error, member.source);
124102
+ }
124103
+ });
124104
+ } catch (error) {
124105
+ throw dialogueSourceError(error, dialogue.source);
124106
+ }
122943
124107
  }
122944
124108
  return result;
122945
124109
  }
124110
+ function dialogueSourceError(error, source) {
124111
+ if (error instanceof SchemaSourceError) return error;
124112
+ return new SchemaSourceError(
124113
+ error instanceof Error ? error.message : String(error),
124114
+ source.uri,
124115
+ source.range.start.line + 1,
124116
+ source.range.start.character + 1,
124117
+ "neoflow-lowering",
124118
+ "error",
124119
+ source.range
124120
+ );
124121
+ }
122946
124122
  function lowerGraphMember(context, member, index) {
124123
+ const graphType = member.graphType;
124124
+ if (graphType !== "Trigger" && graphType !== "Text" && graphType !== "Actions" && graphType !== "Conditions")
124125
+ throw new Error(`Unsupported NeoFlow graph type ${graphType}.`);
122947
124126
  const id2 = sourceId2(member, "dialogue-node", member.name);
122948
124127
  const base = context.nodesById.get(id2) ?? {};
122949
124128
  const linkedValues = lowerNodeBindings(
@@ -122955,7 +124134,7 @@ function lowerGraphMember(context, member, index) {
122955
124134
  linkedValues,
122956
124135
  deriveLogicLinks(context, member)
122957
124136
  );
122958
- if (member.graphType === "Trigger") {
124137
+ if (graphType === "Trigger") {
122959
124138
  effectiveLinkedValues = effectiveLinkedValues.map((link) => {
122960
124139
  const inherited = context.dialogueLinks.find(
122961
124140
  (candidate) => candidate.valueId === link.valueId
@@ -122969,7 +124148,11 @@ function lowerGraphMember(context, member, index) {
122969
124148
  id: id2,
122970
124149
  dialogueId: context.dialogueId,
122971
124150
  sourceName: member.name,
122972
- name: constructorString(member.arguments, "name") ?? nullableString4(base.name),
124151
+ name: graphType === "Trigger" ? nullableString4(base.name) : authoredDisplayName(
124152
+ constructorExpression(member.arguments, "name") ?? void 0,
124153
+ member.name,
124154
+ graphType
124155
+ ),
122973
124156
  layout: isObjectRecord2(base.layout) ? base.layout : { x: 0, y: index * 200, width: 320, height: 160, isOpen: true },
122974
124157
  linkedValues: effectiveLinkedValues,
122975
124158
  primaryLinkedValueId: primaryValueId(member.content?.bindings ?? [], effectiveLinkedValues) ?? nullableString4(base.primaryLinkedValueId)
@@ -122979,7 +124162,7 @@ function lowerGraphMember(context, member, index) {
122979
124162
  member.destination,
122980
124163
  nullableString4(base.toNodeId)
122981
124164
  );
122982
- if (member.graphType === "Trigger") {
124165
+ if (graphType === "Trigger") {
122983
124166
  return [
122984
124167
  reconstructed2(
122985
124168
  "dialogue-node",
@@ -123004,10 +124187,10 @@ function lowerGraphMember(context, member, index) {
123004
124187
  )
123005
124188
  ];
123006
124189
  }
123007
- if (member.graphType === "Text") {
124190
+ if (graphType === "Text") {
123008
124191
  return lowerTextNode(context, member, id2, base, common, destination);
123009
124192
  }
123010
- if (member.graphType === "Actions") {
124193
+ if (graphType === "Actions") {
123011
124194
  return [
123012
124195
  reconstructed2(
123013
124196
  "dialogue-node",
@@ -123028,22 +124211,19 @@ function lowerGraphMember(context, member, index) {
123028
124211
  )
123029
124212
  ];
123030
124213
  }
123031
- if (member.graphType === "Conditions") {
123032
- return [
123033
- reconstructed2(
123034
- "dialogue-node",
123035
- id2,
123036
- {
123037
- ...common,
123038
- type: 3,
123039
- outcomes: lowerOutcomes(context, member.content, id2, base.outcomes),
123040
- toNodeId: void 0
123041
- },
123042
- member
123043
- )
123044
- ];
123045
- }
123046
- throw new Error(`Unsupported NeoFlow graph type ${member.graphType}.`);
124214
+ return [
124215
+ reconstructed2(
124216
+ "dialogue-node",
124217
+ id2,
124218
+ {
124219
+ ...common,
124220
+ type: 3,
124221
+ outcomes: lowerOutcomes(context, member.content, id2, base.outcomes),
124222
+ toNodeId: void 0
124223
+ },
124224
+ member
124225
+ )
124226
+ ];
123047
124227
  }
123048
124228
  function lowerTextNode(context, member, id2, base, common, destination) {
123049
124229
  const prose = requireProse(member.content, `Text ${member.name}`);
@@ -123061,7 +124241,8 @@ function lowerTextNode(context, member, id2, base, common, destination) {
123061
124241
  nullableString4(common.primaryLinkedValueId) ?? context.dialoguePrimaryValueId,
123062
124242
  `node:${id2}`,
123063
124243
  dialogueNodeLocalizedTextLink(id2),
123064
- member
124244
+ member,
124245
+ member.content?.proseSources?.[0]
123065
124246
  );
123066
124247
  const children = member.content?.children.filter((child2) => child2.graphType === "Option") ?? [];
123067
124248
  const baseOptionSettings = isObjectRecord2(base.optionSettings) ? base.optionSettings : {};
@@ -123087,7 +124268,8 @@ function lowerTextNode(context, member, id2, base, common, destination) {
123087
124268
  nullableString4(common.primaryLinkedValueId) ?? context.dialoguePrimaryValueId,
123088
124269
  `option:${optionId}`,
123089
124270
  dialogueChoiceLocalizedTextLink(id2, optionId),
123090
- child2
124271
+ child2,
124272
+ child2.content?.proseSources?.[0]
123091
124273
  );
123092
124274
  if (optionText.textRecord) textRecords.push(optionText.textRecord);
123093
124275
  const priorSettings = isObjectRecord2(optionBase.settings) ? optionBase.settings : {};
@@ -123101,7 +124283,11 @@ function lowerTextNode(context, member, id2, base, common, destination) {
123101
124283
  ...optionBase,
123102
124284
  id: optionId,
123103
124285
  sourceName: child2.name,
123104
- name: constructorString(child2.arguments, "name") ?? nullableString4(optionBase.name),
124286
+ name: authoredDisplayName(
124287
+ constructorExpression(child2.arguments, "name") ?? void 0,
124288
+ child2.name,
124289
+ "Option"
124290
+ ),
123105
124291
  text: optionText.textId,
123106
124292
  variables: optionText.variables,
123107
124293
  toNodeId: requiredDestination(
@@ -123252,7 +124438,11 @@ function lowerOutcomes(context, content, nodeId, rawBaseOutcomes) {
123252
124438
  ...base,
123253
124439
  id: id2,
123254
124440
  sourceName: child2.name,
123255
- name: constructorString(child2.arguments, "name") ?? child2.name,
124441
+ name: authoredDisplayName(
124442
+ constructorExpression(child2.arguments, "name") ?? void 0,
124443
+ child2.name,
124444
+ "Outcome"
124445
+ ) ?? "",
123256
124446
  conditions: lowerConditionUses(
123257
124447
  context,
123258
124448
  constructorExpression(child2.arguments, "when"),
@@ -123285,6 +124475,14 @@ function lowerConditionUses(context, expression, owner) {
123285
124475
  `${owner} condition ${use.name} must resolve to a zero-argument bool function.`
123286
124476
  );
123287
124477
  }
124478
+ context.sourceCapture?.bodies.set(
124479
+ sourceId2(fn, "dialogue-function", fn.name),
124480
+ {
124481
+ name: `${context.dialogue.name}.${fn.name}`,
124482
+ location: fn.bodySource ?? fn.source,
124483
+ thisAlias: context.sourcePrimaryAlias ?? void 0
124484
+ }
124485
+ );
123288
124486
  const prior = context.existingLogic.conditionsByUseId.get(id2);
123289
124487
  const body = functionCode(fn);
123290
124488
  if (body === null) {
@@ -123359,6 +124557,14 @@ function conditionProjectionMatches(context, prior, body) {
123359
124557
  return false;
123360
124558
  }
123361
124559
  function lowerActionLogic(context, prior, fn, fallbackCode, inline, useId, uiResolver) {
124560
+ context.sourceCapture?.bodies.set(
124561
+ inline ? useId : sourceId2(fn, "dialogue-function", fn.name),
124562
+ {
124563
+ name: inline ? `${context.sourceOwnerName} action` : `${context.dialogue.name}.${fn.name}`,
124564
+ location: fn.bodySource ?? fn.source,
124565
+ thisAlias: context.sourcePrimaryAlias ?? void 0
124566
+ }
124567
+ );
123362
124568
  const code = functionCode(fn) ?? fallbackCode;
123363
124569
  if (prior?.type === 0) {
123364
124570
  const projected = uiActionSource(prior.action, uiResolver);
@@ -123385,7 +124591,7 @@ function lowerActionLogic(context, prior, fn, fallbackCode, inline, useId, uiRes
123385
124591
  action: isObjectRecord2(prior?.action) ? prior.action : placeholderVoidAction()
123386
124592
  };
123387
124593
  }
123388
- function lowerProse(context, rawProse, baseTextId, baseVariables, baseLinks, bindingTypes, primaryValueId2, owner, textLink, source) {
124594
+ function lowerProse(context, rawProse, baseTextId, baseVariables, baseLinks, bindingTypes, primaryValueId2, owner, textLink, source, proseSource) {
123389
124595
  const textId = baseTextId ?? pendingId("localized-text", source.source.uri, owner, 0, "text");
123390
124596
  const baseText = baseData2(context.state, "localized-text", textId);
123391
124597
  const variablesByPath = /* @__PURE__ */ new Map();
@@ -123417,8 +124623,13 @@ function lowerProse(context, rawProse, baseTextId, baseVariables, baseLinks, bin
123417
124623
  const main2 = isObjectRecord2(mainCandidate) ? mainCandidate : {};
123418
124624
  const pulledMainText = typeof main2.value === "string" ? main2.value : "";
123419
124625
  let ordinal = 0;
124626
+ let expressionOrdinal = 0;
124627
+ const rawExpressions = context.sourceCapture ? decodeProseSegments(rawProse, false).filter(
124628
+ (segment) => segment.kind === "expression"
124629
+ ) : [];
123420
124630
  const value = decodeProseSegments(rawProse).map((segment) => {
123421
124631
  if (segment.kind === "literal") return segment.value;
124632
+ const rawExpression = rawExpressions[expressionOrdinal++];
123422
124633
  const expression = segment.value;
123423
124634
  const sourcePath = expression.trim();
123424
124635
  const missingVariableId = missingTextVariableId(sourcePath);
@@ -123451,6 +124662,30 @@ function lowerProse(context, rawProse, baseTextId, baseVariables, baseLinks, bin
123451
124662
  const functionName = callExpressionName(sourcePath) ?? `TextValue${ordinal + 1}`;
123452
124663
  const fn = callExpressionName(sourcePath) ? context.functionsByName.get(functionName) : void 0;
123453
124664
  const functionBody = fn ? functionCode(fn) : null;
124665
+ const capture = context.sourceCapture;
124666
+ if (capture) {
124667
+ let location3 = source.source;
124668
+ const text = capture.texts.get(location3.uri);
124669
+ if (text !== void 0 && proseSource && rawExpression) {
124670
+ const file = text;
124671
+ const start = file.offsetAt(proseSource.range.start) + 3;
124672
+ location3 = {
124673
+ uri: location3.uri,
124674
+ range: {
124675
+ start: file.positionAt(start + rawExpression.start),
124676
+ end: file.positionAt(start + rawExpression.end)
124677
+ }
124678
+ };
124679
+ }
124680
+ const bodyId = fn ? sourceId2(fn, "dialogue-function", fn.name) : variableId;
124681
+ const effectivePrimaryAlias = typeof primaryAlias === "string" ? primaryAlias : void 0;
124682
+ if (!capture.bodies.has(bodyId))
124683
+ capture.bodies.set(bodyId, {
124684
+ name: fn ? `${context.dialogue.name}.${fn.name}` : `${context.sourceOwnerName} interpolation`,
124685
+ location: fn?.bodySource ?? fn?.source ?? location3,
124686
+ thisAlias: fn ? context.sourcePrimaryAlias ?? void 0 : effectivePrimaryAlias
124687
+ });
124688
+ }
123454
124689
  if (prior !== void 0 && (fn === void 0 || functionBody === null)) {
123455
124690
  const declaredFunction = fn ?? sourceFunctionForPrior(context, prior);
123456
124691
  variables[variableId] = declaredFunction ? {
@@ -123490,7 +124725,7 @@ function lowerProse(context, rawProse, baseTextId, baseVariables, baseLinks, bin
123490
124725
  bindingTypes,
123491
124726
  primaryValueId2
123492
124727
  );
123493
- const sourceTypeInfo = fn ? sourceReturnTypeInfo(fn.type.name, fn.type.nullable) : directMetadata?.typeInfo ?? (isObjectRecord2(prior?.typeInfo) ? prior.typeInfo : { type: 3 /* String */, required: true });
124728
+ const sourceTypeInfo = fn ? sourceReturnTypeInfo(fn.type.name, fn.type.nullable) : directMetadata?.typeInfo ?? (isObjectRecord2(prior?.typeInfo) ? prior.typeInfo : { type: NS_TYPE_UNKNOWN, required: true });
123494
124729
  variables[variableId] = {
123495
124730
  ...prior ?? {},
123496
124731
  id: variableId,
@@ -123746,12 +124981,33 @@ function lowerBindings(context, bindings, baseLinks) {
123746
124981
  const explicit = bindings.map((binding) => {
123747
124982
  if (binding.initializer === null)
123748
124983
  throw new Error(`Binding ${binding.name} requires an initializer.`);
123749
- const valueId = resolveBindingValueId(
123750
- context,
123751
- binding.initializer,
123752
- existing,
123753
- binding.name
123754
- );
124984
+ let valueId;
124985
+ try {
124986
+ const expression = parseExpression(binding.initializer);
124987
+ valueId = resolveBindingValueId(
124988
+ context,
124989
+ binding.initializer,
124990
+ binding.name,
124991
+ expression
124992
+ );
124993
+ if (expression.kind === "call" && expression.callee.kind === "ident" && expression.callee.name === "Reference") {
124994
+ const explicit2 = expression.typeArguments?.[0];
124995
+ if (explicit2) {
124996
+ const name = astTypeNameV4(explicit2);
124997
+ context.referenceTypes().assertAssignable(valueId, name, `Reference<${name}>`);
124998
+ }
124999
+ }
125000
+ context.referenceTypes().assertAssignable(
125001
+ valueId,
125002
+ binding.type.name,
125003
+ `Binding ${binding.name}`
125004
+ );
125005
+ } catch (error) {
125006
+ throw dialogueSourceError(
125007
+ error,
125008
+ binding.initializerSource ?? binding.source
125009
+ );
125010
+ }
123755
125011
  const previous = existing.find(
123756
125012
  (link) => link.valueId === valueId || link.sourceName === binding.name
123757
125013
  );
@@ -123793,7 +125049,8 @@ function lowerNodeBindings(context, content, baseLinks) {
123793
125049
  (binding) => ({
123794
125050
  id: null,
123795
125051
  state: "pending",
123796
- source: context.dialogue.source,
125052
+ source: binding.source ?? context.dialogue.source,
125053
+ initializerSource: binding.source,
123797
125054
  kind: "field",
123798
125055
  name: binding.name,
123799
125056
  type: parseManifestTypeText(binding.type),
@@ -123870,31 +125127,33 @@ function parseManifestTypeText(source) {
123870
125127
  }
123871
125128
  return result;
123872
125129
  }
123873
- function resolveBindingValueId(context, initializer, existing, sourceName) {
123874
- const idMatch = initializer.match(
123875
- /\bReference(?:<[^>]+>)?\s*\(\s*(?:id\s*:\s*)?("(?:[^"\\]|\\.)*")\s*\)/
123876
- );
123877
- if (idMatch?.[1]) return JSON.parse(idMatch[1]);
125130
+ function resolveBindingValueId(context, initializer, sourceName, expression) {
125131
+ if (expression.kind === "call" && expression.callee.kind === "ident" && expression.callee.name === "Reference") {
125132
+ const idIndex = expression.argumentNames?.indexOf("id") ?? -1;
125133
+ if (idIndex >= 0) {
125134
+ const id2 = expression.args[idIndex];
125135
+ if (id2?.kind === "litString") return id2.value;
125136
+ }
125137
+ if (expression.argumentNames?.includes("key"))
125138
+ throw new Error(
125139
+ `Binding ${sourceName}: Reference(key:) requires a lookup field's collection context. Use Reference<T>(id: "...").`
125140
+ );
125141
+ }
123878
125142
  const direct = directValueSymbol(initializer);
123879
125143
  if (direct !== null) {
123880
125144
  const symbol = context.valueSymbols.get(direct);
123881
125145
  if (symbol !== void 0) return symbol.valueId;
123882
125146
  }
123883
- const byName = existing.find((link) => link.sourceName === sourceName);
123884
- if (typeof byName?.valueId === "string") return byName.valueId;
123885
- if (existing.length === 1 && typeof existing[0]?.valueId === "string") {
123886
- return existing[0].valueId;
123887
- }
123888
125147
  throw new Error(
123889
125148
  `Binding ${sourceName} initializer ${JSON.stringify(initializer)} cannot be resolved to a stable value. Use Reference<T>(id: "...").`
123890
125149
  );
123891
125150
  }
123892
125151
  function directValueSymbol(initializer) {
123893
125152
  const trimmed = initializer.trim();
123894
- if (/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)+$/.test(trimmed)) {
125153
+ if (/^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(trimmed)) {
123895
125154
  return trimmed;
123896
125155
  }
123897
- const reference2 = /^Reference(?:<[^>]+>)?\s*\(\s*([A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)+)\s*\)$/.exec(
125156
+ const reference2 = /^Reference(?:<[^>]+>)?\s*\(\s*([A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*)\s*\)$/.exec(
123898
125157
  trimmed
123899
125158
  );
123900
125159
  return reference2?.[1] ?? null;
@@ -124041,32 +125300,41 @@ function proseExpressions(raw) {
124041
125300
  );
124042
125301
  }
124043
125302
  function lowerDialogueGroupSettings(context, member, base) {
125303
+ const groupSource = member.arguments.find((argument2) => argument2.name === "group")?.source ?? member.source;
125304
+ const prioritySource = member.arguments.find((argument2) => argument2.name === "priority")?.source ?? groupSource;
124044
125305
  const expression = constructorExpression(member.arguments, "group");
124045
125306
  if (expression === null) return null;
124046
125307
  const old = isObjectRecord2(base.dialogueGroupSettings) ? base.dialogueGroupSettings : {};
124047
- const referencedGroupId = referenceId2(expression, "DialogueGroup");
125308
+ const referencedGroupId = referenceId3(expression, "DialogueGroup");
124048
125309
  if (referencedGroupId !== null) {
124049
- if (![...context.dialogueGroupIds.values()].includes(referencedGroupId)) {
124050
- throw new Error(`Unknown dialogue group ${referencedGroupId}.`);
125310
+ if (!context.groupPaths.byId.has(referencedGroupId)) {
125311
+ throw dialogueSourceError(
125312
+ `Unknown dialogue group ${referencedGroupId}.`,
125313
+ groupSource
125314
+ );
124051
125315
  }
124052
- const group2 = baseData2(context.state, "dialogue-group", referencedGroupId);
124053
- const priorityGroupId2 = nullableString4(group2.priorityGroupIdOverride) ?? defaultPriorityGroupId(context.state);
124054
- const priority2 = priorityGroupId2 ? context.priorityGroupsById.get(priorityGroupId2) : void 0;
124055
- const options2 = Array.isArray(priority2?.options) ? priority2.options : [];
125316
+ const group = baseData2(context.state, "dialogue-group", referencedGroupId);
125317
+ const priorityGroupId = nullableString4(group.priorityGroupIdOverride) ?? defaultPriorityGroupId(context.state);
125318
+ const priority = priorityGroupId ? context.priorityGroupsById.get(priorityGroupId) : void 0;
125319
+ const options = Array.isArray(priority?.options) ? priority.options : [];
124056
125320
  const priorityExpression = constructorExpression(
124057
125321
  member.arguments,
124058
125322
  "priority"
124059
125323
  );
124060
- const priorityOptionId = priorityExpression === null ? null : referenceId2(priorityExpression, "PriorityOption");
125324
+ const priorityOptionId = priorityExpression === null ? null : referenceId3(priorityExpression, "PriorityOption");
124061
125325
  if (priorityExpression !== null && priorityOptionId === null) {
124062
- throw new Error(
124063
- 'Trigger priority must be authored as Reference<PriorityOption>(id: "...").'
125326
+ throw dialogueSourceError(
125327
+ 'Trigger priority must be authored as Reference<PriorityOption>(id: "...").',
125328
+ prioritySource
124064
125329
  );
124065
125330
  }
124066
- if (priorityOptionId !== null && !options2.some(
125331
+ if (priorityOptionId !== null && !options.some(
124067
125332
  (candidate) => isObjectRecord2(candidate) && candidate.id === priorityOptionId
124068
125333
  )) {
124069
- throw new Error(`Unknown priority option ${priorityOptionId}.`);
125334
+ throw dialogueSourceError(
125335
+ `Unknown priority option ${priorityOptionId}.`,
125336
+ prioritySource
125337
+ );
124070
125338
  }
124071
125339
  return {
124072
125340
  ...old,
@@ -124079,41 +125347,53 @@ function lowerDialogueGroupSettings(context, member, base) {
124079
125347
  }
124080
125348
  };
124081
125349
  }
124082
- const [groupName, optionName] = expression.split(".");
124083
- if (!groupName || !optionName) {
124084
- throw new Error(
124085
- `Trigger group must be authored as DialogueGroup.PriorityOption.`
125350
+ const groupPath = expression.split(/\s*\.\s*/u);
125351
+ const resolved = context.groupPaths.resolve(groupPath);
125352
+ if (!resolved)
125353
+ throw dialogueSourceError(
125354
+ context.groupPaths.failure(groupPath),
125355
+ groupSource
124086
125356
  );
124087
- }
124088
- const groupId = context.dialogueGroupIds.get(groupName);
124089
- if (!groupId) throw new Error(`Unknown dialogue group ${groupName}.`);
124090
- const group = baseData2(context.state, "dialogue-group", groupId);
124091
- const priorityGroupId = nullableString4(group.priorityGroupIdOverride) ?? defaultPriorityGroupId(context.state);
124092
- const priority = priorityGroupId ? context.priorityGroupsById.get(priorityGroupId) : void 0;
124093
- const options = Array.isArray(priority?.options) ? priority.options : [];
124094
- const option = options.find(
124095
- (candidate) => isObjectRecord2(candidate) && candidate.name === optionName
124096
- );
124097
- if (!isObjectRecord2(option) || typeof option.id !== "string") {
124098
- throw new Error(`Unknown priority option ${expression}.`);
124099
- }
125357
+ const groupId = resolved.group.id;
125358
+ const option = resolved.option;
124100
125359
  return {
124101
125360
  ...old,
124102
125361
  ...lookupValueSettings(context, groupId, old),
124103
125362
  dialogueGroupId: groupId,
124104
125363
  priority: {
124105
125364
  ...isObjectRecord2(old.priority) ? old.priority : {},
124106
- priorityOptionId: option.id,
125365
+ priorityOptionId: option?.id ?? null,
124107
125366
  relativeOrder: constructorNumber(member.arguments, "order")
124108
125367
  }
124109
125368
  };
124110
125369
  }
124111
125370
  function lookupValueSettings(context, groupId, old) {
124112
- if (context.lookupDialogueGroupIds.has(groupId))
124113
- return { lookupValueId: context.dialoguePrimaryValueId };
125371
+ if (context.lookupDialogueGroupIds.has(groupId)) {
125372
+ const valueId = context.dialoguePrimaryValueId;
125373
+ const group = baseData2(context.state, "dialogue-group", groupId);
125374
+ const typeName = typeof group.collectionMemberId === "string" ? context.referenceTypes().collectionEntryTypeName(group.collectionMemberId) : null;
125375
+ if (valueId !== null && typeName !== null) {
125376
+ const primary = context.dialogue.bindings.find(
125377
+ (binding) => hasAnnotation3(binding.annotations, "primary")
125378
+ );
125379
+ try {
125380
+ context.referenceTypes().assertAssignable(
125381
+ valueId,
125382
+ typeName,
125383
+ `Lookup group ${String(group.name ?? groupId)}`
125384
+ );
125385
+ } catch (error) {
125386
+ throw dialogueSourceError(
125387
+ error,
125388
+ primary?.initializerSource ?? primary?.source ?? context.dialogue.source
125389
+ );
125390
+ }
125391
+ }
125392
+ return { lookupValueId: valueId };
125393
+ }
124114
125394
  return old.lookupValueId == null ? {} : { lookupValueId: null };
124115
125395
  }
124116
- function referenceId2(expression, typeName) {
125396
+ function referenceId3(expression, typeName) {
124117
125397
  const pattern = new RegExp(
124118
125398
  `^Reference<${typeName}>\\(id:\\s*("(?:[^"\\\\]|\\\\.)*")\\)$`,
124119
125399
  "u"
@@ -124190,8 +125470,8 @@ function decodeProse(raw) {
124190
125470
  if (indent2.length === 0) return value;
124191
125471
  return value.split("\n").map((line) => line.startsWith(indent2) ? line.slice(indent2.length) : line).join("\n");
124192
125472
  }
124193
- function decodeProseSegments(raw) {
124194
- const value = decodeProse(raw);
125473
+ function decodeProseSegments(raw, decode2 = true) {
125474
+ const value = decode2 ? decodeProse(raw) : raw.slice(3, -3);
124195
125475
  const result = [];
124196
125476
  let literal3 = "";
124197
125477
  const flushLiteral = () => {
@@ -124231,7 +125511,12 @@ function decodeProseSegments(raw) {
124231
125511
  if (expression.length === 0) {
124232
125512
  throw new Error("NeoFlow prose interpolation cannot be empty.");
124233
125513
  }
124234
- result.push({ kind: "expression", value: expression });
125514
+ result.push({
125515
+ kind: "expression",
125516
+ value: expression,
125517
+ start: index + 1,
125518
+ end
125519
+ });
124235
125520
  index = end;
124236
125521
  }
124237
125522
  flushLiteral();
@@ -124306,8 +125591,8 @@ function splitTopLevel(value) {
124306
125591
  function constructorExpression(args, name) {
124307
125592
  return args.find((argument2) => argument2.name === name)?.expression ?? null;
124308
125593
  }
124309
- function constructorString(args, name) {
124310
- return literalString(constructorExpression(args, name) ?? void 0);
125594
+ function authoredDisplayName(expression, symbol, kind) {
125595
+ return expression === void 0 ? inferredDialogueDisplayName(symbol, kind) : literalString(expression);
124311
125596
  }
124312
125597
  function constructorBoolean(args, name) {
124313
125598
  return literalBoolean(constructorExpression(args, name) ?? void 0);
@@ -124524,6 +125809,22 @@ function indexValueSymbols(state, analysis) {
124524
125809
  });
124525
125810
  }
124526
125811
  }
125812
+ const locals = new LocalValueBindingsV4(
125813
+ analysis.values.globals,
125814
+ analysis.schema.enums.map((entry) => entry.name),
125815
+ staticMembersInitializedByName(analysis)
125816
+ );
125817
+ for (const declaration of analysis.values.globals) {
125818
+ const target = locals.declaredTarget(declaration.name);
125819
+ if (target === null) continue;
125820
+ const valueId = "id" in target ? target.id : result.get(target.ownerPath)?.valueId;
125821
+ if (valueId !== void 0)
125822
+ result.set(declaration.name, {
125823
+ valueId,
125824
+ declaredTypeName: declaration.type.name,
125825
+ declaredType: declaration.type
125826
+ });
125827
+ }
124527
125828
  return result;
124528
125829
  }
124529
125830
  function memberDeclaredTypeName(member, classes) {
@@ -124615,6 +125916,12 @@ var SourceSchemaIndex;
124615
125916
  var init_dialogue_lower = __esm({
124616
125917
  "src/project-source/dialogue-lower.ts"() {
124617
125918
  "use strict";
125919
+ init_dialogue_source_names();
125920
+ init_dialogue_group_paths();
125921
+ init_local_values();
125922
+ init_key_reference_spelling();
125923
+ init_reference_target_types();
125924
+ init_source_diagnostics();
124618
125925
  init_executable_parser();
124619
125926
  init_strict_ir();
124620
125927
  init_localization_types();
@@ -124910,226 +126217,6 @@ var init_dialogue_lower = __esm({
124910
126217
  }
124911
126218
  });
124912
126219
 
124913
- // src/project-source/stored-value-placements.ts
124914
- function storedValueRowsByIdV4(records2) {
124915
- const stored = /* @__PURE__ */ new Map();
124916
- let packed = false;
124917
- for (const record7 of records2) {
124918
- if (record7.deleted === true) continue;
124919
- if (record7.recordKind !== "value") continue;
124920
- if (!isObjectRecord2(record7.data)) continue;
124921
- stored.set(record7.recordId, record7.data);
124922
- packed ||= rowCarriesPackedValueContent(record7.data);
124923
- }
124924
- if (!packed) return stored;
124925
- const logical = /* @__PURE__ */ new Map();
124926
- for (const [valueId, row] of stored) {
124927
- if (!rowCarriesPackedValueContent(row)) {
124928
- logical.set(valueId, row);
124929
- continue;
124930
- }
124931
- const authoredRow = stripClientDerivedBodies("value", row);
124932
- if (!isMemberValue(authoredRow)) {
124933
- throw new PackedValueEncodingError(
124934
- `Stored value row "${valueId}" packs a child but is not a well-formed value row, so its packed payload cannot be expanded.`
124935
- );
124936
- }
124937
- const decoded = decodePackedValueRow(authoredRow);
124938
- logical.set(valueId, { ...decoded.row });
124939
- for (const child2 of decoded.children) {
124940
- logical.set(child2.id, { ...child2 });
124941
- }
124942
- }
124943
- return logical;
124944
- }
124945
- function buildStoredValuePlacementIndexV4(records2) {
124946
- const live = [...records2].filter((record7) => record7.deleted !== true);
124947
- const values = storedValueRowsByIdV4(live);
124948
- const classes = [];
124949
- const members = [];
124950
- const memberDataById = /* @__PURE__ */ new Map();
124951
- const constructors = /* @__PURE__ */ new Map();
124952
- const variantTargetClassByRootValueId = /* @__PURE__ */ new Map();
124953
- for (const record7 of live) {
124954
- if (!isObjectRecord2(record7.data)) continue;
124955
- if (record7.recordKind === "value") continue;
124956
- if (record7.recordKind === "class") {
124957
- classes.push({
124958
- id: record7.recordId,
124959
- ...isStringRecord9(record7.data.schema) ? { schema: record7.data.schema } : {},
124960
- ...typeof record7.data.extendsClassId === "string" || record7.data.extendsClassId === null ? { extendsClassId: record7.data.extendsClassId } : {},
124961
- ...typeof record7.data.requiredConstructorId === "string" ? { requiredConstructorId: record7.data.requiredConstructorId } : {},
124962
- ...Array.isArray(record7.data.genericParams) ? {
124963
- genericParamIds: record7.data.genericParams.flatMap(
124964
- (entry) => isObjectRecord2(entry) && typeof entry.id === "string" ? [entry.id] : []
124965
- )
124966
- } : {}
124967
- });
124968
- } else if (record7.recordKind === "member") {
124969
- memberDataById.set(record7.recordId, record7.data);
124970
- members.push({
124971
- id: record7.recordId,
124972
- ...record7.data.defaultValue === void 0 ? {} : { defaultValue: record7.data.defaultValue }
124973
- });
124974
- } else if (record7.recordKind === "constructor") {
124975
- constructors.set(record7.recordId, record7.data);
124976
- } else if (record7.recordKind === "variant" && typeof record7.data.valueId === "string" && typeof record7.data.classId === "string") {
124977
- variantTargetClassByRootValueId.set(
124978
- record7.data.valueId,
124979
- record7.data.classId
124980
- );
124981
- }
124982
- }
124983
- const classesById = new Map(
124984
- classes.map((schemaClass2) => [schemaClass2.id, schemaClass2])
124985
- );
124986
- const resolveSettlement = createConstructorSettlementResolver({
124987
- classes,
124988
- constructors: [...constructors].flatMap(
124989
- ([id2, constructor2]) => typeof constructor2.classId === "string" ? [
124990
- {
124991
- id: id2,
124992
- classId: constructor2.classId,
124993
- ...Array.isArray(constructor2.baseArguments) ? { baseArguments: constructor2.baseArguments } : {},
124994
- ...Array.isArray(constructor2.baseInitializerFields) ? {
124995
- baseInitializerFields: constructor2.baseInitializerFields
124996
- } : {}
124997
- }
124998
- ] : []
124999
- ),
125000
- members
125001
- });
125002
- const memberIdForSchemaKey = (classId, schemaKey) => {
125003
- const visited = /* @__PURE__ */ new Set();
125004
- let cursor = classId;
125005
- while (cursor !== null && !visited.has(cursor)) {
125006
- visited.add(cursor);
125007
- const schemaClass2 = classesById.get(cursor);
125008
- if (schemaClass2 === void 0) return null;
125009
- const memberId = schemaClass2.schema?.[schemaKey];
125010
- if (typeof memberId === "string") return memberId;
125011
- cursor = schemaClass2.extendsClassId ?? null;
125012
- }
125013
- return null;
125014
- };
125015
- const childrenByParentValueId = /* @__PURE__ */ new Map();
125016
- const placementByChildValueId = /* @__PURE__ */ new Map();
125017
- const add = (edge) => {
125018
- const children = childrenByParentValueId.get(edge.parentValueId) ?? /* @__PURE__ */ new Map();
125019
- if (children.has(edge.schemaKey)) return;
125020
- children.set(edge.schemaKey, edge);
125021
- childrenByParentValueId.set(edge.parentValueId, children);
125022
- if (!placementByChildValueId.has(edge.childValueId)) {
125023
- placementByChildValueId.set(edge.childValueId, edge);
125024
- }
125025
- };
125026
- for (const [parentValueId, value] of values) {
125027
- const classId = typeof value.classId === "string" ? value.classId : null;
125028
- const body = value.value;
125029
- if (isObjectRecord2(body)) {
125030
- for (const [schemaKey, childValueId2] of Object.entries(body)) {
125031
- if (typeof childValueId2 !== "string" || !values.has(childValueId2)) {
125032
- continue;
125033
- }
125034
- add({
125035
- childValueId: childValueId2,
125036
- memberId: classId === null ? null : memberIdForSchemaKey(classId, schemaKey),
125037
- parentValueId,
125038
- schemaKey,
125039
- source: "body"
125040
- });
125041
- }
125042
- }
125043
- const constructorId = value.instanceConstructorId;
125044
- const constructorArgs = value.constructorArgs;
125045
- if (classId === null || typeof constructorId !== "string" || !isObjectRecord2(constructorArgs)) {
125046
- continue;
125047
- }
125048
- const constructor2 = constructors.get(constructorId);
125049
- const parameters = constructor2?.argumentTypes;
125050
- if (constructor2 === void 0 || constructor2.classId !== classId || !Array.isArray(parameters)) {
125051
- continue;
125052
- }
125053
- for (const [index, parameter4] of parameters.entries()) {
125054
- if (!isObjectRecord2(parameter4) || typeof parameter4.name !== "string") {
125055
- continue;
125056
- }
125057
- const settled = resolveSettlement(classId, parameter4.name, constructorId);
125058
- if (settled === null) continue;
125059
- if (isObjectRecord2(body) && Object.hasOwn(body, settled.schemaKey)) {
125060
- continue;
125061
- }
125062
- const parameterId = constructorActionParameterId(constructor2, index);
125063
- const childValueId2 = constructorArgs[parameterId];
125064
- if (typeof childValueId2 !== "string" || !values.has(childValueId2) || !memberStoresAggregate(
125065
- memberDataById.get(settled.memberId),
125066
- value,
125067
- memberDataById,
125068
- parentValueId,
125069
- classesById,
125070
- variantTargetClassByRootValueId
125071
- )) {
125072
- continue;
125073
- }
125074
- add({
125075
- childValueId: childValueId2,
125076
- memberId: settled.memberId,
125077
- parentValueId,
125078
- schemaKey: settled.schemaKey,
125079
- source: "constructor"
125080
- });
125081
- }
125082
- }
125083
- return { childrenByParentValueId, placementByChildValueId };
125084
- }
125085
- function memberStoresAggregate(member, parent, membersById, parentValueId, classesById, variantTargetClassByRootValueId, visitedMemberIds = /* @__PURE__ */ new Set()) {
125086
- const kind = member?.kind;
125087
- if (kind === 5 /* Dictionary */ || kind === 6 /* List */ || kind === 7 /* Class */ || kind === "dictionary" || kind === "list" || kind === "class") {
125088
- return true;
125089
- }
125090
- if (kind !== 21 /* Generic */ && kind !== "generic") return false;
125091
- const memberId = typeof member?.id === "string" ? member.id : null;
125092
- if (memberId !== null && visitedMemberIds.has(memberId)) return false;
125093
- const genericParamId = member?.genericParamId;
125094
- const bindings = parent.genericBindings;
125095
- if (typeof genericParamId === "string" && isObjectRecord2(bindings)) {
125096
- const bindingMemberId = bindings[genericParamId];
125097
- if (typeof bindingMemberId === "string") {
125098
- return memberStoresAggregate(
125099
- membersById.get(bindingMemberId),
125100
- parent,
125101
- membersById,
125102
- parentValueId,
125103
- classesById,
125104
- variantTargetClassByRootValueId,
125105
- /* @__PURE__ */ new Set([
125106
- ...visitedMemberIds,
125107
- ...memberId === null ? [] : [memberId]
125108
- ])
125109
- );
125110
- }
125111
- }
125112
- const parentClassId = parent.classId;
125113
- const variantTargetClassId = variantTargetClassByRootValueId.get(parentValueId);
125114
- if (typeof parentClassId === "string" && typeof variantTargetClassId === "string" && classesById.get(parentClassId)?.genericParamIds?.[0] === genericParamId && classesById.has(variantTargetClassId)) {
125115
- return true;
125116
- }
125117
- return false;
125118
- }
125119
- function isStringRecord9(value) {
125120
- return isObjectRecord2(value) && Object.values(value).every((entry) => typeof entry === "string");
125121
- }
125122
- var init_stored_value_placements = __esm({
125123
- "src/project-source/stored-value-placements.ts"() {
125124
- "use strict";
125125
- init_constructors2();
125126
- init_constructor_parameter_settlement();
125127
- init_members();
125128
- init_neo_script_derived_bodies();
125129
- init_value_comparison();
125130
- }
125131
- });
125132
-
125133
126220
  // src/project-source/root-source.ts
125134
126221
  function emitProjectRootSourceV4(records2, manifest, materializedConstructors, localValues, options = {}) {
125135
126222
  const project = [...records2.values()].find(
@@ -125885,9 +126972,9 @@ function storedConstructionEmitters(state, manifest) {
125885
126972
  if (record7.recordKind !== "value") continue;
125886
126973
  if (!isObjectRecord2(record7.data)) continue;
125887
126974
  if (!isObjectRecord2(record7.data.value)) continue;
125888
- const constructorArgs = record7.data.constructorArgs;
126975
+ const constructorArgs2 = record7.data.constructorArgs;
125889
126976
  const hasInstanceProvenance = isVirtualInstanceRootShape(record7.data);
125890
- if (constructorArgs !== void 0 && constructorArgs !== null && !hasInstanceProvenance) {
126977
+ if (constructorArgs2 !== void 0 && constructorArgs2 !== null && !hasInstanceProvenance) {
125891
126978
  continue;
125892
126979
  }
125893
126980
  candidateRoots.add(record7.recordId);
@@ -127041,7 +128128,8 @@ function computeWorkspaceStatus(workspace, options) {
127041
128128
  diagnostic2.range.start.line + 1,
127042
128129
  diagnostic2.range.start.character + 1,
127043
128130
  diagnostic2.code,
127044
- diagnostic2.severity
128131
+ diagnostic2.severity,
128132
+ diagnostic2.range
127045
128133
  );
127046
128134
  if (positioned.severity === "error") parseErrors.push(positioned);
127047
128135
  else parseWarnings.push(positioned);
@@ -127548,10 +128636,28 @@ function computeWorkspaceStatus(workspace, options) {
127548
128636
  ],
127549
128637
  staticMemberValueIds
127550
128638
  );
127551
- const dialogueRecords = lowerDialogueProjectSourcesV4(
127552
- prospectiveState,
127553
- projectAnalysisV4
127554
- );
128639
+ const dialogueBodySources = /* @__PURE__ */ new Map();
128640
+ let dialogueRecords;
128641
+ try {
128642
+ dialogueRecords = lowerDialogueProjectSourcesV4(
128643
+ prospectiveState,
128644
+ projectAnalysisV4,
128645
+ {
128646
+ authoredValueSeeds,
128647
+ manifest,
128648
+ sourceCapture: {
128649
+ texts: new Map(
128650
+ compilationSources.filter((input) => input.uri.endsWith(".neoflow")).map((input) => [input.uri, new SourceText(input.text)])
128651
+ ),
128652
+ bodies: dialogueBodySources
128653
+ }
128654
+ }
128655
+ );
128656
+ } catch (error) {
128657
+ if (!(error instanceof SchemaSourceError)) throw error;
128658
+ parseErrors.push(error);
128659
+ return refusedStatus(conflictedFiles, parseErrors, parseWarnings);
128660
+ }
127555
128661
  reportPhase("supplemental-dialogue", "Comparing records\u2026");
127556
128662
  records2.push(
127557
128663
  ...staticValues.records,
@@ -128067,6 +129173,7 @@ function computeWorkspaceStatus(workspace, options) {
128067
129173
  );
128068
129174
  return {
128069
129175
  ...projectAnalysisV4 === null ? {} : {
129176
+ dialogueBodySources,
128070
129177
  sourceSnapshot: {
128071
129178
  inputs: compilationSources,
128072
129179
  analysis: projectAnalysisV4
@@ -129127,6 +130234,7 @@ var ANIMATION_DOCUMENT_RECORD_KINDS, ANIMATION_REPLAY_RECORD_KINDS, PROSPECTIVE_
129127
130234
  var init_workspace_status_core = __esm({
129128
130235
  "src/project-source/workspace-status-core.ts"() {
129129
130236
  "use strict";
130237
+ init_source_text();
129130
130238
  init_runtime_diagnostic();
129131
130239
  init_NSGetterRuntimeError();
129132
130240
  init_lower_support();
@@ -131436,7 +132544,15 @@ function buildValueLowerContext(state, manifest, options = {}) {
131436
132544
  let storedValuePlacements;
131437
132545
  const readStoredValuePlacements = () => storedValuePlacements ??= buildStoredValuePlacementIndexV4(stateRecords);
131438
132546
  let rootValueTargets;
132547
+ let referenceTypes;
132548
+ const readReferenceTypes = () => referenceTypes ??= new ReferenceTargetTypes(
132549
+ state,
132550
+ void 0,
132551
+ registry.pendingValues.values(),
132552
+ manifest
132553
+ );
131439
132554
  return {
132555
+ referenceTypes: readReferenceTypes,
131440
132556
  listenerBindings: registry.listenerBindings,
131441
132557
  misplacedLocalListeners: registry.misplacedLocalListeners,
131442
132558
  localValues: registry.localValues ??= new LocalValueBindingsV4(
@@ -132105,6 +133221,21 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
132105
133221
  continue;
132106
133222
  }
132107
133223
  if (!defaultRequiresOwnedRows(context, member, expression, binding)) {
133224
+ if (member.kind === "lookup" || member.kind === "dialogueLookup") {
133225
+ const entries = expression.kind === "litList" ? expression.elements : [expression];
133226
+ for (const entry of entries) {
133227
+ const target = referenceTargetSpelling(context, entry);
133228
+ if (target?.spelling !== "id" && target?.spelling !== "symbol")
133229
+ continue;
133230
+ context.referenceObligations.push({
133231
+ kind: "reference",
133232
+ site: referenceSite(binding, entry),
133233
+ memberId,
133234
+ ownerValueId: null,
133235
+ target
133236
+ });
133237
+ }
133238
+ }
132108
133239
  continue;
132109
133240
  }
132110
133241
  const rootValueId = pendingValueId(binding, `${label}.default`);
@@ -133224,12 +134355,12 @@ function staticValueSeedRow(value, loweredMemberId) {
133224
134355
  };
133225
134356
  }
133226
134357
  function seedRowInstanceProvenance(value) {
133227
- const { constructorArgs, ...stamps } = pickInstanceProvenance(
134358
+ const { constructorArgs: constructorArgs2, ...stamps } = pickInstanceProvenance(
133228
134359
  readInstanceProvenance(value)
133229
134360
  );
133230
134361
  return {
133231
134362
  ...stamps,
133232
- ...constructorArgs === void 0 || constructorArgs === null ? {} : { constructorArgs }
134363
+ ...constructorArgs2 === void 0 || constructorArgs2 === null ? {} : { constructorArgs: constructorArgs2 }
133233
134364
  };
133234
134365
  }
133235
134366
  function readInstanceProvenance(value) {
@@ -133238,10 +134369,10 @@ function readInstanceProvenance(value) {
133238
134369
  if (field === null) return null;
133239
134370
  return typeof field === "string" ? field : void 0;
133240
134371
  };
133241
- const constructorArgs = value.constructorArgs;
134372
+ const constructorArgs2 = value.constructorArgs;
133242
134373
  return {
133243
- ...constructorArgs === void 0 ? {} : {
133244
- constructorArgs: isObjectRecord2(constructorArgs) ? constructorArgs : null
134374
+ ...constructorArgs2 === void 0 ? {} : {
134375
+ constructorArgs: isObjectRecord2(constructorArgs2) ? constructorArgs2 : null
133245
134376
  },
133246
134377
  instanceConstructorId: nullableString5(value.instanceConstructorId),
133247
134378
  instanceVariantId: nullableString5(value.instanceVariantId),
@@ -133385,7 +134516,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
133385
134516
  let value;
133386
134517
  let classId = null;
133387
134518
  let genericBindings;
133388
- let constructorArgs;
134519
+ let constructorArgs2;
133389
134520
  let instanceConstructorId;
133390
134521
  if (expression.kind === "litNull") {
133391
134522
  if (resolvedMember.required) {
@@ -133553,7 +134684,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
133553
134684
  }
133554
134685
  if (!partial) {
133555
134686
  instanceConstructorId = effectiveClass.requiredConstructorId ?? null;
133556
- constructorArgs = recordedConstructorArgs;
134687
+ constructorArgs2 = recordedConstructorArgs;
133557
134688
  }
133558
134689
  value = body;
133559
134690
  } else if (resolvedMember.kind === "list") {
@@ -133670,7 +134801,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
133670
134801
  classId,
133671
134802
  ...containerId === void 0 ? {} : { containerId },
133672
134803
  ...genericBindings === void 0 ? {} : { genericBindings },
133673
- ...constructorArgs === void 0 ? {} : { constructorArgs },
134804
+ ...constructorArgs2 === void 0 ? {} : { constructorArgs: constructorArgs2 },
133674
134805
  ...instanceConstructorId === void 0 ? {} : { instanceConstructorId }
133675
134806
  };
133676
134807
  registerSeedRow(context, rows, row, source, sourceExpression);
@@ -133798,7 +134929,7 @@ function lowerStructuralConstructionRow(context, member, expression, source, val
133798
134929
  const settledBy = structuralMemberByParameterName(context, effectiveClass);
133799
134930
  const slices = constructorArgumentValueSlices(authoredSlice);
133800
134931
  const value = {};
133801
- const constructorArgs = {};
134932
+ const constructorArgs2 = {};
133802
134933
  expression.args.forEach((argument2, index) => {
133803
134934
  const name = expression.argumentNames?.[index] ?? parameters[index] ?? null;
133804
134935
  if (name === null) {
@@ -133836,7 +134967,7 @@ function lowerStructuralConstructionRow(context, member, expression, source, val
133836
134967
  slices[index]
133837
134968
  );
133838
134969
  if (structuralArgumentIsAggregate(context, childMember, environment)) {
133839
- constructorArgs[`__arg_${parameterIndex}__`] = childId;
134970
+ constructorArgs2[`__arg_${parameterIndex}__`] = childId;
133840
134971
  } else {
133841
134972
  const leaf = rows.get(childId);
133842
134973
  if (leaf?.nodeType !== "literal") {
@@ -133851,7 +134982,7 @@ function lowerStructuralConstructionRow(context, member, expression, source, val
133851
134982
  leaf,
133852
134983
  localizedTexts
133853
134984
  });
133854
- constructorArgs[`__arg_${parameterIndex}__`] = inline;
134985
+ constructorArgs2[`__arg_${parameterIndex}__`] = inline;
133855
134986
  deleteSeedRow(context, rows, childId);
133856
134987
  }
133857
134988
  });
@@ -133892,7 +135023,7 @@ function lowerStructuralConstructionRow(context, member, expression, source, val
133892
135023
  memberId: member.id,
133893
135024
  value,
133894
135025
  classId: effectiveClass.id,
133895
- constructorArgs,
135026
+ constructorArgs: constructorArgs2,
133896
135027
  // Provenance is stamped explicitly on every construction this lowerer
133897
135028
  // writes. `constructorArgs` alone is already a complete recipe (see
133898
135029
  // `carriesCompleteConstructionRecipe`), so the stamp adds no meaning — it
@@ -135969,6 +137100,12 @@ function validateReferenceContract(context, member, target, ownerValueId) {
135969
137100
  `Lookup member ${member.name} target ${target.id} is ${classDisplayName2(context, actualClassId)}, but the member declares ${classDisplayName2(context, declaredClassId)} \u2014 ${narrowedFrom} and this member narrows it. Point it at a ${classDisplayName2(context, declaredClassId)} row.`
135970
137101
  );
135971
137102
  }
137103
+ if (target.genericTypeName)
137104
+ context.referenceTypes().assertAssignable(
137105
+ target.id,
137106
+ target.genericTypeName,
137107
+ `Reference<${target.genericTypeName}>`
137108
+ );
135972
137109
  if (target.genericTypeName && expectedTypeName && !referenceTypeNameAssignable(
135973
137110
  context,
135974
137111
  target.genericTypeName,
@@ -137407,14 +138544,14 @@ function firstRequiredConstructorParameterKey(context, classId) {
137407
138544
  return null;
137408
138545
  }
137409
138546
  function storedConstructorCallSource(context, schemaClass2, value, className, environment, visited, targetTyped, cloneAggregateArguments = false) {
137410
- const constructorArgs = value.constructorArgs;
137411
- if (!isObjectRecord2(constructorArgs)) return null;
138547
+ const constructorArgs2 = value.constructorArgs;
138548
+ if (!isObjectRecord2(constructorArgs2)) return null;
137412
138549
  const manifestClass = context.manifestClasses.get(
137413
138550
  stringField3(schemaClass2, "id")
137414
138551
  );
137415
138552
  if (manifestClass === void 0) return null;
137416
138553
  if (value.instanceConstructorId === null) {
137417
- if (Object.keys(constructorArgs).length !== 0) {
138554
+ if (Object.keys(constructorArgs2).length !== 0) {
137418
138555
  throw new Error(
137419
138556
  `Stored implicit construction for ${className} carries constructor arguments.`
137420
138557
  );
@@ -137438,7 +138575,7 @@ function storedConstructorCallSource(context, schemaClass2, value, className, en
137438
138575
  );
137439
138576
  const argumentsValue = constructor2.arguments.flatMap((argument2, index) => {
137440
138577
  const key = `__arg_${index}__`;
137441
- if (!(key in constructorArgs)) {
138578
+ if (!(key in constructorArgs2)) {
137442
138579
  if (argument2.default !== null || argument2.type.nullable) return [];
137443
138580
  throw new Error(
137444
138581
  `Stored construction on value row "${stringOrNull2(value.id) ?? "<unknown>"}" of class "${stringOrNull2(schemaClass2.name) ?? "<unnamed>"}" (${stringOrNull2(schemaClass2.id) ?? "<no id>"}) is missing evaluated argument ${key} for required parameter "${argument2.name}".`
@@ -137448,14 +138585,14 @@ function storedConstructorCallSource(context, schemaClass2, value, className, en
137448
138585
  context,
137449
138586
  schemaClass2,
137450
138587
  value,
137451
- constructorArgs[key],
138588
+ constructorArgs2[key],
137452
138589
  argument2.name
137453
138590
  );
137454
138591
  return [
137455
138592
  `${argument2.name}: ${storedConstructorArgumentSource(
137456
138593
  context,
137457
138594
  argument2.type,
137458
- constructorArgs[key],
138595
+ constructorArgs2[key],
137459
138596
  environment,
137460
138597
  visited,
137461
138598
  cloneAggregateArguments,
@@ -137472,7 +138609,7 @@ function storedConstructorCallSource(context, schemaClass2, value, className, en
137472
138609
  constructorArgumentBodySchemaKey(
137473
138610
  context,
137474
138611
  value,
137475
- constructorArgs[key]
138612
+ constructorArgs2[key]
137476
138613
  ) !== void 0
137477
138614
  )}`
137478
138615
  ];
@@ -138919,6 +140056,7 @@ var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, M
138919
140056
  var init_value_sources = __esm({
138920
140057
  "src/project-source/value-sources.ts"() {
138921
140058
  "use strict";
140059
+ init_reference_target_types();
138922
140060
  init_listener_template_graph();
138923
140061
  init_listener_template_type();
138924
140062
  init_project_root_members();
@@ -139174,13 +140312,19 @@ function emitProjectDocumentSourcesV4(records2, options = {}) {
139174
140312
  recordKeys: emitted.recordKeys
139175
140313
  };
139176
140314
  }).toArray();
140315
+ const dialogueGroupSymbols = emittedDialogueGroupSymbols(
140316
+ records2,
140317
+ options.dialogueGroupSymbols,
140318
+ options.localValues?.map((value) => value.name)
140319
+ );
139177
140320
  const supplementalFiles = emitSupplementalProjectSourcesV4(
139178
140321
  records2,
139179
140322
  options.binaryPaths,
139180
140323
  {
139181
140324
  manifest,
139182
140325
  collectionValuePaths: indexes3.rootPathsByValueId,
139183
- localValues: options.localValues
140326
+ localValues: options.localValues,
140327
+ dialogueGroupSymbols
139184
140328
  }
139185
140329
  );
139186
140330
  const materializedConstructors = new Map(
@@ -139205,7 +140349,10 @@ function emitProjectDocumentSourcesV4(records2, options = {}) {
139205
140349
  localValues,
139206
140350
  valueOptions
139207
140351
  );
139208
- const dialogueFiles = emitDialogueProjectSourcesV4(records2);
140352
+ const dialogueFiles = emitDialogueProjectSourcesV4(
140353
+ records2,
140354
+ dialogueGroupSymbols
140355
+ );
139209
140356
  const localFiles = localValues.files();
139210
140357
  const groupingPaths = new Map(options.recordFiles);
139211
140358
  for (const file of localFiles) {
@@ -139299,6 +140446,7 @@ var PROJECT_SOURCE_ANALYSIS_V4_CACHE_PATH, SCHEMA_RECORD_KINDS2;
139299
140446
  var init_project_documents = __esm({
139300
140447
  "src/project-source/project-documents.ts"() {
139301
140448
  "use strict";
140449
+ init_dialogue_group_symbols();
139302
140450
  init_local_values();
139303
140451
  init_project_source_manifest();
139304
140452
  init_language_spec();
@@ -140949,6 +142097,75 @@ var init_project_file_source_preservation = __esm({
140949
142097
  }
140950
142098
  });
140951
142099
 
142100
+ // src/project-source/dialogue-source-diagnostic.ts
142101
+ function locateDialogueSourceError(error, sources2, texts, assigned) {
142102
+ if (!(error instanceof SourceBodyCompileError) || !sources2) return error;
142103
+ let bodyId = error.bodyId;
142104
+ for (const [pending, final] of assigned)
142105
+ if (final === bodyId) {
142106
+ bodyId = pending;
142107
+ break;
142108
+ }
142109
+ const body = sources2.get(bodyId);
142110
+ if (!body) return error;
142111
+ const { location: location3 } = body;
142112
+ const text = texts.get(location3.uri);
142113
+ let range2 = location3.range;
142114
+ let line = range2.start.line + 1;
142115
+ let column = range2.start.character + 1;
142116
+ if (text !== void 0) {
142117
+ const source = new SourceText(text);
142118
+ const start = source.offsetAt(range2.start);
142119
+ const authored = lex(
142120
+ text.slice(start, source.offsetAt(range2.end))
142121
+ ).tokens.filter(
142122
+ (token) => token.kind !== "comment" && token.kind !== "eof"
142123
+ );
142124
+ if (authored[0]?.text === "{" && authored.at(-1)?.text === "}") {
142125
+ range2 = {
142126
+ start: source.positionAt(start + authored[0].end),
142127
+ end: source.positionAt(start + authored.at(-1).start)
142128
+ };
142129
+ }
142130
+ const map = createNeoScriptSourceMap(
142131
+ error.code,
142132
+ source,
142133
+ range2,
142134
+ {
142135
+ name: body.name,
142136
+ uri: location3.uri,
142137
+ coordinateSpace: "file"
142138
+ },
142139
+ body.thisAlias
142140
+ );
142141
+ const position = map && sourcePositionMapper(map)({
142142
+ line: error.compileError.line,
142143
+ column: error.compileError.column
142144
+ });
142145
+ if (position) ({ line, column } = position);
142146
+ }
142147
+ const message = error.compileError.message.replace(/^\d+:\d+: /u, "");
142148
+ return new SchemaSourceError(
142149
+ `${body.name}: ${message}`,
142150
+ location3.uri,
142151
+ line,
142152
+ column,
142153
+ "neoflow-compile",
142154
+ "error",
142155
+ range2
142156
+ );
142157
+ }
142158
+ var init_dialogue_source_diagnostic = __esm({
142159
+ "src/project-source/dialogue-source-diagnostic.ts"() {
142160
+ "use strict";
142161
+ init_lexer();
142162
+ init_source_text();
142163
+ init_compiler();
142164
+ init_general_function_call_ir_source_recompile();
142165
+ init_source_diagnostics();
142166
+ }
142167
+ });
142168
+
140952
142169
  // ../packages/neoscript-language/src/local-scope-index.ts
140953
142170
  var LocalScopeIndex;
140954
142171
  var init_local_scope_index = __esm({
@@ -144598,6 +145815,8 @@ function projectCompletions(analysis, document, position) {
144598
145815
  items: [...script.items, variantScopeInBody]
144599
145816
  };
144600
145817
  }
145818
+ const groupMembers = dialogueGroupCompletions(analysis, document, position);
145819
+ if (groupMembers) return { isIncomplete: false, items: groupMembers };
144601
145820
  const annotations = projectAnnotationCompletions(
144602
145821
  analysis,
144603
145822
  document,
@@ -146232,6 +147451,7 @@ function projectSemanticTokens(document, analysis) {
146232
147451
  const index = buildProjectSymbolIndex(analysis.symbols);
146233
147452
  const tokens = projectTokens(document);
146234
147453
  const bodyContexts = projectBodies(analysis, document.uri);
147454
+ const source = analysis.documents.get(document.uri);
146235
147455
  const result = tokens.flatMap((token, tokenIndex) => {
146236
147456
  if (token.kind === "eof" || token.kind === "error") return [];
146237
147457
  if (rangeItemAt(bodyContexts, token.range.start)) {
@@ -146242,6 +147462,14 @@ function projectSemanticTokens(document, analysis) {
146242
147462
  let type;
146243
147463
  if (declaration) {
146244
147464
  type = projectSemanticTokenType(declaration);
147465
+ } else if (NEOFLOW_GRAPH_TYPES.has(token.text) && (source && sourceTypeAt(source, token.range.start) || tokens[tokenIndex + 1] && symbolsDeclaredAt(
147466
+ index,
147467
+ document.uri,
147468
+ tokens[tokenIndex + 1].range
147469
+ ).some(
147470
+ (symbol) => symbol.kind === "graphChild" && symbol.detail === token.text
147471
+ ))) {
147472
+ type = "type";
146245
147473
  } else if (resolved) {
146246
147474
  type = projectSemanticTokenType(resolved);
146247
147475
  } else if (token.kind === "keyword") type = "keyword";
@@ -146317,6 +147545,15 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
146317
147545
  }
146318
147546
  const exact = symbolsDeclaredAt(index, document.uri, token.range);
146319
147547
  if (exact.length === 1) return { token, symbol: exact[0] };
147548
+ if (!body) {
147549
+ const path = dialoguePathTokens(sourceTokens, tokenIndex);
147550
+ if (path.length > 0 && isDialogueGroupArgument(sourceTokens, tokenIndex - 2 * (path.length - 1))) {
147551
+ const catalog = sourceDialogueGroups(analysis);
147552
+ const resolved = catalog.paths.resolve(path);
147553
+ const symbol = resolved && catalog.symbols.get(resolved.option?.id ?? resolved.group.id);
147554
+ if (symbol) return { token, symbol };
147555
+ }
147556
+ }
146320
147557
  const candidates = index.byName.get(token.text) ?? [];
146321
147558
  if (candidates.length === 0) return null;
146322
147559
  const source = analysis.documents.get(document.uri);
@@ -146326,6 +147563,7 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
146326
147563
  (symbol) => symbol.kind === "class" || symbol.kind === "interface" || symbol.kind === "enum" || symbol.kind === "genericParameter"
146327
147564
  );
146328
147565
  if (types.length === 1) return { token, symbol: types[0] };
147566
+ if (typePosition) return null;
146329
147567
  }
146330
147568
  const scoped = candidates.filter(
146331
147569
  (symbol) => symbol.scopeRange && symbol.location.uri === document.uri && rangeContains(symbol.scopeRange, token.range.start)
@@ -147143,10 +148381,61 @@ function projectFunctionsNamed(analysis, name) {
147143
148381
  }
147144
148382
  return byName.get(name) ?? [];
147145
148383
  }
148384
+ function dialoguePathTokens(tokens, end) {
148385
+ const path = [];
148386
+ for (let i2 = end; i2 >= 0 && isProjectNameToken(tokens[i2]); i2 -= 2) {
148387
+ path.push(tokens[i2].text);
148388
+ if (tokens[i2 - 1]?.text !== ".") break;
148389
+ }
148390
+ return path.reverse();
148391
+ }
148392
+ function dialogueGroupCompletions(analysis, document, position) {
148393
+ const tokens = projectTokens(document);
148394
+ let index = projectTokenIndexAt(document, position);
148395
+ const token = tokens[index];
148396
+ if (isProjectNameToken(token) && positionCompare(token.range.start, position) < 0)
148397
+ index--;
148398
+ if (tokens[index]?.text !== ".") index--;
148399
+ if (tokens[index]?.text !== ".") return null;
148400
+ const path = dialoguePathTokens(tokens, index - 1);
148401
+ if (!isDialogueGroupArgument(tokens, index - 2 * path.length + 1))
148402
+ return null;
148403
+ const catalog = sourceDialogueGroups(analysis);
148404
+ const group = catalog.paths.group(path);
148405
+ if (!group) return null;
148406
+ const items = [];
148407
+ const children = catalog.paths.childGroups(group);
148408
+ const priorities = catalog.paths.priorityOptions(group);
148409
+ for (const [name, child2] of children) {
148410
+ if (!child2 || priorities.has(name)) continue;
148411
+ items.push({
148412
+ label: name,
148413
+ kind: "variable",
148414
+ detail: "DialogueGroup",
148415
+ insertText: name,
148416
+ symbolId: child2.id
148417
+ });
148418
+ }
148419
+ for (const [name, option] of priorities) {
148420
+ if (children.get(name)) continue;
148421
+ items.push({
148422
+ label: name,
148423
+ kind: "enumMember",
148424
+ detail: "PriorityOption",
148425
+ insertText: name,
148426
+ symbolId: option.id
148427
+ });
148428
+ }
148429
+ return items;
148430
+ }
148431
+ function isDialogueGroupArgument(tokens, pathStart) {
148432
+ return tokens[pathStart - 1]?.text === ":" && tokens[pathStart - 2]?.text === "group";
148433
+ }
147146
148434
  var PROJECT_BODIES, PROJECT_BODY_INDEX_CACHE, PROJECT_BODY_SNAPSHOT_CACHE, SOURCE_TYPES, CONSTRUCTION_INDEX_CACHE, VARIANT_SCOPE_INDEX_CACHE, PROJECT_SYMBOL_INDEX_CACHE, INITIALIZER_ROOTS, CONSTRUCTION_SITE_CACHE, DECLARATION_FIELDS, PROJECT_TYPE_DECLARATIONS, PROJECT_FUNCTIONS;
147147
148435
  var init_project_source_language_features = __esm({
147148
148436
  "../packages/neoscript-language/src/project-source-language-features.ts"() {
147149
148437
  "use strict";
148438
+ init_project_source_dialogue_groups();
147150
148439
  init_project_listener_annotations();
147151
148440
  init_strict_resolver();
147152
148441
  init_type_substitution();
@@ -147155,6 +148444,7 @@ var init_project_source_language_features = __esm({
147155
148444
  init_analyzer();
147156
148445
  init_lexer();
147157
148446
  init_language_spec();
148447
+ init_neoflow_graph_parser();
147158
148448
  init_project_source_semantics();
147159
148449
  init_project_source_variants();
147160
148450
  init_project_source_lifecycle_editor();
@@ -149023,7 +150313,7 @@ function workspaceForSourceLayoutV4(workspace, document) {
149023
150313
  }
149024
150314
  return { ...workspace, state: { ...workspace.state, records: records2 } };
149025
150315
  }
149026
- function readWorkspaceRecordFilesV4(workspace) {
150316
+ function readWorkspaceRecordFilesV4(workspace, dialogueGroupSymbols) {
149027
150317
  const paths = /* @__PURE__ */ new Map();
149028
150318
  const keysById = /* @__PURE__ */ new Map();
149029
150319
  for (const [key, record7] of Object.entries(workspace.state.records)) {
@@ -149036,6 +150326,20 @@ function readWorkspaceRecordFilesV4(workspace) {
149036
150326
  for (const absolute of listProjectSourceFilesV4(workspace.root)) {
149037
150327
  const path = relative4(workspace.root, absolute).split(sep4).join("/");
149038
150328
  const content = readFileSync10(absolute, "utf8");
150329
+ if (dialogueGroupSymbols && /\bDialogueGroup\b/u.test(content) && neoProjectSourceKind(path, content) === "definition") {
150330
+ const source = parseNeoProjectSource(content, "definition", path);
150331
+ for (const declaration of source.declarations) {
150332
+ if (declaration.kind !== "global" || declaration.type.name !== "DialogueGroup")
150333
+ continue;
150334
+ const annotation2 = declaration.annotations.find(
150335
+ (item) => item.name === "id"
150336
+ );
150337
+ const argument2 = annotation2?.arguments[0];
150338
+ const id2 = argument2 && lex(argument2.text).tokens[0]?.value;
150339
+ if (typeof id2 === "string")
150340
+ dialogueGroupSymbols.set(id2, declaration.name);
150341
+ }
150342
+ }
149039
150343
  const tokens = lex(content).roots.filter(
149040
150344
  (token) => token.kind !== "comment"
149041
150345
  );
@@ -154656,9 +155960,9 @@ function pruneUnreachableAnimationValues(args) {
154656
155960
  }
154657
155961
  function visitConstructionArgumentIds(value, visit) {
154658
155962
  if (!isLiteralValueContent(value)) return;
154659
- const constructorArgs = value.constructorArgs;
154660
- if (constructorArgs === void 0) return;
154661
- if (constructorArgs === null) return;
155963
+ const constructorArgs2 = value.constructorArgs;
155964
+ if (constructorArgs2 === void 0) return;
155965
+ if (constructorArgs2 === null) return;
154662
155966
  const scan = (payload) => {
154663
155967
  if (typeof payload === "string") {
154664
155968
  visit(payload);
@@ -154667,7 +155971,7 @@ function visitConstructionArgumentIds(value, visit) {
154667
155971
  if (payload === null || typeof payload !== "object") return;
154668
155972
  for (const entry of Object.values(payload)) scan(entry);
154669
155973
  };
154670
- scan(constructorArgs);
155974
+ scan(constructorArgs2);
154671
155975
  }
154672
155976
  function buildOptionalUnityRuntimeLocalizationExport(args) {
154673
155977
  if (args.config === void 0) return void 0;
@@ -169073,6 +170377,15 @@ function candidateTimestamp(purpose) {
169073
170377
  return purpose === "export" /* Export */ ? 1 : Date.now();
169074
170378
  }
169075
170379
  function locateStoredClosureCaptureError(error, status, assigned) {
170380
+ const located = locateDialogueSourceError(
170381
+ error,
170382
+ status.dialogueBodySources,
170383
+ new Map(
170384
+ status.sourceSnapshot?.inputs.map((input) => [input.uri, input.text])
170385
+ ),
170386
+ assigned
170387
+ );
170388
+ if (located !== error) return located;
169076
170389
  if (!(error instanceof StoredClosureCaptureError)) return error;
169077
170390
  let valueId = error.valueId;
169078
170391
  for (const [pendingId2, assignedId] of assigned) {
@@ -169307,8 +170620,8 @@ function cloneWorkspaceStatus(status) {
169307
170620
  };
169308
170621
  }
169309
170622
  function rewrittenSeedProvenance(memberId, seed) {
169310
- const constructorArgs = seed.constructorArgs;
169311
- if (constructorArgs !== void 0 && !isObjectRecord2(constructorArgs)) {
170623
+ const constructorArgs2 = seed.constructorArgs;
170624
+ if (constructorArgs2 !== void 0 && !isObjectRecord2(constructorArgs2)) {
169312
170625
  throw new Error(
169313
170626
  `Static value seed ${JSON.stringify(memberId)} rewrote constructorArgs to a non-object.`
169314
170627
  );
@@ -169326,7 +170639,7 @@ function rewrittenSeedProvenance(memberId, seed) {
169326
170639
  }
169327
170640
  }
169328
170641
  return {
169329
- ...constructorArgs === void 0 ? {} : { constructorArgs },
170642
+ ...constructorArgs2 === void 0 ? {} : { constructorArgs: constructorArgs2 },
169330
170643
  ...seed.instanceConstructorId === void 0 ? {} : {
169331
170644
  instanceConstructorId: seed.instanceConstructorId
169332
170645
  },
@@ -169475,6 +170788,9 @@ function createPendingProjectSourceIdentityV4(workspace, status, authoredValueSe
169475
170788
  }
169476
170789
  materializePendingSourceLocalization(records2, status);
169477
170790
  const emission = emitProjectDocumentFilesV4(records2, {
170791
+ dialogueGroupSymbols: authoredDialogueGroupSymbols(
170792
+ status.sourceSnapshot?.analysis
170793
+ ),
169478
170794
  storedValueBase: storedValueRowsByIdV4(
169479
170795
  Object.values(workspace.state.records)
169480
170796
  ),
@@ -171058,6 +172374,8 @@ var compileNSVoidBody2, compileNSFunction2, compileNSGetter2, compileNSSetter2,
171058
172374
  var init_push = __esm({
171059
172375
  "src/commands/push.ts"() {
171060
172376
  "use strict";
172377
+ init_dialogue_group_symbols();
172378
+ init_dialogue_source_diagnostic();
171061
172379
  init_lower_constructors();
171062
172380
  init_neoscript_source_catalog();
171063
172381
  init_src2();
@@ -171848,10 +173166,18 @@ function prepareWorkspaceResetV4(workspace, document, options = {}) {
171848
173166
  const layoutWorkspace = workspaceForSourceLayoutV4(workspace, document);
171849
173167
  const status = listProjectSourceFilesV4(workspace.root).length === 0 ? null : readWorkspaceLayoutStatusV4(layoutWorkspace, document);
171850
173168
  const localValues = status?.localValues ?? workspace.state.localValues;
173169
+ const dialogueGroupSymbols = new Map(
173170
+ authoredDialogueGroupSymbols(status?.sourceSnapshot?.analysis)
173171
+ );
173172
+ const recordFiles = readWorkspaceRecordFilesV4(
173173
+ layoutWorkspace,
173174
+ dialogueGroupSymbols
173175
+ );
171851
173176
  const emitted = emitProjectDocumentFilesV4(emissionRecords, {
171852
173177
  localValues,
173178
+ dialogueGroupSymbols,
171853
173179
  binaryPaths: workspaceBinaryPathsV4(workspace, status?.binaryFiles),
171854
- recordFiles: readWorkspaceRecordFilesV4(layoutWorkspace)
173180
+ recordFiles
171855
173181
  });
171856
173182
  assertUniqueEmittedPaths2(emitted.files);
171857
173183
  const resolveSourcePath = createWorkspaceSourcePathResolver(workspace.root);
@@ -171948,6 +173274,7 @@ var LEGACY_ROOT_FILES, LEGACY_PRIVATE_PATHS;
171948
173274
  var init_reset = __esm({
171949
173275
  "src/project-source/reset.ts"() {
171950
173276
  "use strict";
173277
+ init_dialogue_group_symbols();
171951
173278
  init_language_spec();
171952
173279
  init_source_layout();
171953
173280
  init_workspace_status();
@@ -172428,7 +173755,13 @@ async function finishFormat4Pull(args) {
172428
173755
  )
172429
173756
  );
172430
173757
  const layoutWorkspace = workspaceForSourceLayoutV4(workspace, document);
172431
- const recordFiles = readWorkspaceRecordFilesV4(layoutWorkspace);
173758
+ const dialogueGroupSymbols = new Map(
173759
+ authoredDialogueGroupSymbols(localStatus?.sourceSnapshot?.analysis)
173760
+ );
173761
+ const recordFiles = readWorkspaceRecordFilesV4(
173762
+ layoutWorkspace,
173763
+ dialogueGroupSymbols
173764
+ );
172432
173765
  for (const [key, record7] of localStatus?.reconstructed ?? []) {
172433
173766
  if (record7.file != null) recordFiles.set(key, record7.file);
172434
173767
  }
@@ -172447,7 +173780,8 @@ async function finishFormat4Pull(args) {
172447
173780
  {
172448
173781
  localValues,
172449
173782
  binaryPaths,
172450
- recordFiles
173783
+ recordFiles,
173784
+ dialogueGroupSymbols
172451
173785
  }
172452
173786
  );
172453
173787
  for (const recovery of localResult.staticMemberOwnershipRecoveries ?? []) {
@@ -172455,7 +173789,7 @@ async function finishFormat4Pull(args) {
172455
173789
  }
172456
173790
  const serverResult = conflictCount === 0 ? null : emitProjectDocumentFilesV4(
172457
173791
  buildEmitRecordSet(document, plans, "server"),
172458
- { recordFiles, localValues, binaryPaths }
173792
+ { recordFiles, localValues, binaryPaths, dialogueGroupSymbols }
172459
173793
  );
172460
173794
  const resolveSourcePath = createWorkspaceSourcePathResolver(workspace.root);
172461
173795
  if (!destructive && Object.keys(workspace.state.records).length === 0) {
@@ -172938,6 +174272,7 @@ function composeProspectivePullRecord(recordKind, recordId, data, serverRecord)
172938
174272
  var init_pull = __esm({
172939
174273
  "src/commands/pull.ts"() {
172940
174274
  "use strict";
174275
+ init_dialogue_group_symbols();
172941
174276
  init_project_file_source_preservation();
172942
174277
  init_push();
172943
174278
  init_source_layout();
@@ -184929,7 +186264,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
184929
186264
  async function main() {
184930
186265
  const args = parseArgs(process.argv.slice(2));
184931
186266
  if (args.command === "--version") {
184932
- console.log("0.71.1");
186267
+ console.log("0.71.3");
184933
186268
  return;
184934
186269
  }
184935
186270
  if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {