@crystaldesign/diva-backoffice 26.13.0-beta.14 → 26.13.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/build/esm/index.js +1261 -899
  2. package/build/types/backoffice/src/layout/Toolbar/Tools/DivaAgent/backofficeToolset.d.ts +20 -0
  3. package/build/types/backoffice/src/layout/Toolbar/Tools/DivaAgent/backofficeToolset.d.ts.map +1 -1
  4. package/build/types/backoffice/src/layout/Toolbar/Tools/DivaAgent/index.d.ts.map +1 -1
  5. package/build/types/backoffice/src/layout/Toolbar/Tools/DivaAgent/mediaToolset.d.ts.map +1 -1
  6. package/build/types/backoffice/src/layout/Toolbar/Tools/DivaAgent/navigationToolset.d.ts +14 -0
  7. package/build/types/backoffice/src/layout/Toolbar/Tools/DivaAgent/navigationToolset.d.ts.map +1 -1
  8. package/build/types/backoffice/src/tests/unit/agentBridge/expectedPath.test.d.ts +2 -0
  9. package/build/types/backoffice/src/tests/unit/agentBridge/expectedPath.test.d.ts.map +1 -0
  10. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/approvalWithdrawn.test.d.ts +2 -0
  11. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/approvalWithdrawn.test.d.ts.map +1 -0
  12. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/backofficeSelectionFacts.test.d.ts +2 -0
  13. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/backofficeSelectionFacts.test.d.ts.map +1 -0
  14. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/fakeGridEnvironment.d.ts +6 -0
  15. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/fakeGridEnvironment.d.ts.map +1 -1
  16. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/navigateToPaths.test.d.ts +2 -0
  17. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/navigateToPaths.test.d.ts.map +1 -0
  18. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/readColumnOptionsRow.test.d.ts +2 -0
  19. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/readColumnOptionsRow.test.d.ts.map +1 -0
  20. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/reloadSelection.test.d.ts +2 -0
  21. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/reloadSelection.test.d.ts.map +1 -0
  22. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/stageAfterRemount.test.d.ts +2 -0
  23. package/build/types/backoffice/src/tests/unit/layout/Toolbar/Tools/DivaAgent/stageAfterRemount.test.d.ts.map +1 -0
  24. package/package.json +16 -12
@@ -55498,7 +55498,202 @@ function _objectSpread$1e(e) { for (var r = 1; r < arguments.length; r++) { var
55498
55498
  /** The selection tools this toolset executes — defined by the diva AI service (tools/browser/backoffice.ts). */
55499
55499
  var BACKOFFICE_TOOL_NAMES = ['listSeries', 'selectSerie', 'selectItem'];
55500
55500
 
55501
+ /** The serie/item a view holds, as the agent panel reads it from the toolbar store. */
55502
+
55503
+ /** sessionStorage: it stays with this tab and survives the reload it is written for. */
55504
+ var RELOAD_SELECTION_STORAGE_KEY = 'divaAgent.reloadSelection';
55505
+ /** An older entry belongs to a reload long past — restoring it would override what the user picked since. */
55506
+ var RELOAD_SELECTION_MAX_AGE_MS = 2 * 60000;
55507
+ /** How long the selection must hold still before the restore acts: the reloaded view selects its own defaults first. */
55508
+ var RESTORE_SETTLE_MS = 1000;
55509
+ /** How long the restore keeps watching a restored selection — a slow view default can still override it. */
55510
+ var RESTORE_WATCH_MS = 10000;
55511
+ /** Steps the restore may apply: serie, then article, each again after a view default overrode it. */
55512
+ var RESTORE_MAX_STEPS = 6;
55513
+ var RESTORE_POLL_MS = 100;
55514
+ var isRecord$3 = function isRecord(value) {
55515
+ return _typeof(value) === 'object' && value !== null;
55516
+ };
55517
+ var withoutLeadingSlash = function withoutLeadingSlash(path) {
55518
+ return path.replace(/^\//, '');
55519
+ };
55520
+
55521
+ /** Remember the view's serie/item for the reload reloadPage triggers on this path — see takeReloadSelection. */
55522
+ function rememberReloadSelection(path, selection) {
55523
+ if ((selection === null || selection === void 0 ? void 0 : selection.serieNo) === undefined) return;
55524
+ var stored = {
55525
+ path: withoutLeadingSlash(path),
55526
+ serieNo: String(selection.serieNo),
55527
+ itemTypeNo: selection.itemTypeNo,
55528
+ at: Date.now()
55529
+ };
55530
+ try {
55531
+ window.sessionStorage.setItem(RELOAD_SELECTION_STORAGE_KEY, JSON.stringify(stored));
55532
+ } catch (_unused) {
55533
+ /* storage unavailable — the reloaded view starts with its default selection */
55534
+ }
55535
+ }
55536
+
55537
+ /** The selection reloadPage left for this path, taken once; nothing for another path or an entry older than its max age. */
55538
+ function takeReloadSelection(path) {
55539
+ var stored;
55540
+ try {
55541
+ var raw = window.sessionStorage.getItem(RELOAD_SELECTION_STORAGE_KEY);
55542
+ window.sessionStorage.removeItem(RELOAD_SELECTION_STORAGE_KEY);
55543
+ stored = raw ? JSON.parse(raw) : undefined;
55544
+ } catch (_unused2) {
55545
+ return undefined;
55546
+ }
55547
+ if (!isRecord$3(stored) || stored.path !== withoutLeadingSlash(path) || typeof stored.serieNo !== 'string') return undefined;
55548
+ if (typeof stored.at !== 'number' || Date.now() - stored.at > RELOAD_SELECTION_MAX_AGE_MS) return undefined;
55549
+ return {
55550
+ serieNo: stored.serieNo,
55551
+ itemTypeNo: typeof stored.itemTypeNo === 'string' ? stored.itemTypeNo : undefined
55552
+ };
55553
+ }
55554
+
55555
+ /** The selection once it has not changed for `settleMs`. */
55556
+ function settledSelection(_x, _x2) {
55557
+ return _settledSelection.apply(this, arguments);
55558
+ }
55559
+ /**
55560
+ * Re-apply the selection reloadPage carried across the reload through selectSerie/selectItem — the setters the
55561
+ * dropdowns use. The reloaded view selects its own defaults while it loads (the serie selector and the configurator
55562
+ * pick the first serie and article), so each step waits until the selection holds still, and a default that overrode
55563
+ * a step is answered by applying it again, a bounded number of times. True once the view holds the selection; false
55564
+ * when it gave up or `stopped` turned true — the user took over the selection or left the view, so nothing more is applied.
55565
+ */
55566
+ function _settledSelection() {
55567
+ _settledSelection = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(current, settleMs) {
55568
+ var read, last, stableSince, now;
55569
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
55570
+ while (1) switch (_context3.prev = _context3.next) {
55571
+ case 0:
55572
+ read = function read() {
55573
+ var _current = current(),
55574
+ serieNo = _current.serieNo,
55575
+ itemTypeNo = _current.itemTypeNo;
55576
+ return "".concat(serieNo, "|").concat(itemTypeNo);
55577
+ };
55578
+ last = read();
55579
+ stableSince = Date.now();
55580
+ case 3:
55581
+ if (!(Date.now() - stableSince < settleMs)) {
55582
+ _context3.next = 13;
55583
+ break;
55584
+ }
55585
+ _context3.next = 6;
55586
+ return new Promise(function (resolve) {
55587
+ return setTimeout(resolve, RESTORE_POLL_MS);
55588
+ });
55589
+ case 6:
55590
+ now = read();
55591
+ if (!(now === last)) {
55592
+ _context3.next = 9;
55593
+ break;
55594
+ }
55595
+ return _context3.abrupt("continue", 3);
55596
+ case 9:
55597
+ last = now;
55598
+ stableSince = Date.now();
55599
+ _context3.next = 3;
55600
+ break;
55601
+ case 13:
55602
+ return _context3.abrupt("return", current());
55603
+ case 14:
55604
+ case "end":
55605
+ return _context3.stop();
55606
+ }
55607
+ }, _callee3);
55608
+ }));
55609
+ return _settledSelection.apply(this, arguments);
55610
+ }
55611
+ function restoreReloadSelection(_x3, _x4, _x5) {
55612
+ return _restoreReloadSelection.apply(this, arguments);
55613
+ }
55614
+
55501
55615
  /** Toolset that drives the backoffice serie/item selection through the same context setters the WYSIWYG dropdowns use. */
55616
+ function _restoreReloadSelection() {
55617
+ _restoreReloadSelection = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(toolset, target, current) {
55618
+ var timing,
55619
+ stopped,
55620
+ watchUntil,
55621
+ steps,
55622
+ live,
55623
+ serieDiffers,
55624
+ itemDiffers,
55625
+ _args4 = arguments;
55626
+ return _regeneratorRuntime.wrap(function _callee4$(_context4) {
55627
+ while (1) switch (_context4.prev = _context4.next) {
55628
+ case 0:
55629
+ timing = _args4.length > 3 && _args4[3] !== undefined ? _args4[3] : {
55630
+ settleMs: RESTORE_SETTLE_MS,
55631
+ watchMs: RESTORE_WATCH_MS
55632
+ };
55633
+ stopped = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : function () {
55634
+ return false;
55635
+ };
55636
+ watchUntil = Date.now() + timing.watchMs;
55637
+ steps = 0;
55638
+ case 4:
55639
+ _context4.next = 6;
55640
+ return settledSelection(current, timing.settleMs);
55641
+ case 6:
55642
+ live = _context4.sent;
55643
+ if (!stopped()) {
55644
+ _context4.next = 9;
55645
+ break;
55646
+ }
55647
+ return _context4.abrupt("return", false);
55648
+ case 9:
55649
+ serieDiffers = String(live.serieNo) !== String(target.serieNo);
55650
+ itemDiffers = !!target.itemTypeNo && String(live.itemTypeNo) !== target.itemTypeNo;
55651
+ if (!(!serieDiffers && !itemDiffers)) {
55652
+ _context4.next = 16;
55653
+ break;
55654
+ }
55655
+ if (!(Date.now() >= watchUntil)) {
55656
+ _context4.next = 14;
55657
+ break;
55658
+ }
55659
+ return _context4.abrupt("return", true);
55660
+ case 14:
55661
+ _context4.next = 27;
55662
+ break;
55663
+ case 16:
55664
+ if (!(steps++ >= RESTORE_MAX_STEPS)) {
55665
+ _context4.next = 20;
55666
+ break;
55667
+ }
55668
+ return _context4.abrupt("return", false);
55669
+ case 20:
55670
+ if (!serieDiffers) {
55671
+ _context4.next = 25;
55672
+ break;
55673
+ }
55674
+ _context4.next = 23;
55675
+ return toolset.dispatch('selectSerie', {
55676
+ serieNo: target.serieNo
55677
+ });
55678
+ case 23:
55679
+ _context4.next = 27;
55680
+ break;
55681
+ case 25:
55682
+ _context4.next = 27;
55683
+ return toolset.dispatch('selectItem', {
55684
+ typeNo: target.itemTypeNo
55685
+ });
55686
+ case 27:
55687
+ _context4.next = 4;
55688
+ break;
55689
+ case 29:
55690
+ case "end":
55691
+ return _context4.stop();
55692
+ }
55693
+ }, _callee4);
55694
+ }));
55695
+ return _restoreReloadSelection.apply(this, arguments);
55696
+ }
55502
55697
  function createBackofficeToolset(ctx) {
55503
55698
  /** Never captured: see `getBinding`. A host without one gets the render-time binding. */
55504
55699
  var binding = function binding() {
@@ -55545,7 +55740,7 @@ function createBackofficeToolset(ctx) {
55545
55740
  }
55546
55741
  }, _callee);
55547
55742
  }));
55548
- return function loadSeries(_x) {
55743
+ return function loadSeries(_x6) {
55549
55744
  return _ref.apply(this, arguments);
55550
55745
  };
55551
55746
  }();
@@ -55558,9 +55753,22 @@ function createBackofficeToolset(ctx) {
55558
55753
  return {
55559
55754
  useCase: 'backoffice',
55560
55755
  toolNames: BACKOFFICE_TOOL_NAMES,
55756
+ // The setters run to their end whatever the signal says — a cancel cannot undo a selection change.
55757
+ abortUnaware: BACKOFFICE_TOOL_NAMES,
55758
+ // A serie switch that changes nothing else on screen must still read as arrived when the bridge settles.
55759
+ getFacts: function getFacts() {
55760
+ var _bound$elementProps$s, _bound$elementProps$s2, _bound$elementProps$i, _bound$elementProps$i2;
55761
+ var bound = binding();
55762
+ return {
55763
+ selection: {
55764
+ serieNo: (_bound$elementProps$s = bound === null || bound === void 0 || (_bound$elementProps$s2 = bound.elementProps.serie) === null || _bound$elementProps$s2 === void 0 ? void 0 : _bound$elementProps$s2.serieNo) !== null && _bound$elementProps$s !== void 0 ? _bound$elementProps$s : null,
55765
+ itemTypeNo: (_bound$elementProps$i = bound === null || bound === void 0 || (_bound$elementProps$i2 = bound.elementProps.item) === null || _bound$elementProps$i2 === void 0 ? void 0 : _bound$elementProps$i2.typeNo) !== null && _bound$elementProps$i !== void 0 ? _bound$elementProps$i : null
55766
+ }
55767
+ };
55768
+ },
55561
55769
  dispatch: function () {
55562
55770
  var _dispatch = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(name, input) {
55563
- var args, _bound$elementProps$s, _bound$elementProps$s2, _bound$elementProps$i, _bound$elementProps$i2, bound, series, unbound, _bound, onSerieChange, _series, target, _binding, _args$typeNo, onItemChange, typeNo;
55771
+ var args, _bound$elementProps$s3, _bound$elementProps$s4, _bound$elementProps$i3, _bound$elementProps$i4, bound, series, unbound, _bound, onSerieChange, _series, target, _binding, _args$typeNo, onItemChange, typeNo;
55564
55772
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
55565
55773
  while (1) switch (_context2.prev = _context2.next) {
55566
55774
  case 0:
@@ -55577,8 +55785,8 @@ function createBackofficeToolset(ctx) {
55577
55785
  // An empty list is ambiguous — a catalog without series looks like an instance with no binding to ask.
55578
55786
  unbound = !(bound !== null && bound !== void 0 && bound.parameters.catalogId) && !(bound !== null && bound !== void 0 && bound.parameters.packageId);
55579
55787
  return _context2.abrupt("return", _objectSpread$1e({
55580
- selectedSerieNo: (_bound$elementProps$s = bound === null || bound === void 0 || (_bound$elementProps$s2 = bound.elementProps.serie) === null || _bound$elementProps$s2 === void 0 ? void 0 : _bound$elementProps$s2.serieNo) !== null && _bound$elementProps$s !== void 0 ? _bound$elementProps$s : null,
55581
- selectedItemTypeNo: (_bound$elementProps$i = bound === null || bound === void 0 || (_bound$elementProps$i2 = bound.elementProps.item) === null || _bound$elementProps$i2 === void 0 ? void 0 : _bound$elementProps$i2.typeNo) !== null && _bound$elementProps$i !== void 0 ? _bound$elementProps$i : null,
55788
+ selectedSerieNo: (_bound$elementProps$s3 = bound === null || bound === void 0 || (_bound$elementProps$s4 = bound.elementProps.serie) === null || _bound$elementProps$s4 === void 0 ? void 0 : _bound$elementProps$s4.serieNo) !== null && _bound$elementProps$s3 !== void 0 ? _bound$elementProps$s3 : null,
55789
+ selectedItemTypeNo: (_bound$elementProps$i3 = bound === null || bound === void 0 || (_bound$elementProps$i4 = bound.elementProps.item) === null || _bound$elementProps$i4 === void 0 ? void 0 : _bound$elementProps$i4.typeNo) !== null && _bound$elementProps$i3 !== void 0 ? _bound$elementProps$i3 : null,
55582
55790
  series: series.map(function (serie) {
55583
55791
  return {
55584
55792
  serieNo: serie.serieNo,
@@ -55655,7 +55863,7 @@ function createBackofficeToolset(ctx) {
55655
55863
  }
55656
55864
  }, _callee2);
55657
55865
  }));
55658
- function dispatch(_x2, _x3) {
55866
+ function dispatch(_x7, _x8) {
55659
55867
  return _dispatch.apply(this, arguments);
55660
55868
  }
55661
55869
  return dispatch;
@@ -79697,6 +79905,15 @@ var ENRICHER_EDITOR_VIEWS = [{
79697
79905
  }
79698
79906
  }];
79699
79907
 
79908
+ /**
79909
+ * Where the editors lived in the backoffice (`/backoffice/catalogs/idmeditor/…`). The Data Engine mounts them at its
79910
+ * root instead; old links under this prefix are redirected to the same page there.
79911
+ */
79912
+ var LEGACY_EDITOR_ROUTE_BASE = 'catalogs/idmeditor';
79913
+
79914
+ /** Router base of the Data Engine component. */
79915
+ var DATA_ENGINE_BASENAME = '/dataengine';
79916
+
79700
79917
  function ownKeys$A(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
79701
79918
  function _objectSpread$A(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$A(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$A(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
79702
79919
  function _createForOfIteratorHelper$i(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$i(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
@@ -79875,11 +80092,42 @@ function allViews(root, ctx) {
79875
80092
  };
79876
80093
  }
79877
80094
 
80095
+ /**
80096
+ * The length cap a .NET validation pattern encodes: `[…][…]{0,29}` is one mandatory character plus up to 29 = 30,
80097
+ * a lone `[…]{0,29}` is 29. Undefined when the text holds no such quantifier.
80098
+ */
80099
+ function patternLengthLimit(pattern) {
80100
+ var _pattern$slice$match;
80101
+ var quantifier = /\{0,(\d+)\}/.exec(pattern);
80102
+ if (!quantifier) return undefined;
80103
+ var leadingClasses = ((_pattern$slice$match = pattern.slice(0, quantifier.index).match(/\]/g)) !== null && _pattern$slice$match !== void 0 ? _pattern$slice$match : []).length;
80104
+ return leadingClasses > 1 ? Number(quantifier[1]) + 1 : Number(quantifier[1]);
80105
+ }
80106
+
79878
80107
  /** Record _ids are Mongo ObjectIds — a 21-char nanoid here is a grid rowId, not an _id. */
79879
80108
  var isRecordId = function isRecordId(id) {
79880
80109
  return /^[0-9a-f]{24}$/i.test(id);
79881
80110
  };
79882
80111
 
80112
+ /** The sub-view an editor opens on when a path names only the catalog or the pack. */
80113
+ var EDITOR_DEFAULT_VIEW = {
80114
+ catalogs: 'series',
80115
+ packages: 'properties'
80116
+ };
80117
+
80118
+ /**
80119
+ * A navigateTo path as the router knows it: no leading slash, no legacy editor prefix — old links and tickets still
80120
+ * carry `catalogs/idmeditor/` — and a bare `catalogs/<_id>` or `packages/<_id>` completed with the editor's default
80121
+ * sub-view.
80122
+ */
80123
+ function normalizeNavigationPath(path) {
80124
+ var stripped = path.replace(/^\//, '').replace(new RegExp("^".concat(LEGACY_EDITOR_ROUTE_BASE, "/")), '');
80125
+ var bareEditor = /^(catalogs|packages)\/([0-9a-f]{24})\/?$/i.exec(stripped);
80126
+ if (!bareEditor) return stripped;
80127
+ var defaultView = bareEditor[1] === 'catalogs' ? EDITOR_DEFAULT_VIEW.catalogs : EDITOR_DEFAULT_VIEW.packages;
80128
+ return "".concat(bareEditor[1], "/").concat(bareEditor[2], "/").concat(defaultView);
80129
+ }
80130
+
79883
80131
  /** Editor path with a data-derived id: valid when the id is a record _id, 'bad-id' when it is a grid rowId. */
79884
80132
  function isDynamicEditorPath(root, requested) {
79885
80133
  var _permittedEditorViews2 = permittedEditorViews(root),
@@ -80131,12 +80379,8 @@ function columnAgentMeta(divaDef) {
80131
80379
  // Surface the validation regex and the length cap it encodes up front (server rejections quote it only after a failed write).
80132
80380
  if (typeof (divaDef === null || divaDef === void 0 ? void 0 : divaDef.regex) === 'string' && divaDef.regex) {
80133
80381
  meta.pattern = divaDef.regex;
80134
- var quantifier = /\{0,(\d+)\}/.exec(divaDef.regex);
80135
- if (quantifier) {
80136
- var _divaDef$regex$slice$;
80137
- var leadingClasses = ((_divaDef$regex$slice$ = divaDef.regex.slice(0, quantifier.index).match(/\]/g)) !== null && _divaDef$regex$slice$ !== void 0 ? _divaDef$regex$slice$ : []).length;
80138
- meta.maxLength = leadingClasses > 1 ? Number(quantifier[1]) + 1 : Number(quantifier[1]);
80139
- }
80382
+ var maxLength = patternLengthLimit(divaDef.regex);
80383
+ if (maxLength !== undefined) meta.maxLength = maxLength;
80140
80384
  }
80141
80385
  if (type === 'array') meta.note = "array cell — stage a ';'-separated list ('A;B'); empty clears";
80142
80386
  if (type === 'lookup') {
@@ -81785,7 +82029,7 @@ function createNavigationToolset(ctx) {
81785
82029
  },
81786
82030
  dispatch: function () {
81787
82031
  var _dispatch = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee13(name, input, signal, onProgress) {
81788
- var awaitingApproval, args, _allViews2, views, editorSubviews, _args$path, _root$navigationState2, _allViews3, _views, _editorSubviews, requested, dynamic, known, catalogIdIn, fromCatalog, toCatalog, only, entries, compactWanted, fullWanted, _args$value, _resolveGrid, entry, api, error, multiValues, _entry$getHandle$getD, _entry$getHandle2, filterBeforeBulk, deadline, bulk, _api$getFilterModel, requestedColumns, fields, rows, _notUnique, returnedData, returnedRoots, fieldsOmitted, unknownColumns, _bulk, missing, unverified, notReached, filterBeforeLocate, _located, _args$value2, matchedRows, carrierCount, notUnique, _cellValueOf2, matchedValue, gridsOnScreen, subtableHint, trimmedFirstRow, revealNote, revealed, _args$id, openError, _entry$getHandle$getD3, _entry$getHandle4, _lastNode$data, _entry$getHandle$hasP, _entry$getHandle5, _api$getFilterModel2, prelude, _resolveGrid2, _entry, _api, _error, waitedForRowsMs, previewCell, divaDefs, leafFields, _requested, columns, _unknownColumns, limit, _rows, displayed, unsavedRowCount, i, _api$getDisplayedRowA, context, _i2, node, values, truncatedColumns, _iterator8, _step8, column, raw, labelled, columnMeta, lastNode, gridContext, hasCreatorRow, creatorRowLoaded, totalRowCount, dirty, filterModel, filteredBy, _ref31, _ref32, _staged$0$rowId, _staged$, _addedRows$, _outcome$committed, _root$navigationState3, _outcome$failed, _outcome$declined2, _outcome$skipped, callStartedAt, KNOWN_KEYS, ALIASES, unknownKeys, hints, edits, EDIT_KEYS, EDIT_ALIASES, editFaults, addRows, addRowsTsv, listedAddRowCount, tsvHeaderLine, tsvRowLines, lines, header, duplicate, faults, removeRowIds, removeRows, editedRows, removedRows, intendedRowCount, _prelude, _resolveGrid3, _entry2, _api2, _error2, handle, explicitParentRow, mountedAfterFirst, isSubtable, parentBinding, boundParentRow, parentBindingNote, idColumnPresent, isUnloadedRecordId, reroutedRecordIds, _iterator9, _step9, _edit2, _i3, _arr2, rowId, serieScope, fmt, _divaDefs, checkCellInput, parserRefusal, parseRefusalOf, newRowEditability, newRowEditRefusal, typedValueOf, computedRefusalOf, writeCell, isLookupColumn, lookupWrite, staged, storedWrite, expectedValueOf, stagingNotes, failed, unchanged, removed, removedRecordIds, filterBeforeStaging, keyFilterApplied, restoreUserFilter, keyFilterChanged, keyCache, keyRefusals, resolveByKey, resolveTarget, applyEditToNode, columnDefFor, requiredFields, failures, editabilityUnverified, failedRows, problems, needsServerLookup, lookupKeyOf, lookupKeys, _iterator11, _step11, _edit3, _keyColumn6, _keyValue6, _iterator12, _step12, _removal, _keyColumn7, _keyValue7, _iterator13, _step13, edit, keyColumn, keyValue, _iterator14, _step14, removal, _keyColumn, _keyValue, keysByColumn, _i6, _arr3, _keysByColumn$get, address, _keyColumn2, _iterator15, _step15, _step15$value, _keyColumn3, keyValues, _deadline, refusals, _iterator16, _step16, _step16$value, _keyValue2, refusal, mergedOutcome, mergeCommitOutcome, preApproved, notProcessedKeys, chunkFailure, chunkCommitThrew, intendedCount, _approved, passDeadline, serverChunks, roomForAnotherChunk, blockSize, _keysByColumn, _iterator17, _step17, _keysByColumn$get2, _step17$value, _keyColumn4, _keyValue3, handledKeys, settledKeys, chunkError, _located2, settleVerdicts, stageChunk, _iterator25, _step25, _step25$value, _keyColumn5, _keyValues, _iterator26, _step26, _keyValue4, _bulk2, lookupDeadline, reason, _iterator27, _step27, _keyValue5, key, _iterator28, _step28, _key, _iterator29, _step29, value, filterWasChanged, remainingEdits, remainingRemovals, _iterator30, _step30, _removal2, _target, _target$error, id, _iterator31, _step31, _edit4$column, _edit4, _column2, _target2, _target2$error, _node2, _rowId2, targets, _iterator32, _step32, _api2$getRowNode2, _rowId, addedRows, providedAddColumns, conditionedPosDefaults, lookupWriteCache, addRowsStopAt, _loop4, _ret3, _i7, unsentListedRows, unsentTsvLines, keyRemainingCount, addRemainingCount, remainingCount, remainingPart, addSchemaHint, validationErrors, alreadySent, _iterator33, _step33, _api2$getRowNode12, _rowId3, rowErrors, focusNode, totalStaged, survivingOperations, cleaningLabel, approved, survived, survivedCount, trimEcho, storedOf, finalOutcome, outcome, serverErrors, reported, isSessionRowId, sentValuesOf, lengthLimitNote, addError, _iterator34, _step34, failure, _iterator35, _step35, _rowId4, _iterator36, _step36, _rowId5, _iterator37, _step37, _api2$getRowNode13, _rowId6, _rowErrors, _i9, _addedRows, _api2$getRowNode5, a, outcomeIsEmpty, survivedAfterCommit, autoCommitted, autoCommittedOps, committedIds, failedIds, editTargets, addTargets, removalTargets, hasIdColumn, verifyDeadline, verifyDeadlineHit, filterBeforeVerify, verifyFilterApplied, probeServerRow, restoreVerifyFilter, verifiedChanges, verifiedAdds, verifiedRemovals, _iterator38, _step38, _loop5, _iterator39, _step39, _loop6, _iterator40, _step40, target, probe, appliedCount, livePath, editorPathFor, echoValues, withServerIds, addedRowsWithoutId, landedInSeries, foreignSeries, committedOps, confirmedCount, notCommittedRowIds, isEmptyCell, silentlyDropped, storedDiffers, dirtyGrids, _root$navigationState4, _livePath$match, _livePath$match2, _ref55, _ref56, _livePath, packageBase, catalogBase, baseId, isPack, _root$webplannerInsta, destroyed, reloadTriggered, knownKeys, source, _action, _input, _entry3$getActions, _entry3$getActions2, _resolveGrid4, _entry3, _error3, _handle, actionName, actionInput, _addTargets, removeTargets, viewActions, available, approve, declined, autoNote, authorizedFetch, refreshAndSettle, unsettledNote, viewAction, mutating, cloneSettled, _catalogId, _handle$getApplicatio7, _handle$getApplicatio8, catalogId, importSettled, _handle$getApplicatio9, _handle$getApplicatio10, _params2$scope, _pricelistNode, app, serieNo, _params2, scope, _key4, parent, parentHandle, pricelistNode, patch, label, factors, pricelistRowId, factorOutcome, rejected, _handle$getApplicatio11, _handle$getApplicatio12, _app, pricesSettled, removeTargetIn, _target3, _header, live, saved, gone, attempt, rowsNote, _target4, markAdded, keys, resolved, _iterator43, _step43, _loop9, _ret5, added, newColumns, _loop10, _i15, _resolved, decisionSubtableNote, partialNote, _column8, _search, _entry4$getActions, _entry4$getActions2, _enumDef$customParams, _data, _plainWords$sort$, _resolveGrid5, _entry4, _api3, _error4, _handle2, _column7, search, _limit, wantsExact, needle, equals, optionAction, _yield$optionAction$o, options, note, enumDef, enumData, _enumDef$customParams2, computedDef, savedRowsOnly, _fields2, _enumDef$cellDataType, firstRow, rowData, patternChars, plainWords, remoteSearch, matchLocally, fetchLimit, fetched, text, _options, fetchCapped, _handle2$getApplicati, _handle2$getApplicati2, appScope, deps, hint, _resolveGrid6, _api4, _error5, _resolveGrid7, _entry5, _error6, _handle3, _label, _autoNote;
82032
+ var awaitingApproval, args, _allViews2, views, editorSubviews, _args$path, _root$navigationState2, _allViews3, _views, _editorSubviews, requested, dynamic, known, editorView, _permittedEditorViews4, idm, enricher, subViews, catalogIdIn, fromCatalog, toCatalog, only, entries, compactWanted, fullWanted, _args$value, _resolveGrid, entry, api, error, multiValues, _entry$getHandle$getD, _entry$getHandle2, filterBeforeBulk, deadline, bulk, _api$getFilterModel, requestedColumns, fields, rows, _notUnique, returnedData, returnedRoots, fieldsOmitted, unknownColumns, _bulk, missing, unverified, notReached, filterBeforeLocate, _located, _args$value2, matchedRows, carrierCount, notUnique, _cellValueOf2, matchedValue, gridsOnScreen, subtableHint, trimmedFirstRow, revealNote, revealed, _args$id, openError, _entry$getHandle$getD3, _entry$getHandle4, _lastNode$data, _entry$getHandle$hasP, _entry$getHandle5, _api$getFilterModel2, prelude, _resolveGrid2, _entry, _api, _error, waitedForRowsMs, previewCell, divaDefs, leafFields, _requested, columns, _unknownColumns, limit, _rows, displayed, unsavedRowCount, i, _api$getDisplayedRowA, context, _i2, node, values, truncatedColumns, _iterator8, _step8, column, raw, labelled, columnMeta, lastNode, gridContext, hasCreatorRow, creatorRowLoaded, totalRowCount, dirty, filterModel, filteredBy, _ref31, _ref32, _staged$0$rowId, _staged$, _addedRows$, _outcome$committed, _root$navigationState3, _outcome$failed, _outcome$declined2, _outcome$skipped, callStartedAt, KNOWN_KEYS, ALIASES, unknownKeys, hints, edits, EDIT_KEYS, EDIT_ALIASES, editFaults, addRows, addRowsTsv, listedAddRowCount, tsvHeaderLine, tsvRowLines, lines, header, duplicate, faults, removeRowIds, removeRows, editedRows, removedRows, intendedRowCount, _prelude, _resolveGrid3, _entry2, _api2, _error2, handle, explicitParentRow, mountedAfterFirst, isSubtable, parentBinding, boundParentRow, parentBindingNote, idColumnPresent, isUnloadedRecordId, reroutedRecordIds, _iterator9, _step9, _edit2, _i3, _arr2, rowId, serieScope, fmt, _divaDefs, checkCellInput, parserRefusal, parseRefusalOf, newRowEditability, newRowEditRefusal, typedValueOf, computedRefusalOf, writeCell, isLookupColumn, lookupWrite, staged, storedWrite, expectedValueOf, stagingNotes, failed, unchanged, removed, removedRecordIds, filterBeforeStaging, keyFilterApplied, restoreUserFilter, keyFilterChanged, keyCache, keyRefusals, resolveByKey, resolveTarget, applyEditToNode, columnDefFor, requiredFields, failures, editabilityUnverified, failedRows, problems, needsServerLookup, lookupKeyOf, lookupKeys, _iterator11, _step11, _edit3, _keyColumn6, _keyValue6, _iterator12, _step12, _removal, _keyColumn7, _keyValue7, _iterator13, _step13, edit, keyColumn, keyValue, _iterator14, _step14, removal, _keyColumn, _keyValue, keysByColumn, _i6, _arr3, _keysByColumn$get, address, _keyColumn2, _iterator15, _step15, _step15$value, _keyColumn3, keyValues, _deadline, refusals, _iterator16, _step16, _step16$value, _keyValue2, refusal, mergedOutcome, mergeCommitOutcome, preApproved, notProcessedKeys, chunkFailure, chunkCommitThrew, intendedCount, _approved, passDeadline, serverChunks, roomForAnotherChunk, blockSize, _keysByColumn, _iterator17, _step17, _keysByColumn$get2, _step17$value, _keyColumn4, _keyValue3, handledKeys, settledKeys, chunkError, _located2, settleVerdicts, stageChunk, _iterator25, _step25, _step25$value, _keyColumn5, _keyValues, _iterator26, _step26, _keyValue4, _bulk2, lookupDeadline, reason, _iterator27, _step27, _keyValue5, key, _iterator28, _step28, _key, _iterator29, _step29, value, filterWasChanged, remainingEdits, remainingRemovals, _iterator30, _step30, _removal2, _target, _target$error, id, _iterator31, _step31, _edit4$column, _edit4, _column2, _target2, _target2$error, _node2, _rowId2, targets, _iterator32, _step32, _api2$getRowNode2, _rowId, addedRows, providedAddColumns, conditionedPosDefaults, lookupWriteCache, addRowsStopAt, _loop4, _ret3, _i7, unsentListedRows, unsentTsvLines, keyRemainingCount, addRemainingCount, remainingCount, remainingPart, addSchemaHint, validationErrors, alreadySent, _iterator33, _step33, _api2$getRowNode12, _rowId3, rowErrors, focusNode, totalStaged, survivingOperations, cleaningLabel, approved, survived, survivedCount, withdrawn, decision, trimEcho, storedOf, finalOutcome, outcome, serverErrors, reported, isSessionRowId, sentValuesOf, lengthLimitNote, addError, _iterator34, _step34, failure, _iterator35, _step35, _rowId4, _iterator36, _step36, _rowId5, _iterator37, _step37, _api2$getRowNode13, _rowId6, _rowErrors, _i9, _addedRows, _api2$getRowNode5, a, outcomeIsEmpty, survivedAfterCommit, autoCommitted, autoCommittedOps, committedIds, failedIds, editTargets, addTargets, removalTargets, hasIdColumn, verifyDeadline, verifyDeadlineHit, filterBeforeVerify, verifyFilterApplied, probeServerRow, restoreVerifyFilter, verifiedChanges, verifiedAdds, verifiedRemovals, _iterator38, _step38, _loop5, _iterator39, _step39, _loop6, _iterator40, _step40, target, probe, appliedCount, livePath, editorPathFor, echoValues, withServerIds, addedRowsWithoutId, landedInSeries, foreignSeries, committedOps, confirmedCount, notCommittedRowIds, isEmptyCell, silentlyDropped, storedDiffers, _root$navigationState4, _ctx$getSelection, dirtyGrids, _root$navigationState5, _livePath$match, _livePath$match2, _ref55, _ref56, _livePath, packageBase, catalogBase, baseId, isPack, _root$webplannerInsta, destroyed, reloadTriggered, knownKeys, source, _action, _input, _entry3$getActions, _entry3$getActions2, _resolveGrid4, _entry3, _error3, _handle, actionName, actionInput, _addTargets, removeTargets, viewActions, available, approve, declined, autoNote, authorizedFetch, refreshAndSettle, unsettledNote, viewAction, mutating, cloneSettled, _catalogId, _handle$getApplicatio7, _handle$getApplicatio8, catalogId, importSettled, _handle$getApplicatio9, _handle$getApplicatio10, _params2$scope, _pricelistNode, app, serieNo, _params2, scope, _key4, parent, parentHandle, pricelistNode, patch, label, factors, pricelistRowId, factorOutcome, rejected, _handle$getApplicatio11, _handle$getApplicatio12, _app, pricesSettled, removeTargetIn, _target3, _header, live, saved, gone, attempt, rowsNote, _target4, markAdded, keys, resolved, _iterator43, _step43, _loop9, _ret5, added, newColumns, _loop10, _i15, _resolved, decisionSubtableNote, partialNote, _column8, _search, _entry4$getActions, _entry4$getActions2, _enumDef$customParams, _optionsRow$data, _plainWords$sort$, _resolveGrid5, _entry4, _api3, _error4, _handle2, _column7, search, _limit, wantsExact, needle, equals, optionAction, _yield$optionAction$o, options, note, enumDef, enumData, _enumDef$customParams2, computedDef, savedRowsOnly, _fields2, _enumDef$cellDataType, optionsRowId, optionsRow, rowData, patternChars, plainWords, remoteSearch, matchLocally, fetchLimit, fetched, text, _options, fetchCapped, _handle2$getApplicati, _handle2$getApplicati2, appScope, deps, hint, _resolveGrid6, _api4, _error5, _resolveGrid7, _entry5, _error6, _handle3, _label, _autoNote;
81789
82033
  return _regeneratorRuntime.wrap(function _callee13$(_context21) {
81790
82034
  while (1) switch (_context21.prev = _context21.next) {
81791
82035
  case 0:
@@ -81794,7 +82038,7 @@ function createNavigationToolset(ctx) {
81794
82038
  };
81795
82039
  args = input !== null && input !== void 0 ? input : {};
81796
82040
  _context21.t0 = name;
81797
- _context21.next = _context21.t0 === 'listViews' ? 5 : _context21.t0 === 'navigateTo' ? 7 : _context21.t0 === 'listGrids' ? 23 : _context21.t0 === 'locateRow' ? 30 : _context21.t0 === 'openToolbarTool' ? 94 : _context21.t0 === 'readGridRows' ? 102 : _context21.t0 === 'stageTableEdits' ? 171 : _context21.t0 === 'reloadPage' ? 690 : _context21.t0 === 'reloadPlanner' ? 695 : _context21.t0 === 'runTableAction' ? 709 : _context21.t0 === 'readColumnOptions' ? 962 : _context21.t0 === 'clearGridFilter' ? 1028 : _context21.t0 === 'discardStagedChanges' ? 1033 : 1054;
82041
+ _context21.next = _context21.t0 === 'listViews' ? 5 : _context21.t0 === 'navigateTo' ? 7 : _context21.t0 === 'listGrids' ? 28 : _context21.t0 === 'locateRow' ? 35 : _context21.t0 === 'openToolbarTool' ? 99 : _context21.t0 === 'readGridRows' ? 107 : _context21.t0 === 'stageTableEdits' ? 176 : _context21.t0 === 'reloadPage' ? 702 : _context21.t0 === 'reloadPlanner' ? 708 : _context21.t0 === 'runTableAction' ? 722 : _context21.t0 === 'readColumnOptions' ? 975 : _context21.t0 === 'clearGridFilter' ? 1044 : _context21.t0 === 'discardStagedChanges' ? 1049 : 1070;
81798
82042
  break;
81799
82043
  case 5:
81800
82044
  _allViews2 = allViews(root, ctx), views = _allViews2.views, editorSubviews = _allViews2.editorSubviews;
@@ -81804,8 +82048,8 @@ function createNavigationToolset(ctx) {
81804
82048
  editorSubviews: editorSubviews
81805
82049
  });
81806
82050
  case 7:
81807
- _allViews3 = allViews(root, ctx), _views = _allViews3.views, _editorSubviews = _allViews3.editorSubviews; // Models regularly prepend a leading slash — normalize instead of rejecting.
81808
- requested = String((_args$path = args.path) !== null && _args$path !== void 0 ? _args$path : '').replace(/^\//, '');
82051
+ _allViews3 = allViews(root, ctx), _views = _allViews3.views, _editorSubviews = _allViews3.editorSubviews; // Models prepend a leading slash and copy old links — normalize instead of rejecting.
82052
+ requested = normalizeNavigationPath(String((_args$path = args.path) !== null && _args$path !== void 0 ? _args$path : ''));
81809
82053
  dynamic = isDynamicEditorPath(root, requested); // Thrown (not returned) so the failed call does NOT end the turn — the model corrects the path in the same turn.
81810
82054
  if (!(dynamic === 'bad-id')) {
81811
82055
  _context21.next = 12;
@@ -81817,13 +82061,24 @@ function createNavigationToolset(ctx) {
81817
82061
  return view.path === requested;
81818
82062
  }) || _editorSubviews.some(function (view) {
81819
82063
  return view.path === requested;
81820
- }) || dynamic === true;
82064
+ }) || dynamic === true; // An editor path with a sub-view the editor does not have: name the ones it has instead of a bare refusal.
82065
+ editorView = /^(catalogs|packages)\/[0-9a-f]{24}\/(.+)$/i.exec(requested);
82066
+ if (!(requested && !known && editorView)) {
82067
+ _context21.next = 18;
82068
+ break;
82069
+ }
82070
+ _permittedEditorViews4 = permittedEditorViews(root), idm = _permittedEditorViews4.idm, enricher = _permittedEditorViews4.enricher;
82071
+ subViews = (editorView[1] === 'catalogs' ? idm : enricher).map(function (view) {
82072
+ return view.path;
82073
+ });
82074
+ throw new Error("Unknown sub-view '".concat(editorView[2], "' in '").concat(args.path, "' \u2014 the ").concat(editorView[1] === 'catalogs' ? 'catalog' : 'pack', " editor has: ").concat(subViews.join(', ') || 'none you may open', "."));
82075
+ case 18:
81821
82076
  if (!(!requested || !known)) {
81822
- _context21.next = 15;
82077
+ _context21.next = 20;
81823
82078
  break;
81824
82079
  }
81825
82080
  throw new Error("Unknown path '".concat(args.path, "' \u2014 use a path from listViews (never guess paths)."));
81826
- case 15:
82081
+ case 20:
81827
82082
  // Direct catalog→catalog jumps crash the router while the old planner state is mounted — force the two-step via the list.
81828
82083
  catalogIdIn = function catalogIdIn(path) {
81829
82084
  var _exec2;
@@ -81832,11 +82087,11 @@ function createNavigationToolset(ctx) {
81832
82087
  fromCatalog = catalogIdIn((_root$navigationState2 = root.navigationState.path) !== null && _root$navigationState2 !== void 0 ? _root$navigationState2 : '');
81833
82088
  toCatalog = catalogIdIn(requested);
81834
82089
  if (!(fromCatalog && toCatalog && fromCatalog !== toCatalog)) {
81835
- _context21.next = 20;
82090
+ _context21.next = 25;
81836
82091
  break;
81837
82092
  }
81838
82093
  throw new Error("Direct switch into ANOTHER catalog (".concat(fromCatalog, " \u2192 ").concat(toCatalog, ") is blocked: with the current catalog's planner state mounted it has crashed the router and the agent bridge. ") + "Go via the list instead: navigateTo 'catalogs' first (unmounts the editor cleanly), THEN navigateTo the target catalog's sub-view.");
81839
- case 20:
82094
+ case 25:
81840
82095
  // Deferred so the turn persists BEFORE the unmount; the pending marker suppresses the auto-'Continue.' in the gap.
81841
82096
  pendingAgentNavigation.set(requested);
81842
82097
  setTimeout(function () {
@@ -81846,18 +82101,20 @@ function createNavigationToolset(ctx) {
81846
82101
  }, 500);
81847
82102
  return _context21.abrupt("return", {
81848
82103
  ok: true,
82104
+ // The bridge waits for THIS path — it can differ from the argument once normalized.
82105
+ path: requested,
81849
82106
  note: "Navigation triggered — this turn ends here; an automatic 'Continue.' follows after arrival."
81850
82107
  });
81851
- case 23:
82108
+ case 28:
81852
82109
  only = args.grid ? resolveGrid(args.grid) : undefined;
81853
82110
  if (!(only !== null && only !== void 0 && only.error || only && !only.entry)) {
81854
- _context21.next = 26;
82111
+ _context21.next = 31;
81855
82112
  break;
81856
82113
  }
81857
82114
  return _context21.abrupt("return", {
81858
82115
  error: only.error
81859
82116
  });
81860
- case 26:
82117
+ case 31:
81861
82118
  entries = only !== null && only !== void 0 && only.entry ? [only.entry] : root.gridRegistry.entries;
81862
82119
  compactWanted = (input === null || input === void 0 ? void 0 : input.compact) === true; // An explicit compact:false on ONE table overrides the size guard — the caller asked for the metadata and pays for it.
81863
82120
  fullWanted = (input === null || input === void 0 ? void 0 : input.compact) === false && !!(only !== null && only !== void 0 && only.entry);
@@ -81932,41 +82189,41 @@ function createNavigationToolset(ctx) {
81932
82189
  });
81933
82190
  })
81934
82191
  });
81935
- case 30:
82192
+ case 35:
81936
82193
  _resolveGrid = resolveGrid(args.grid), entry = _resolveGrid.entry, api = _resolveGrid.api, error = _resolveGrid.error;
81937
82194
  if (!(error || !api || !entry)) {
81938
- _context21.next = 33;
82195
+ _context21.next = 38;
81939
82196
  break;
81940
82197
  }
81941
82198
  return _context21.abrupt("return", {
81942
82199
  error: error
81943
82200
  });
81944
- case 33:
82201
+ case 38:
81945
82202
  // BULK READ: one call instead of a locateRow chain. Read-only — the pre-bulk filter model is restored before returning.
81946
82203
  multiValues = Array.isArray(input === null || input === void 0 ? void 0 : input.values) ? input.values.map(String) : undefined;
81947
82204
  if (!(multiValues !== null && multiValues !== void 0 && multiValues.length)) {
81948
- _context21.next = 61;
82205
+ _context21.next = 66;
81949
82206
  break;
81950
82207
  }
81951
82208
  filterBeforeBulk = api.getFilterModel(); // Time budget: running past the call timeout leaves this handler blocking the serialized call queue.
81952
82209
  deadline = Date.now() + 14000;
81953
- _context21.prev = 37;
81954
- _context21.next = 40;
82210
+ _context21.prev = 42;
82211
+ _context21.next = 45;
81955
82212
  return bulkLocateRows(api, args.column, multiValues, deadline);
81956
- case 40:
82213
+ case 45:
81957
82214
  bulk = _context21.sent;
81958
- _context21.next = 47;
82215
+ _context21.next = 52;
81959
82216
  break;
81960
- case 43:
81961
- _context21.prev = 43;
81962
- _context21.t1 = _context21["catch"](37);
82217
+ case 48:
82218
+ _context21.prev = 48;
82219
+ _context21.t1 = _context21["catch"](42);
81963
82220
  // A lookup that failed AFTER its filter went out (a column that takes no equals filter) must not leave the
81964
82221
  // user's own filter wiped — setFilterModel replaces the whole model, not just this column's part.
81965
82222
  if (JSON.stringify((_api$getFilterModel = api.getFilterModel()) !== null && _api$getFilterModel !== void 0 ? _api$getFilterModel : {}) !== JSON.stringify(filterBeforeBulk !== null && filterBeforeBulk !== void 0 ? filterBeforeBulk : {})) api.setFilterModel(Object.keys(filterBeforeBulk !== null && filterBeforeBulk !== void 0 ? filterBeforeBulk : {}).length ? filterBeforeBulk : null);
81966
82223
  return _context21.abrupt("return", {
81967
82224
  error: _context21.t1 instanceof Error ? _context21.t1.message : String(_context21.t1)
81968
82225
  });
81969
- case 47:
82226
+ case 52:
81970
82227
  // Row previews BEFORE the filter goes back — the grid recycles its nodes on a refilter.
81971
82228
  requestedColumns = Array.isArray(input === null || input === void 0 ? void 0 : input.columns) ? input.columns.map(String) : [];
81972
82229
  fields = _toConsumableArray(new Set([].concat(_toConsumableArray(bulkRowFields((_entry$getHandle$getD = (_entry$getHandle2 = entry.getHandle()) === null || _entry$getHandle2 === void 0 ? void 0 : _entry$getHandle2.getDivaColumnDefs()) !== null && _entry$getHandle$getD !== void 0 ? _entry$getHandle$getD : [], bulk.column)), _toConsumableArray(requestedColumns))));
@@ -82013,14 +82270,14 @@ function createNavigationToolset(ctx) {
82013
82270
  });
82014
82271
  }) : []; // A pure read must not leave lookup filters behind — restore what was active before.
82015
82272
  if (!bulk.filterApplied) {
82016
- _context21.next = 59;
82273
+ _context21.next = 64;
82017
82274
  break;
82018
82275
  }
82019
82276
  api.setFilterModel(Object.keys(filterBeforeBulk !== null && filterBeforeBulk !== void 0 ? filterBeforeBulk : {}).length ? filterBeforeBulk : null);
82020
82277
  // The settle wait lives inside the budget too — the model is restored either way.
82021
- _context21.next = 59;
82278
+ _context21.next = 64;
82022
82279
  return waitForRows(api, Math.max(0, deadline - Date.now()));
82023
- case 59:
82280
+ case 64:
82024
82281
  _bulk = bulk, missing = _bulk.missing, unverified = _bulk.unverified, notReached = _bulk.notReached;
82025
82282
  return _context21.abrupt("return", _objectSpread$A(_objectSpread$A(_objectSpread$A(_objectSpread$A(_objectSpread$A(_objectSpread$A(_objectSpread$A({
82026
82283
  rows: rows
@@ -82039,33 +82296,33 @@ function createNavigationToolset(ctx) {
82039
82296
  } : {}), {}, {
82040
82297
  note: "".concat(rows.length, "/").concat(multiValues.length, " located") + (bulk.serverLookups ? " in ".concat(bulk.serverLookups, " server lookup(s) of up to ").concat(BULK_LOOKUP_CHUNK, " values each.") : ' from the loaded rows, no server lookup needed.') + (returnedData.length ? " Each row carries _id, the located column and the table's required and lookup columns (translated ones in their first language)" + (fieldsOmitted.length ? ' — fieldsOmitted names the other record fields, pass the ones you need in `columns`.' : '.') : '') + (unknownColumns.length ? ' unknownColumns: no returned row carries these fields.' : '') + (missing.length ? " Missing values did NOT match — check them for typos before concluding they don't exist." : '') + (unverified.length ? " UNVERIFIED values have NO verdict \u2014 that is not a miss: their server lookup did not answer within ".concat(LOOKUP_WAIT_MS / 1000, " s, or the batch matched more rows than the table loads at once. Look them up again (smaller batches, once the tab is idle), never conclude they do not exist.") : '') + (_notUnique.length ? " notUnique values match SEVERAL rows \u2014 their rows are listed (at most ".concat(NOT_UNIQUE_ROW_LIMIT, "; matches = how many carry the exact value). Never use such a value as a reference id; address the record you mean by its _id.") : '') + (notReached.length ? " TIME BUDGET HIT: ".concat(notReached.length, " value(s) were NOT looked up \u2014 call again with just those.") : ' No filter was left behind.')
82041
82298
  }));
82042
- case 61:
82299
+ case 66:
82043
82300
  if (!(((_args$value = args.value) !== null && _args$value !== void 0 ? _args$value : '') === '')) {
82044
- _context21.next = 63;
82301
+ _context21.next = 68;
82045
82302
  break;
82046
82303
  }
82047
82304
  return _context21.abrupt("return", {
82048
82305
  error: "Provide 'value' (one row) or 'values' (bulk read)."
82049
82306
  });
82050
- case 63:
82307
+ case 68:
82051
82308
  // Captured before the lookup: a rejected loose hit must hand the user's OWN filter back, not an empty one.
82052
82309
  filterBeforeLocate = api.getFilterModel();
82053
- _context21.prev = 64;
82054
- _context21.next = 67;
82310
+ _context21.prev = 69;
82311
+ _context21.next = 72;
82055
82312
  return locateRowCore(api, args.column, String((_args$value2 = args.value) !== null && _args$value2 !== void 0 ? _args$value2 : ''), args.select !== false);
82056
- case 67:
82313
+ case 72:
82057
82314
  _located = _context21.sent;
82058
- _context21.next = 73;
82315
+ _context21.next = 78;
82059
82316
  break;
82060
- case 70:
82061
- _context21.prev = 70;
82062
- _context21.t2 = _context21["catch"](64);
82317
+ case 75:
82318
+ _context21.prev = 75;
82319
+ _context21.t2 = _context21["catch"](69);
82063
82320
  return _context21.abrupt("return", {
82064
82321
  error: _context21.t2 instanceof Error ? _context21.t2.message : String(_context21.t2)
82065
82322
  });
82066
- case 73:
82323
+ case 78:
82067
82324
  if (_located.node) {
82068
- _context21.next = 75;
82325
+ _context21.next = 80;
82069
82326
  break;
82070
82327
  }
82071
82328
  return _context21.abrupt("return", _objectSpread$A(_objectSpread$A({
@@ -82075,7 +82332,7 @@ function createNavigationToolset(ctx) {
82075
82332
  } : {}), {}, {
82076
82333
  note: _located.lookupTimedOut ? "The server filter for ".concat(args.column, " = '").concat(args.value, "' did NOT answer within ").concat(LOOKUP_WAIT_MS / 1000, " s \u2014 this is NOT proof that the row is missing (a busy or stuck grid). Retry once the tab is idle; the lookup filter is already removed.") : "No row matched ".concat(args.column, " ~ '").concat(args.value, "'. The lookup filter is already removed \u2014 do NOT call clearGridFilter, it would drop a filter the user set.")
82077
82334
  }));
82078
- case 75:
82335
+ case 80:
82079
82336
  matchedRows = _located.filterApplied ? countDisplayedRealRows(api) : _located.loadedMatches;
82080
82337
  carrierCount = _located.exact ? countExactRows(api, _located.column, String(args.value)) : 0;
82081
82338
  notUnique = carrierCount > 1 ? {
@@ -82088,30 +82345,30 @@ function createNavigationToolset(ctx) {
82088
82345
  } : undefined; // `exact:true` requires a genuine hit — a loose (contains/prefix) one is reported as NOT FOUND rather
82089
82346
  // than handed back disguised as the requested value (serieNo '9' resolving to '99').
82090
82347
  if (!(args.exact && !_located.exact)) {
82091
- _context21.next = 85;
82348
+ _context21.next = 90;
82092
82349
  break;
82093
82350
  }
82094
82351
  matchedValue = String((_cellValueOf2 = cellValueOf(api, _located.node, _located.column)) !== null && _cellValueOf2 !== void 0 ? _cellValueOf2 : '');
82095
82352
  if (!_located.filterApplied) {
82096
- _context21.next = 84;
82353
+ _context21.next = 89;
82097
82354
  break;
82098
82355
  }
82099
82356
  api.setFilterModel(Object.keys(filterBeforeLocate !== null && filterBeforeLocate !== void 0 ? filterBeforeLocate : {}).length ? filterBeforeLocate : null);
82100
- _context21.next = 84;
82357
+ _context21.next = 89;
82101
82358
  return waitForRows(api);
82102
- case 84:
82359
+ case 89:
82103
82360
  return _context21.abrupt("return", {
82104
82361
  matchedRows: 0,
82105
82362
  note: "No EXACT match for ".concat(args.column, " = '").concat(args.value, "' \u2014 the closest candidate was '").concat(matchedValue, "' (").concat(matchedRows, " loose candidate(s) total, none exact). Nothing was selected.")
82106
82363
  });
82107
- case 85:
82364
+ case 90:
82108
82365
  if (!(args.select !== false)) {
82109
- _context21.next = 88;
82366
+ _context21.next = 93;
82110
82367
  break;
82111
82368
  }
82112
- _context21.next = 88;
82369
+ _context21.next = 93;
82113
82370
  return sleep(400);
82114
- case 88:
82371
+ case 93:
82115
82372
  // A subtable already on screen re-renders in place, so only openToolbarTool for one NOT yet listed.
82116
82373
  gridsOnScreen = root.gridRegistry.entries.map(function (e) {
82117
82374
  return e.label;
@@ -82144,59 +82401,59 @@ function createNavigationToolset(ctx) {
82144
82401
  gridsOnScreen: gridsOnScreen,
82145
82402
  note: (notUnique ? "NOT UNIQUE: ".concat(notUnique.matches, " rows carry ").concat(args.column, " = '").concat(args.value, "' \u2014 firstRow is only the first of them, notUnique.rows lists them. Never use this value as a reference id; address the record you mean by its _id. ") : '') + (_located.exact ? '' : "NOT AN EXACT MATCH: ".concat(args.column, " = '").concat(args.value, "' was requested but this row's value is different (see firstRow) \u2014 ") + "it only matched loosely. Do not treat this as proof that '".concat(args.value, "' exists; pass exact:true to require a genuine hit instead of the closest candidate. ")) + (_located.filterApplied ? 'VERIFY via firstRow that this is really the requested entity. LEAVE the filter active — it is what shows the user the match; clearGridFilter only when the user is done with this row or before locating something else.' : 'The row was already loaded — scrolled to and highlighted WITHOUT filtering; the table is fully loaded (or the value is an _id), so matchedRows is complete. No filter to clear.') + subtableHint + revealNote
82146
82403
  }));
82147
- case 94:
82148
- _context21.next = 96;
82404
+ case 99:
82405
+ _context21.next = 101;
82149
82406
  return openToolbarToolById(String((_args$id = args.id) !== null && _args$id !== void 0 ? _args$id : ''));
82150
- case 96:
82407
+ case 101:
82151
82408
  openError = _context21.sent;
82152
82409
  if (!openError) {
82153
- _context21.next = 99;
82410
+ _context21.next = 104;
82154
82411
  break;
82155
82412
  }
82156
82413
  throw new Error(openError);
82157
- case 99:
82158
- _context21.next = 101;
82414
+ case 104:
82415
+ _context21.next = 106;
82159
82416
  return sleep(400);
82160
- case 101:
82417
+ case 106:
82161
82418
  return _context21.abrupt("return", {
82162
82419
  ok: true,
82163
82420
  gridsNowOnScreen: root.gridRegistry.entries.map(function (entry) {
82164
82421
  return entry.label;
82165
82422
  })
82166
82423
  });
82167
- case 102:
82168
- _context21.next = 104;
82424
+ case 107:
82425
+ _context21.next = 109;
82169
82426
  return applyParentRowPrelude(input, args);
82170
- case 104:
82427
+ case 109:
82171
82428
  prelude = _context21.sent;
82172
82429
  if (!prelude) {
82173
- _context21.next = 107;
82430
+ _context21.next = 112;
82174
82431
  break;
82175
82432
  }
82176
82433
  return _context21.abrupt("return", prelude);
82177
- case 107:
82434
+ case 112:
82178
82435
  _resolveGrid2 = resolveGrid(args.grid), _entry = _resolveGrid2.entry, _api = _resolveGrid2.api, _error = _resolveGrid2.error;
82179
82436
  if (!(_error || !_api || !_entry)) {
82180
- _context21.next = 110;
82437
+ _context21.next = 115;
82181
82438
  break;
82182
82439
  }
82183
82440
  return _context21.abrupt("return", {
82184
82441
  error: _error
82185
82442
  });
82186
- case 110:
82443
+ case 115:
82187
82444
  if (!isRealRow(_api.getDisplayedRowAtIndex(0))) {
82188
- _context21.next = 114;
82445
+ _context21.next = 119;
82189
82446
  break;
82190
82447
  }
82191
82448
  _context21.t3 = 0;
82192
- _context21.next = 117;
82449
+ _context21.next = 122;
82193
82450
  break;
82194
- case 114:
82195
- _context21.next = 116;
82451
+ case 119:
82452
+ _context21.next = 121;
82196
82453
  return waitForRows(_api);
82197
- case 116:
82454
+ case 121:
82198
82455
  _context21.t3 = _context21.sent;
82199
- case 117:
82456
+ case 122:
82200
82457
  waitedForRowsMs = _context21.t3;
82201
82458
  previewCell = function previewCell(column, v, truncatedColumns) {
82202
82459
  if (v == null || _typeof(v) !== 'object') return v;
@@ -82236,66 +82493,66 @@ function createNavigationToolset(ctx) {
82236
82493
  if (context !== null && context !== void 0 && context.isNew && !context.isEmpty) unsavedRowCount += 1;
82237
82494
  }
82238
82495
  _i2 = 0;
82239
- case 130:
82496
+ case 135:
82240
82497
  if (!(_i2 < displayed && _rows.length < limit)) {
82241
- _context21.next = 161;
82498
+ _context21.next = 166;
82242
82499
  break;
82243
82500
  }
82244
82501
  node = _api.getDisplayedRowAtIndex(_i2);
82245
82502
  if (!(!isRealRow(node) || !node.id)) {
82246
- _context21.next = 134;
82503
+ _context21.next = 139;
82247
82504
  break;
82248
82505
  }
82249
- return _context21.abrupt("continue", 158);
82250
- case 134:
82506
+ return _context21.abrupt("continue", 163);
82507
+ case 139:
82251
82508
  values = {};
82252
82509
  truncatedColumns = [];
82253
82510
  _iterator8 = _createForOfIteratorHelper$i(columns);
82254
- _context21.prev = 137;
82511
+ _context21.prev = 142;
82255
82512
  _iterator8.s();
82256
- case 139:
82513
+ case 144:
82257
82514
  if ((_step8 = _iterator8.n()).done) {
82258
- _context21.next = 149;
82515
+ _context21.next = 154;
82259
82516
  break;
82260
82517
  }
82261
82518
  column = _step8.value;
82262
82519
  raw = cellValueOf(_api, node, column);
82263
82520
  labelled = labelledLookupValues(divaDefOf(divaDefs, column), raw, node.data);
82264
82521
  if (!labelled) {
82265
- _context21.next = 146;
82522
+ _context21.next = 151;
82266
82523
  break;
82267
82524
  }
82268
82525
  values[column] = labelled;
82269
- return _context21.abrupt("continue", 147);
82270
- case 146:
82526
+ return _context21.abrupt("continue", 152);
82527
+ case 151:
82271
82528
  // The stored SET_POS_COUNT_VALUE:n form reads like a decision action; the number is what gets written back.
82272
82529
  values[column] = isPosCountActionsColumn(divaDefOf(divaDefs, column)) ? posCountOf(raw) : previewCell(column, raw, truncatedColumns);
82273
- case 147:
82274
- _context21.next = 139;
82530
+ case 152:
82531
+ _context21.next = 144;
82275
82532
  break;
82276
- case 149:
82277
- _context21.next = 154;
82533
+ case 154:
82534
+ _context21.next = 159;
82278
82535
  break;
82279
- case 151:
82280
- _context21.prev = 151;
82281
- _context21.t4 = _context21["catch"](137);
82536
+ case 156:
82537
+ _context21.prev = 156;
82538
+ _context21.t4 = _context21["catch"](142);
82282
82539
  _iterator8.e(_context21.t4);
82283
- case 154:
82284
- _context21.prev = 154;
82540
+ case 159:
82541
+ _context21.prev = 159;
82285
82542
  _iterator8.f();
82286
- return _context21.finish(154);
82287
- case 157:
82543
+ return _context21.finish(159);
82544
+ case 162:
82288
82545
  _rows.push(_objectSpread$A({
82289
82546
  rowId: node.id,
82290
82547
  values: values
82291
82548
  }, truncatedColumns.length ? {
82292
82549
  truncatedColumns: truncatedColumns
82293
82550
  } : {}));
82294
- case 158:
82551
+ case 163:
82295
82552
  _i2++;
82296
- _context21.next = 130;
82553
+ _context21.next = 135;
82297
82554
  break;
82298
- case 161:
82555
+ case 166:
82299
82556
  columnMeta = columns.map(function (field) {
82300
82557
  return _objectSpread$A({
82301
82558
  column: field
@@ -82339,7 +82596,7 @@ function createNavigationToolset(ctx) {
82339
82596
  countNote: dirty ? 'This table has UNCOMMITTED staged rows, so totalRowCount is inflated by them — do not report it as the row count; enumerate, or reload the page first.' : undefined,
82340
82597
  note: _rows.length === 0 ? "The table has 0 loaded rows after polling ".concat(waitedForRowsMs, " ms for its first block \u2014 its prefilter (serie/catalog selection) yields no data here. This is not a loading race any more: treat it as empty; re-read only if you changed the selection/filter or navigated since.") : "Returned ".concat(_rows.length, " of ").concat(totalRowCount, " rows").concat(_rows.length < totalRowCount ? _rows.length === limit ? " \u2014 the `limit` (".concat(limit, ") cut the slice: re-call with a higher limit (max 500) for more. For COUNTS always report totalRowCount, never the returned slice") : ' — the rest is not loaded client-side (server-side lazy table; scrolling or a filter loads more). For COUNTS always report totalRowCount, never the returned slice' : '', ". For stageTableEdits you can address rows directly by keyColumn/keyValue (unique value) \u2014 rowId is the fallback for rows without a unique key.")
82341
82598
  }));
82342
- case 171:
82599
+ case 176:
82343
82600
  callStartedAt = Date.now(); // A misspelled top-level key would be dropped in silence and `grid` would default to the wrong table.
82344
82601
  KNOWN_KEYS = ['grid', 'edits', 'addRows', 'removeRowIds', 'removeRows', 'cleanReferences', 'parentRow', 'addRowsTsv', 'source', 'mapping', 'dryRun'];
82345
82602
  ALIASES = {
@@ -82350,18 +82607,18 @@ function createNavigationToolset(ctx) {
82350
82607
  }; // Over the MCP bridge a `source` and its `mapping` are replaced by the payload's rows before the call ever
82351
82608
  // reaches here. Arriving unexpanded means this is the in-app agent, which has no payload store of its own.
82352
82609
  if (!(input !== null && input !== void 0 && input.source || input !== null && input !== void 0 && input.mapping)) {
82353
- _context21.next = 176;
82610
+ _context21.next = 181;
82354
82611
  break;
82355
82612
  }
82356
82613
  return _context21.abrupt("return", {
82357
82614
  error: "A payload `source` (and its `mapping`) only works over the MCP bridge, where the service resolves it into rows. In this chat, pass the rows as addRows or addRowsTsv, with the table's own column ids. Nothing was staged."
82358
82615
  });
82359
- case 176:
82616
+ case 181:
82360
82617
  unknownKeys = Object.keys(input !== null && input !== void 0 ? input : {}).filter(function (key) {
82361
82618
  return !KNOWN_KEYS.includes(key);
82362
82619
  });
82363
82620
  if (!unknownKeys.length) {
82364
- _context21.next = 180;
82621
+ _context21.next = 185;
82365
82622
  break;
82366
82623
  }
82367
82624
  hints = unknownKeys.map(function (key) {
@@ -82370,7 +82627,7 @@ function createNavigationToolset(ctx) {
82370
82627
  return _context21.abrupt("return", {
82371
82628
  error: "Unknown parameter(s) ".concat(hints.join(', '), ". stageTableEdits takes: ").concat(KNOWN_KEYS.join(', '), ". Nothing was staged.")
82372
82629
  });
82373
- case 180:
82630
+ case 185:
82374
82631
  edits = Array.isArray(input === null || input === void 0 ? void 0 : input.edits) ? input.edits : []; // A missing `newValue` would coerce to '' — the documented "clear the cell" — and wipe the cell in silence.
82375
82632
  EDIT_KEYS = ['rowId', 'keyColumn', 'keyValue', 'column', 'newValue'];
82376
82633
  EDIT_ALIASES = {
@@ -82393,13 +82650,13 @@ function createNavigationToolset(ctx) {
82393
82650
  return ["edits[".concat(index, "] ").concat(faults.filter(Boolean).join(' and '))];
82394
82651
  });
82395
82652
  if (!editFaults.length) {
82396
- _context21.next = 186;
82653
+ _context21.next = 191;
82397
82654
  break;
82398
82655
  }
82399
82656
  return _context21.abrupt("return", {
82400
82657
  error: "".concat(editFaults.join('; '), ". Each edit takes: ").concat(EDIT_KEYS.join(', '), " \u2014 newValue is required (an empty string clears the cell). Nothing was staged.")
82401
82658
  });
82402
- case 186:
82659
+ case 191:
82403
82660
  // Entries without the `values` wrapper are unambiguous — treat the entry AS the values.
82404
82661
  addRows = (Array.isArray(input === null || input === void 0 ? void 0 : input.addRows) ? input.addRows : []).map(function (row) {
82405
82662
  return row && _typeof(row) === 'object' && !('values' in row) && Object.keys(row).length ? {
@@ -82415,7 +82672,7 @@ function createNavigationToolset(ctx) {
82415
82672
  tsvHeaderLine = '';
82416
82673
  tsvRowLines = [];
82417
82674
  if (!(addRowsTsv !== undefined)) {
82418
- _context21.next = 206;
82675
+ _context21.next = 211;
82419
82676
  break;
82420
82677
  }
82421
82678
  lines = addRowsTsv.split('\n').map(function (line) {
@@ -82426,13 +82683,13 @@ function createNavigationToolset(ctx) {
82426
82683
  // Exactly one empty tail is the final newline; a second one is a blank row the caller wrote and gets its fault.
82427
82684
  if (lines.length && lines[lines.length - 1] === '') lines.pop();
82428
82685
  if (!(lines.length < 2)) {
82429
- _context21.next = 196;
82686
+ _context21.next = 201;
82430
82687
  break;
82431
82688
  }
82432
82689
  return _context21.abrupt("return", {
82433
82690
  error: "addRowsTsv needs a HEADER line of column field ids and at least one row line, tab-separated (e.g. 'typeNo\\tsequenceNo' then 'ART_001\\t10'). Nothing was staged."
82434
82691
  });
82435
- case 196:
82692
+ case 201:
82436
82693
  tsvHeaderLine = lines[0];
82437
82694
  tsvRowLines = lines.slice(1);
82438
82695
  header = lines[0].split('\t').map(function (cell) {
@@ -82442,13 +82699,13 @@ function createNavigationToolset(ctx) {
82442
82699
  return cell && header.indexOf(cell) !== index;
82443
82700
  });
82444
82701
  if (!(!header.every(Boolean) || duplicate)) {
82445
- _context21.next = 202;
82702
+ _context21.next = 207;
82446
82703
  break;
82447
82704
  }
82448
82705
  return _context21.abrupt("return", {
82449
82706
  error: duplicate ? "addRowsTsv names the column '".concat(duplicate, "' twice in its header line. Nothing was staged.") : 'addRowsTsv has an empty column name in its header line. Nothing was staged.'
82450
82707
  });
82451
- case 202:
82708
+ case 207:
82452
82709
  faults = [];
82453
82710
  lines.slice(1).forEach(function (line, index) {
82454
82711
  if (!line.trim()) {
@@ -82476,19 +82733,19 @@ function createNavigationToolset(ctx) {
82476
82733
  });
82477
82734
  });
82478
82735
  if (!faults.length) {
82479
- _context21.next = 206;
82736
+ _context21.next = 211;
82480
82737
  break;
82481
82738
  }
82482
82739
  return _context21.abrupt("return", {
82483
82740
  error: "addRowsTsv: ".concat(faults.slice(0, 5).join('; ')).concat(faults.length > 5 ? "; and ".concat(faults.length - 5, " more") : '', ". Every row line needs exactly one cell per header column (an empty cell leaves that column unset). Nothing was staged.")
82484
82741
  });
82485
- case 206:
82742
+ case 211:
82486
82743
  removeRowIds = _toConsumableArray(new Set((Array.isArray(input === null || input === void 0 ? void 0 : input.removeRowIds) ? input.removeRowIds : []).map(String)));
82487
82744
  removeRows = Array.isArray(input === null || input === void 0 ? void 0 : input.removeRows) ? input.removeRows : []; // A dry run must NEVER reach the staging path below. It only knows how to check NEW rows: entered on
82488
82745
  // `dryRun && addRows.length`, a dry run carrying only edits or removals used to fall through and was staged,
82489
82746
  // approved and committed for real. A mixed call would check the rows and write the rest — refused as well.
82490
82747
  if (!(input !== null && input !== void 0 && input.dryRun && (!addRows.length || edits.length || removeRowIds.length || removeRows.length))) {
82491
- _context21.next = 210;
82748
+ _context21.next = 215;
82492
82749
  break;
82493
82750
  }
82494
82751
  return _context21.abrupt("return", {
@@ -82496,7 +82753,7 @@ function createNavigationToolset(ctx) {
82496
82753
  dryRun: true,
82497
82754
  error: 'A dry run checks NEW rows only (addRows, addRowsTsv or a payload `source`)' + (addRows.length ? ', and this call also carries edits or removals, which it would not check. ' : ', and this call carries none. ') + 'Nothing was staged. Re-send without dryRun to apply edits or removals, or send only the rows to check.'
82498
82755
  });
82499
- case 210:
82756
+ case 215:
82500
82757
  // The cap counts ROWS on screen: two edits on one row are one live grid row, so each row counts once however
82501
82758
  // many of its cells change.
82502
82759
  editedRows = new Set(edits.map(function (edit) {
@@ -82510,7 +82767,7 @@ function createNavigationToolset(ctx) {
82510
82767
  intendedRowCount = editedRows.size + addRows.length + removeRowIds.length + removedRows.size; // A dry run stages nothing, so the browser limit does not apply to it — checking a big payload in one go is
82511
82768
  // exactly how an agent finds out it has to split, and what to fix before it does.
82512
82769
  if (!(intendedRowCount > WRITE_ROW_LIMIT && !(input !== null && input !== void 0 && input.dryRun))) {
82513
- _context21.next = 215;
82770
+ _context21.next = 220;
82514
82771
  break;
82515
82772
  }
82516
82773
  return _context21.abrupt("return", {
@@ -82518,47 +82775,54 @@ function createNavigationToolset(ctx) {
82518
82775
  intendedRowCount: intendedRowCount,
82519
82776
  limit: WRITE_ROW_LIMIT
82520
82777
  });
82521
- case 215:
82778
+ case 220:
82522
82779
  if (!(!edits.length && !addRows.length && !removeRowIds.length && !removeRows.length)) {
82523
- _context21.next = 217;
82780
+ _context21.next = 222;
82524
82781
  break;
82525
82782
  }
82526
82783
  throw new Error('Provide edits: [{rowId | keyColumn+keyValue, column, newValue}], addRows: [{values}], removeRowIds and/or removeRows: [{keyColumn, keyValue}] — key addressing locates the row for you (unique value of any column), rowIds come from readGridRows.');
82527
- case 217:
82528
- _context21.next = 219;
82784
+ case 222:
82785
+ _context21.next = 224;
82529
82786
  return applyParentRowPrelude(input, args);
82530
- case 219:
82787
+ case 224:
82531
82788
  _prelude = _context21.sent;
82532
82789
  if (!_prelude) {
82533
- _context21.next = 222;
82790
+ _context21.next = 227;
82534
82791
  break;
82535
82792
  }
82536
82793
  return _context21.abrupt("return", _prelude);
82537
- case 222:
82794
+ case 227:
82538
82795
  _resolveGrid3 = resolveGrid(args.grid), _entry2 = _resolveGrid3.entry, _api2 = _resolveGrid3.api, _error2 = _resolveGrid3.error;
82539
82796
  if (!(_error2 || !_api2 || !_entry2)) {
82540
- _context21.next = 225;
82797
+ _context21.next = 230;
82541
82798
  break;
82542
82799
  }
82543
82800
  return _context21.abrupt("return", {
82544
82801
  error: _error2
82545
82802
  });
82546
- case 225:
82803
+ case 230:
82547
82804
  handle = _entry2.getHandle();
82548
82805
  if (handle) {
82549
- _context21.next = 228;
82806
+ _context21.next = 233;
82550
82807
  break;
82551
82808
  }
82552
82809
  return _context21.abrupt("return", {
82553
82810
  error: "Table '".concat(_entry2.label, "' is not ready.")
82554
82811
  });
82555
- case 228:
82812
+ case 233:
82556
82813
  if (!handle.hasPendingChanges()) {
82557
- _context21.next = 230;
82814
+ _context21.next = 235;
82558
82815
  break;
82559
82816
  }
82560
82817
  throw new Error('This table already has uncommitted (staged) changes — wait for the pending decision or ask the user to save/discard their manual edits first.');
82561
- case 230:
82818
+ case 235:
82819
+ if (!(_api2.getDisplayedRowCount() === 1 && !isRealRow(_api2.getDisplayedRowAtIndex(0)))) {
82820
+ _context21.next = 238;
82821
+ break;
82822
+ }
82823
+ _context21.next = 238;
82824
+ return waitForRows(_api2);
82825
+ case 238:
82562
82826
  // Without parentRow the write lands under the parent the subtable is bound to — the one an earlier call left
82563
82827
  // selected. Only the subtable's own declaration names it; without one the write is refused, never guessed.
82564
82828
  explicitParentRow = !!(input !== null && input !== void 0 && input.parentRow); // Mount order is the fallback for a subtable whose module declares no parent (media refs, the assortment item
@@ -82569,13 +82833,13 @@ function createNavigationToolset(ctx) {
82569
82833
  isSubtable = explicitParentRow || !!_entry2.getBoundParent || mountedAfterFirst;
82570
82834
  parentBinding = explicitParentRow ? undefined : declaredParentBinding(_entry2);
82571
82835
  if (!(parentBinding !== null && parentBinding !== void 0 && parentBinding.refusal)) {
82572
- _context21.next = 236;
82836
+ _context21.next = 244;
82573
82837
  break;
82574
82838
  }
82575
82839
  return _context21.abrupt("return", {
82576
82840
  error: parentBinding.refusal
82577
82841
  });
82578
- case 236:
82842
+ case 244:
82579
82843
  boundParentRow = parentBinding === null || parentBinding === void 0 ? void 0 : parentBinding.parent;
82580
82844
  parentBindingNote = boundParentRow ? " SUBTABLE WRITE WITHOUT parentRow: bound to the parent row this subtable is showing \u2014 '".concat(boundParentRow.grid, "' ").concat(boundParentRow.column, " = '").concat(boundParentRow.value, "' (boundParentRow). Verify that is the intended parent; pass parentRow to bind explicitly.") : mountedAfterFirst && !explicitParentRow && !_entry2.getBoundParent ? ' SUBTABLE WRITE WITHOUT parentRow: this table declares no parent binding, so the parent row it landed under cannot be named here — verify it in the table before building on the write.' : ''; // A record _id offered as rowId — partlistpos hands the _id out AS the rowId, and locateRow.firstRow._id is the
82581
82845
  // same value — is a valid address once its node is loaded. When it is not (the subtable re-rendered, a filter
@@ -82603,40 +82867,40 @@ function createNavigationToolset(ctx) {
82603
82867
  _iterator9.f();
82604
82868
  }
82605
82869
  _i3 = 0, _arr2 = _toConsumableArray(removeRowIds);
82606
- case 244:
82870
+ case 252:
82607
82871
  if (!(_i3 < _arr2.length)) {
82608
- _context21.next = 254;
82872
+ _context21.next = 262;
82609
82873
  break;
82610
82874
  }
82611
82875
  rowId = _arr2[_i3];
82612
82876
  if (isUnloadedRecordId(rowId)) {
82613
- _context21.next = 248;
82877
+ _context21.next = 256;
82614
82878
  break;
82615
82879
  }
82616
- return _context21.abrupt("continue", 251);
82617
- case 248:
82880
+ return _context21.abrupt("continue", 259);
82881
+ case 256:
82618
82882
  removeRowIds.splice(removeRowIds.indexOf(rowId), 1);
82619
82883
  removeRows.push({
82620
82884
  keyColumn: '_id',
82621
82885
  keyValue: rowId
82622
82886
  });
82623
82887
  reroutedRecordIds += 1;
82624
- case 251:
82888
+ case 259:
82625
82889
  _i3++;
82626
- _context21.next = 244;
82890
+ _context21.next = 252;
82627
82891
  break;
82628
- case 254:
82892
+ case 262:
82629
82893
  // Hard stop for CREATES when the serie scope is unresolved — the row would be filed wherever the endpoint defaults to.
82630
82894
  serieScope = serieScopeOf(_entry2, handle);
82631
82895
  if (!(addRows.length && serieScope && !serieScope.serieId)) {
82632
- _context21.next = 257;
82896
+ _context21.next = 265;
82633
82897
  break;
82634
82898
  }
82635
82899
  return _context21.abrupt("return", {
82636
82900
  error: "'".concat(_entry2.label, "' belongs to ONE serie (its endpoint is /series/<id>/\u2026) and NO serie is selected, so a new row would be filed wherever the view defaults to \u2014 usually the FIRST serie (serie 0, the components serie). Nothing was staged."),
82637
82901
  fix: 'selectSerie(<serieNo>) first — listSeries shows the numbers and the current selection — then re-send this call unchanged.'
82638
82902
  });
82639
- case 257:
82903
+ case 265:
82640
82904
  fmt = function fmt(v) {
82641
82905
  return v == null ? undefined : _typeof(v) === 'object' ? JSON.stringify(v).slice(0, 80) : v;
82642
82906
  }; // The AG col def loses the DIVA custom props (editable/required/customParams) — check the DIVA def too.
@@ -82979,8 +83243,14 @@ function createNavigationToolset(ctx) {
82979
83243
  _context3.t0 = _context3["catch"](0);
82980
83244
  return _context3.abrupt("return", _context3.t0 instanceof Error ? _context3.t0.message : String(_context3.t0));
82981
83245
  case 10:
83246
+ if (isRealRow(_api2.getRowNode(rowId))) {
83247
+ _context3.next = 12;
83248
+ break;
83249
+ }
83250
+ return _context3.abrupt("return", "Row '".concat(rowId, "' is not in the table any more (it reloaded or was still loading) \u2014 nothing was staged for this cell; send it again."));
83251
+ case 12:
82982
83252
  return _context3.abrupt("return", "".concat(parserRefusal(column, text), ", or the row is marked for deletion or over the row limit. Nothing was staged for this cell."));
82983
- case 11:
83253
+ case 13:
82984
83254
  case "end":
82985
83255
  return _context3.stop();
82986
83256
  }
@@ -83443,7 +83713,7 @@ function createNavigationToolset(ctx) {
83443
83713
  // for rows that came from a payload: the agent never read them, so this is its only way to check them — and
83444
83714
  // the answer stays small, counts plus the failing rows, however many rows there are.
83445
83715
  if (!(input !== null && input !== void 0 && input.dryRun && addRows.length)) {
83446
- _context21.next = 296;
83716
+ _context21.next = 304;
83447
83717
  break;
83448
83718
  }
83449
83719
  requiredFields = _divaDefs.filter(function (definition) {
@@ -83584,7 +83854,7 @@ function createNavigationToolset(ctx) {
83584
83854
  return "'".concat(column, "'");
83585
83855
  }).join(', '), " (editabilityUnverified) \u2014 its rule needs grid context a dry run does not have, so the real call may still refuse it. ") : '. ') + "Row numbers count the addRows list (a payload's rows follow the rows listed in the call), then the addRowsTsv lines. " + 'Re-send without dryRun to stage and commit.' + (addRows.length > WRITE_ROW_LIMIT ? " NOTE: ".concat(addRows.length, " rows exceed the ").concat(WRITE_ROW_LIMIT, "-row limit of ONE write \u2014 split them across calls.") : '')
83586
83856
  }));
83587
- case 296:
83857
+ case 304:
83588
83858
  /** Mirrors locateRowCore's own loaded-rows check (read-only) — never mutates the filter itself. */
83589
83859
  needsServerLookup = function needsServerLookup(keyColumn, keyValue) {
83590
83860
  var colDef = columnDefFor(keyColumn);
@@ -83675,51 +83945,51 @@ function createNavigationToolset(ctx) {
83675
83945
  }
83676
83946
  // The chunked pass judges uniqueness with its own lookups — this pre-check only serves the direct path.
83677
83947
  if (!(!lookupKeys.size && hasUnloadedDisplayedRows(_api2))) {
83678
- _context21.next = 339;
83948
+ _context21.next = 347;
83679
83949
  break;
83680
83950
  }
83681
83951
  keysByColumn = new Map();
83682
83952
  _i6 = 0, _arr3 = [].concat(_toConsumableArray(edits.filter(function (edit) {
83683
83953
  return (edit === null || edit === void 0 ? void 0 : edit.rowId) == null;
83684
83954
  })), _toConsumableArray(removeRows));
83685
- case 307:
83955
+ case 315:
83686
83956
  if (!(_i6 < _arr3.length)) {
83687
- _context21.next = 318;
83957
+ _context21.next = 326;
83688
83958
  break;
83689
83959
  }
83690
83960
  address = _arr3[_i6];
83691
83961
  if (!((address === null || address === void 0 ? void 0 : address.keyColumn) == null || (address === null || address === void 0 ? void 0 : address.keyValue) == null)) {
83692
- _context21.next = 311;
83962
+ _context21.next = 319;
83693
83963
  break;
83694
83964
  }
83695
- return _context21.abrupt("continue", 315);
83696
- case 311:
83965
+ return _context21.abrupt("continue", 323);
83966
+ case 319:
83697
83967
  _keyColumn2 = String(address.keyColumn);
83698
83968
  if (!(_keyColumn2 === '_id' || !columnDefFor(_keyColumn2))) {
83699
- _context21.next = 314;
83969
+ _context21.next = 322;
83700
83970
  break;
83701
83971
  }
83702
- return _context21.abrupt("continue", 315);
83703
- case 314:
83972
+ return _context21.abrupt("continue", 323);
83973
+ case 322:
83704
83974
  keysByColumn.set(_keyColumn2, ((_keysByColumn$get = keysByColumn.get(_keyColumn2)) !== null && _keysByColumn$get !== void 0 ? _keysByColumn$get : new Set()).add(String(address.keyValue)));
83705
- case 315:
83975
+ case 323:
83706
83976
  _i6++;
83707
- _context21.next = 307;
83977
+ _context21.next = 315;
83708
83978
  break;
83709
- case 318:
83979
+ case 326:
83710
83980
  _iterator15 = _createForOfIteratorHelper$i(keysByColumn);
83711
- _context21.prev = 319;
83981
+ _context21.prev = 327;
83712
83982
  _iterator15.s();
83713
- case 321:
83983
+ case 329:
83714
83984
  if ((_step15 = _iterator15.n()).done) {
83715
- _context21.next = 331;
83985
+ _context21.next = 339;
83716
83986
  break;
83717
83987
  }
83718
83988
  _step15$value = _slicedToArray(_step15.value, 2), _keyColumn3 = _step15$value[0], keyValues = _step15$value[1];
83719
83989
  _deadline = Date.now() + 14000 * Math.ceil(keyValues.size / BULK_LOOKUP_CHUNK);
83720
- _context21.next = 326;
83990
+ _context21.next = 334;
83721
83991
  return confirmUniqueKeys(_api2, _keyColumn3, _toConsumableArray(keyValues), _deadline);
83722
- case 326:
83992
+ case 334:
83723
83993
  refusals = _context21.sent;
83724
83994
  _iterator16 = _createForOfIteratorHelper$i(refusals);
83725
83995
  try {
@@ -83732,21 +84002,21 @@ function createNavigationToolset(ctx) {
83732
84002
  } finally {
83733
84003
  _iterator16.f();
83734
84004
  }
83735
- case 329:
83736
- _context21.next = 321;
84005
+ case 337:
84006
+ _context21.next = 329;
83737
84007
  break;
83738
- case 331:
83739
- _context21.next = 336;
84008
+ case 339:
84009
+ _context21.next = 344;
83740
84010
  break;
83741
- case 333:
83742
- _context21.prev = 333;
83743
- _context21.t5 = _context21["catch"](319);
84011
+ case 341:
84012
+ _context21.prev = 341;
84013
+ _context21.t5 = _context21["catch"](327);
83744
84014
  _iterator15.e(_context21.t5);
83745
- case 336:
83746
- _context21.prev = 336;
84015
+ case 344:
84016
+ _context21.prev = 344;
83747
84017
  _iterator15.f();
83748
- return _context21.finish(336);
83749
- case 339:
84018
+ return _context21.finish(344);
84019
+ case 347:
83750
84020
  mergedOutcome = {
83751
84021
  committed: [],
83752
84022
  failed: [],
@@ -83768,33 +84038,46 @@ function createNavigationToolset(ctx) {
83768
84038
  /** The failed chunk threw inside its commit — whether any of its rows reached the server is unknown. */
83769
84039
  chunkCommitThrew = false;
83770
84040
  if (!(lookupKeys.size > 0)) {
83771
- _context21.next = 424;
84041
+ _context21.next = 434;
83772
84042
  break;
83773
84043
  }
83774
84044
  intendedCount = edits.length + addRows.length + removeRowIds.length + removeRows.length;
83775
84045
  if (!ctx.autoApprove) awaitingApproval();
83776
84046
  _context21.t6 = ctx.autoApprove;
83777
84047
  if (_context21.t6) {
83778
- _context21.next = 352;
84048
+ _context21.next = 360;
83779
84049
  break;
83780
84050
  }
83781
- _context21.next = 351;
84051
+ _context21.next = 359;
83782
84052
  return _entry2.requestAgentApproval(intendedCount, "".concat(intendedCount, " change(s) \u2014 ").concat(lookupKeys.size, " row(s) must be located first"), signal);
83783
- case 351:
84053
+ case 359:
83784
84054
  _context21.t6 = _context21.sent;
83785
- case 352:
84055
+ case 360:
83786
84056
  _approved = _context21.t6;
83787
84057
  if (_approved) {
83788
- _context21.next = 356;
84058
+ _context21.next = 366;
83789
84059
  break;
83790
84060
  }
83791
84061
  restoreUserFilter();
84062
+ // As at the later bar: an aborted call (the client stopped waiting) withdraws it — no decision of the user.
84063
+ if (!((signal === null || signal === void 0 ? void 0 : signal.aborted) === true)) {
84064
+ _context21.next = 365;
84065
+ break;
84066
+ }
84067
+ return _context21.abrupt("return", {
84068
+ applied: false,
84069
+ outcome: 'WITHDRAWN',
84070
+ stagedCount: 0,
84071
+ note: 'The approval bar was WITHDRAWN because the call was cancelled (the client stopped waiting) — the user did NOT decide and nothing was staged or saved. Send the same changes again and tell the user the bar is waiting for them.'
84072
+ });
84073
+ case 365:
83792
84074
  return _context21.abrupt("return", {
83793
84075
  applied: false,
84076
+ outcome: 'DISCARDED',
83794
84077
  stagedCount: 0,
83795
84078
  note: 'The user DECLINED the change — nothing was staged or saved. Do not retry; ask what to do instead.'
83796
84079
  });
83797
- case 356:
84080
+ case 366:
83798
84081
  preApproved = true;
83799
84082
  passDeadline = callStartedAt + KEY_PASS_BUDGET_MS;
83800
84083
  serverChunks = 0;
@@ -84046,16 +84329,16 @@ function createNavigationToolset(ctx) {
84046
84329
  }();
84047
84330
  };
84048
84331
  _iterator25 = _createForOfIteratorHelper$i(_keysByColumn);
84049
- _context21.prev = 369;
84332
+ _context21.prev = 379;
84050
84333
  _iterator25.s();
84051
- case 371:
84334
+ case 381:
84052
84335
  if ((_step25 = _iterator25.n()).done) {
84053
- _context21.next = 410;
84336
+ _context21.next = 420;
84054
84337
  break;
84055
84338
  }
84056
84339
  _step25$value = _slicedToArray(_step25.value, 2), _keyColumn5 = _step25$value[0], _keyValues = _step25$value[1];
84057
84340
  if (!(signal !== null && signal !== void 0 && signal.aborted || !roomForAnotherChunk())) {
84058
- _context21.next = 377;
84341
+ _context21.next = 387;
84059
84342
  break;
84060
84343
  }
84061
84344
  _iterator26 = _createForOfIteratorHelper$i(_keyValues);
@@ -84069,25 +84352,25 @@ function createNavigationToolset(ctx) {
84069
84352
  } finally {
84070
84353
  _iterator26.f();
84071
84354
  }
84072
- return _context21.abrupt("continue", 408);
84073
- case 377:
84355
+ return _context21.abrupt("continue", 418);
84356
+ case 387:
84074
84357
  _bulk2 = void 0;
84075
84358
  _located2 = undefined;
84076
- _context21.prev = 379;
84359
+ _context21.prev = 389;
84077
84360
  // The first chunk runs even when the approval used the budget up: a call must never answer after waiting alone.
84078
84361
  lookupDeadline = Math.max(passDeadline, Date.now() + CHUNK_RESERVE_MS);
84079
- _context21.next = 383;
84362
+ _context21.next = 393;
84080
84363
  return bulkLocateRows(_api2, _keyColumn5, _keyValues, lookupDeadline, {
84081
84364
  chunkSize: blockSize,
84082
84365
  onChunk: stageChunk(_keyColumn5)
84083
84366
  });
84084
- case 383:
84367
+ case 393:
84085
84368
  _bulk2 = _context21.sent;
84086
- _context21.next = 393;
84369
+ _context21.next = 403;
84087
84370
  break;
84088
- case 386:
84089
- _context21.prev = 386;
84090
- _context21.t7 = _context21["catch"](379);
84371
+ case 396:
84372
+ _context21.prev = 396;
84373
+ _context21.t7 = _context21["catch"](389);
84091
84374
  // A column the table cannot filter on fails before its first lookup; rows staged before that are committed.
84092
84375
  reason = _context21.t7 instanceof Error ? _context21.t7.message : String(_context21.t7);
84093
84376
  if (_located2) settleVerdicts(_keyColumn5, _located2);
@@ -84106,28 +84389,28 @@ function createNavigationToolset(ctx) {
84106
84389
  } finally {
84107
84390
  _iterator27.f();
84108
84391
  }
84109
- return _context21.abrupt("continue", 408);
84110
- case 393:
84392
+ return _context21.abrupt("continue", 418);
84393
+ case 403:
84111
84394
  settleVerdicts(_keyColumn5, _bulk2);
84112
84395
  if (!chunkError) {
84113
- _context21.next = 406;
84396
+ _context21.next = 416;
84114
84397
  break;
84115
84398
  }
84116
84399
  if (!handle.hasPendingChanges()) {
84117
- _context21.next = 398;
84400
+ _context21.next = 408;
84118
84401
  break;
84119
84402
  }
84120
- _context21.next = 398;
84403
+ _context21.next = 408;
84121
84404
  return handle.rollback();
84122
- case 398:
84405
+ case 408:
84123
84406
  if (mergedOutcome.committed.length) {
84124
- _context21.next = 402;
84407
+ _context21.next = 412;
84125
84408
  break;
84126
84409
  }
84127
84410
  if (keyFilterChanged()) keyFilterApplied = true;
84128
84411
  restoreUserFilter();
84129
84412
  throw chunkError;
84130
- case 402:
84413
+ case 412:
84131
84414
  chunkFailure = chunkError instanceof Error ? chunkError.message : String(chunkError);
84132
84415
  _iterator28 = _createForOfIteratorHelper$i(lookupKeys.keys());
84133
84416
  try {
@@ -84140,8 +84423,8 @@ function createNavigationToolset(ctx) {
84140
84423
  } finally {
84141
84424
  _iterator28.f();
84142
84425
  }
84143
- return _context21.abrupt("break", 410);
84144
- case 406:
84426
+ return _context21.abrupt("break", 420);
84427
+ case 416:
84145
84428
  _iterator29 = _createForOfIteratorHelper$i(_bulk2.notReached);
84146
84429
  try {
84147
84430
  for (_iterator29.s(); !(_step29 = _iterator29.n()).done;) {
@@ -84153,21 +84436,21 @@ function createNavigationToolset(ctx) {
84153
84436
  } finally {
84154
84437
  _iterator29.f();
84155
84438
  }
84156
- case 408:
84157
- _context21.next = 371;
84439
+ case 418:
84440
+ _context21.next = 381;
84158
84441
  break;
84159
- case 410:
84160
- _context21.next = 415;
84442
+ case 420:
84443
+ _context21.next = 425;
84161
84444
  break;
84162
- case 412:
84163
- _context21.prev = 412;
84164
- _context21.t8 = _context21["catch"](369);
84445
+ case 422:
84446
+ _context21.prev = 422;
84447
+ _context21.t8 = _context21["catch"](379);
84165
84448
  _iterator25.e(_context21.t8);
84166
- case 415:
84167
- _context21.prev = 415;
84449
+ case 425:
84450
+ _context21.prev = 425;
84168
84451
  _iterator25.f();
84169
- return _context21.finish(415);
84170
- case 418:
84452
+ return _context21.finish(425);
84453
+ case 428:
84171
84454
  // Bring the loaded window back to what the caller had before more edits (possibly rowId-addressed,
84172
84455
  // always assumed already-loaded) rely on it — restoreUserFilter only mutates when a lookup above
84173
84456
  // actually changed something, and the grid needs a moment to settle after a filter change.
@@ -84175,12 +84458,12 @@ function createNavigationToolset(ctx) {
84175
84458
  filterWasChanged = keyFilterApplied;
84176
84459
  restoreUserFilter();
84177
84460
  if (!filterWasChanged) {
84178
- _context21.next = 424;
84461
+ _context21.next = 434;
84179
84462
  break;
84180
84463
  }
84181
- _context21.next = 424;
84464
+ _context21.next = 434;
84182
84465
  return waitForRows(_api2);
84183
- case 424:
84466
+ case 434:
84184
84467
  remainingEdits = edits.filter(function (edit) {
84185
84468
  return (edit === null || edit === void 0 ? void 0 : edit.rowId) == null && (edit === null || edit === void 0 ? void 0 : edit.keyColumn) != null && (edit === null || edit === void 0 ? void 0 : edit.keyValue) != null && notProcessedKeys.has(lookupKeyOf(String(edit.keyColumn), String(edit.keyValue)));
84186
84469
  });
@@ -84189,73 +84472,73 @@ function createNavigationToolset(ctx) {
84189
84472
  }); // Key-addressed removals resolve to rowIds before the edit loop (conflicts are checked against the final id list).
84190
84473
  // Rows already resolved+staged+committed by the sequential lookup pass above are skipped here.
84191
84474
  _iterator30 = _createForOfIteratorHelper$i(removeRows);
84192
- _context21.prev = 427;
84475
+ _context21.prev = 437;
84193
84476
  _iterator30.s();
84194
- case 429:
84477
+ case 439:
84195
84478
  if ((_step30 = _iterator30.n()).done) {
84196
- _context21.next = 443;
84479
+ _context21.next = 453;
84197
84480
  break;
84198
84481
  }
84199
84482
  _removal2 = _step30.value;
84200
84483
  if (!((_removal2 === null || _removal2 === void 0 ? void 0 : _removal2.keyColumn) != null && (_removal2 === null || _removal2 === void 0 ? void 0 : _removal2.keyValue) != null && lookupKeys.has(lookupKeyOf(String(_removal2.keyColumn), String(_removal2.keyValue))))) {
84201
- _context21.next = 433;
84484
+ _context21.next = 443;
84202
84485
  break;
84203
84486
  }
84204
- return _context21.abrupt("continue", 441);
84205
- case 433:
84206
- _context21.next = 435;
84487
+ return _context21.abrupt("continue", 451);
84488
+ case 443:
84489
+ _context21.next = 445;
84207
84490
  return resolveTarget(_removal2);
84208
- case 435:
84491
+ case 445:
84209
84492
  _target = _context21.sent;
84210
84493
  if (!(_target.error || !_target.node)) {
84211
- _context21.next = 439;
84494
+ _context21.next = 449;
84212
84495
  break;
84213
84496
  }
84214
84497
  failed.push({
84215
84498
  rowId: _target.label,
84216
84499
  error: (_target$error = _target.error) !== null && _target$error !== void 0 ? _target$error : 'Row not found.'
84217
84500
  });
84218
- return _context21.abrupt("continue", 441);
84219
- case 439:
84501
+ return _context21.abrupt("continue", 451);
84502
+ case 449:
84220
84503
  id = String(_target.node.id);
84221
84504
  if (!removeRowIds.includes(id)) removeRowIds.push(id);
84222
- case 441:
84223
- _context21.next = 429;
84505
+ case 451:
84506
+ _context21.next = 439;
84224
84507
  break;
84225
- case 443:
84226
- _context21.next = 448;
84508
+ case 453:
84509
+ _context21.next = 458;
84227
84510
  break;
84228
- case 445:
84229
- _context21.prev = 445;
84230
- _context21.t9 = _context21["catch"](427);
84511
+ case 455:
84512
+ _context21.prev = 455;
84513
+ _context21.t9 = _context21["catch"](437);
84231
84514
  _iterator30.e(_context21.t9);
84232
- case 448:
84233
- _context21.prev = 448;
84515
+ case 458:
84516
+ _context21.prev = 458;
84234
84517
  _iterator30.f();
84235
- return _context21.finish(448);
84236
- case 451:
84518
+ return _context21.finish(458);
84519
+ case 461:
84237
84520
  _iterator31 = _createForOfIteratorHelper$i(edits);
84238
- _context21.prev = 452;
84521
+ _context21.prev = 462;
84239
84522
  _iterator31.s();
84240
- case 454:
84523
+ case 464:
84241
84524
  if ((_step31 = _iterator31.n()).done) {
84242
- _context21.next = 474;
84525
+ _context21.next = 484;
84243
84526
  break;
84244
84527
  }
84245
84528
  _edit4 = _step31.value;
84246
84529
  if (!((_edit4 === null || _edit4 === void 0 ? void 0 : _edit4.rowId) == null && (_edit4 === null || _edit4 === void 0 ? void 0 : _edit4.keyColumn) != null && (_edit4 === null || _edit4 === void 0 ? void 0 : _edit4.keyValue) != null && lookupKeys.has(lookupKeyOf(String(_edit4.keyColumn), String(_edit4.keyValue))))) {
84247
- _context21.next = 458;
84530
+ _context21.next = 468;
84248
84531
  break;
84249
84532
  }
84250
- return _context21.abrupt("continue", 472);
84251
- case 458:
84533
+ return _context21.abrupt("continue", 482);
84534
+ case 468:
84252
84535
  _column2 = String((_edit4$column = _edit4 === null || _edit4 === void 0 ? void 0 : _edit4.column) !== null && _edit4$column !== void 0 ? _edit4$column : '');
84253
- _context21.next = 461;
84536
+ _context21.next = 471;
84254
84537
  return resolveTarget(_edit4);
84255
- case 461:
84538
+ case 471:
84256
84539
  _target2 = _context21.sent;
84257
84540
  if (!(_target2.error || !_target2.node)) {
84258
- _context21.next = 465;
84541
+ _context21.next = 475;
84259
84542
  break;
84260
84543
  }
84261
84544
  failed.push({
@@ -84263,12 +84546,12 @@ function createNavigationToolset(ctx) {
84263
84546
  column: _column2,
84264
84547
  error: (_target2$error = _target2.error) !== null && _target2$error !== void 0 ? _target2$error : 'Row not found.'
84265
84548
  });
84266
- return _context21.abrupt("continue", 472);
84267
- case 465:
84549
+ return _context21.abrupt("continue", 482);
84550
+ case 475:
84268
84551
  _node2 = _target2.node;
84269
84552
  _rowId2 = String(_node2.id);
84270
84553
  if (!removeRowIds.includes(_rowId2)) {
84271
- _context21.next = 470;
84554
+ _context21.next = 480;
84272
84555
  break;
84273
84556
  }
84274
84557
  failed.push({
@@ -84276,25 +84559,25 @@ function createNavigationToolset(ctx) {
84276
84559
  column: _column2,
84277
84560
  error: 'This row is also being removed — edit OR remove a row, not both.'
84278
84561
  });
84279
- return _context21.abrupt("continue", 472);
84280
- case 470:
84281
- _context21.next = 472;
84562
+ return _context21.abrupt("continue", 482);
84563
+ case 480:
84564
+ _context21.next = 482;
84282
84565
  return applyEditToNode(_node2, _rowId2, _column2, _edit4 === null || _edit4 === void 0 ? void 0 : _edit4.newValue);
84283
- case 472:
84284
- _context21.next = 454;
84566
+ case 482:
84567
+ _context21.next = 464;
84285
84568
  break;
84286
- case 474:
84287
- _context21.next = 479;
84569
+ case 484:
84570
+ _context21.next = 489;
84288
84571
  break;
84289
- case 476:
84290
- _context21.prev = 476;
84291
- _context21.t10 = _context21["catch"](452);
84572
+ case 486:
84573
+ _context21.prev = 486;
84574
+ _context21.t10 = _context21["catch"](462);
84292
84575
  _iterator31.e(_context21.t10);
84293
- case 479:
84294
- _context21.prev = 479;
84576
+ case 489:
84577
+ _context21.prev = 489;
84295
84578
  _iterator31.f();
84296
- return _context21.finish(479);
84297
- case 482:
84579
+ return _context21.finish(489);
84580
+ case 492:
84298
84581
  targets = removeRowIds.filter(function (rowId) {
84299
84582
  if (isRealRow(_api2.getRowNode(rowId))) return true;
84300
84583
  failed.push({
@@ -84315,14 +84598,14 @@ function createNavigationToolset(ctx) {
84315
84598
  _iterator32.f();
84316
84599
  }
84317
84600
  if (!targets.length) {
84318
- _context21.next = 489;
84601
+ _context21.next = 499;
84319
84602
  break;
84320
84603
  }
84321
- _context21.next = 488;
84604
+ _context21.next = 498;
84322
84605
  return handle.stageRemoveRows(targets);
84323
- case 488:
84606
+ case 498:
84324
84607
  removed.push.apply(removed, _toConsumableArray(targets));
84325
- case 489:
84608
+ case 499:
84326
84609
  /** `sent`: what this call wrote per column it was given (plain value or lookup key) — the receipt reads these columns back. */
84327
84610
  addedRows = [];
84328
84611
  /** Columns the AGENT provided per added row — lookup writes drag companion fields into `values`. */
@@ -84802,30 +85085,30 @@ function createNavigationToolset(ctx) {
84802
85085
  }, _loop4, null, [[80, 100, 103, 106]]);
84803
85086
  });
84804
85087
  _i7 = 0;
84805
- case 496:
85088
+ case 506:
84806
85089
  if (!(_i7 < addRows.length)) {
84807
- _context21.next = 506;
85090
+ _context21.next = 516;
84808
85091
  break;
84809
85092
  }
84810
- return _context21.delegateYield(_loop4(), "t11", 498);
84811
- case 498:
85093
+ return _context21.delegateYield(_loop4(), "t11", 508);
85094
+ case 508:
84812
85095
  _ret3 = _context21.t11;
84813
85096
  if (!(_ret3 === 0)) {
84814
- _context21.next = 501;
85097
+ _context21.next = 511;
84815
85098
  break;
84816
85099
  }
84817
- return _context21.abrupt("break", 506);
84818
- case 501:
85100
+ return _context21.abrupt("break", 516);
85101
+ case 511:
84819
85102
  if (!(_ret3 === 1)) {
84820
- _context21.next = 503;
85103
+ _context21.next = 513;
84821
85104
  break;
84822
85105
  }
84823
- return _context21.abrupt("continue", 503);
84824
- case 503:
85106
+ return _context21.abrupt("continue", 513);
85107
+ case 513:
84825
85108
  _i7++;
84826
- _context21.next = 496;
85109
+ _context21.next = 506;
84827
85110
  break;
84828
- case 506:
85111
+ case 516:
84829
85112
  unsentListedRows = addRows.slice(Math.min(addRowsStopAt, listedAddRowCount), listedAddRowCount);
84830
85113
  unsentTsvLines = tsvRowLines.slice(Math.max(0, addRowsStopAt - listedAddRowCount));
84831
85114
  keyRemainingCount = remainingEdits.length + remainingRemovals.length;
@@ -84859,16 +85142,16 @@ function createNavigationToolset(ctx) {
84859
85142
  return " ADD SCHEMA of '".concat(_entry2.label, "' \u2014 required: ").concat(req.join(', ') || 'none').concat(defaulted.length ? "; defaulted (OMIT): ".concat(defaulted.join(', ')) : '', ". Enum/lookup columns take only their listed values (listGrids/readColumnOptions).");
84860
85143
  };
84861
85144
  if (!(!staged.length && !addedRows.length && !removed.length)) {
84862
- _context21.next = 519;
85145
+ _context21.next = 529;
84863
85146
  break;
84864
85147
  }
84865
85148
  if (!handle.hasPendingChanges()) {
84866
- _context21.next = 517;
85149
+ _context21.next = 527;
84867
85150
  break;
84868
85151
  }
84869
- _context21.next = 517;
85152
+ _context21.next = 527;
84870
85153
  return handle.rollback();
84871
- case 517:
85154
+ case 527:
84872
85155
  restoreUserFilter();
84873
85156
  return _context21.abrupt("return", _objectSpread$A(_objectSpread$A({
84874
85157
  applied: false,
@@ -84878,7 +85161,7 @@ function createNavigationToolset(ctx) {
84878
85161
  }, remainingPart), {}, {
84879
85162
  note: unchanged.length ? 'NOTHING was staged: every proposed value equals the current cell value (the change may already have been applied earlier). Tell the user the data already matches — do NOT claim you changed anything.' : "Nothing could be staged \u2014 nothing to approve. Fix the failures (fresh readGridRows) and try again.".concat(failed.length ? addSchemaHint() : '')
84880
85163
  }));
84881
- case 519:
85164
+ case 529:
84882
85165
  // The table would silently skip invalid staged rows on save — surface that as a failure instead of a fake success.
84883
85166
  validationErrors = []; // Rows the sequential lookup pass already sent carry the SERVER's verdict (a rejection leaves the same
84884
85167
  // error markers) — that is reported as a server error below, not as a validation failure of the rest.
@@ -84890,20 +85173,20 @@ function createNavigationToolset(ctx) {
84890
85173
  })), _toConsumableArray(addedRows.map(function (a) {
84891
85174
  return a.rowId;
84892
85175
  })))));
84893
- _context21.prev = 522;
85176
+ _context21.prev = 532;
84894
85177
  _iterator33.s();
84895
- case 524:
85178
+ case 534:
84896
85179
  if ((_step33 = _iterator33.n()).done) {
84897
- _context21.next = 532;
85180
+ _context21.next = 542;
84898
85181
  break;
84899
85182
  }
84900
85183
  _rowId3 = _step33.value;
84901
85184
  if (!alreadySent.has(_rowId3)) {
84902
- _context21.next = 528;
85185
+ _context21.next = 538;
84903
85186
  break;
84904
85187
  }
84905
- return _context21.abrupt("continue", 530);
84906
- case 528:
85188
+ return _context21.abrupt("continue", 540);
85189
+ case 538:
84907
85190
  rowErrors = (_api2$getRowNode12 = _api2.getRowNode(_rowId3)) === null || _api2$getRowNode12 === void 0 || (_api2$getRowNode12 = _api2$getRowNode12.data) === null || _api2$getRowNode12 === void 0 || (_api2$getRowNode12 = _api2$getRowNode12.__diva_context) === null || _api2$getRowNode12 === void 0 ? void 0 : _api2$getRowNode12.errors;
84908
85191
  if (Array.isArray(rowErrors) && rowErrors.length) {
84909
85192
  validationErrors.push({
@@ -84913,28 +85196,28 @@ function createNavigationToolset(ctx) {
84913
85196
  })
84914
85197
  });
84915
85198
  }
84916
- case 530:
84917
- _context21.next = 524;
85199
+ case 540:
85200
+ _context21.next = 534;
84918
85201
  break;
84919
- case 532:
84920
- _context21.next = 537;
85202
+ case 542:
85203
+ _context21.next = 547;
84921
85204
  break;
84922
- case 534:
84923
- _context21.prev = 534;
84924
- _context21.t12 = _context21["catch"](522);
85205
+ case 544:
85206
+ _context21.prev = 544;
85207
+ _context21.t12 = _context21["catch"](532);
84925
85208
  _iterator33.e(_context21.t12);
84926
- case 537:
84927
- _context21.prev = 537;
85209
+ case 547:
85210
+ _context21.prev = 547;
84928
85211
  _iterator33.f();
84929
- return _context21.finish(537);
84930
- case 540:
85212
+ return _context21.finish(547);
85213
+ case 550:
84931
85214
  if (!validationErrors.length) {
84932
- _context21.next = 545;
85215
+ _context21.next = 555;
84933
85216
  break;
84934
85217
  }
84935
- _context21.next = 543;
85218
+ _context21.next = 553;
84936
85219
  return handle.rollback();
84937
- case 543:
85220
+ case 553:
84938
85221
  restoreUserFilter();
84939
85222
  // Rows resolved by the sequential lookup pass above commit individually, BEFORE this check runs —
84940
85223
  // a validation failure in the rest of the batch cannot roll those back, so "everything was reverted"
@@ -84950,7 +85233,7 @@ function createNavigationToolset(ctx) {
84950
85233
  }, remainingPart), {}, {
84951
85234
  note: mergedOutcome.committed.length ? "".concat(mergedOutcome.committed.length, " row(s) addressed by keyColumn/keyValue were already COMMITTED individually before this validation failure (each such row is located, staged and saved on its own, to avoid losing it to a later filter change) \u2014 do NOT re-send those, see committedRowIds. The REST of the batch failed validation and was reverted: fix the listed problems and try ONE new stageTableEdits call for just those.").concat(addSchemaHint()) : "NOTHING was staged for approval: some rows fail the table's validation (everything was reverted). Fix the listed problems \u2014 e.g. fill the required columns \u2014 and try ONE new stageTableEdits call.".concat(addSchemaHint())
84952
85235
  }));
84953
- case 545:
85236
+ case 555:
84954
85237
  // Bring the first staged row into view; staged cells/rows are highlighted.
84955
85238
  focusNode = _api2.getRowNode((_ref31 = (_ref32 = (_staged$0$rowId = (_staged$ = staged[0]) === null || _staged$ === void 0 ? void 0 : _staged$.rowId) !== null && _staged$0$rowId !== void 0 ? _staged$0$rowId : removed[0]) !== null && _ref32 !== void 0 ? _ref32 : (_addedRows$ = addedRows[0]) === null || _addedRows$ === void 0 ? void 0 : _addedRows$.rowId) !== null && _ref31 !== void 0 ? _ref31 : '');
84956
85239
  if ((focusNode === null || focusNode === void 0 ? void 0 : focusNode.rowIndex) != null) _api2.ensureIndexVisible(focusNode.rowIndex, 'middle');
@@ -84984,36 +85267,40 @@ function createNavigationToolset(ctx) {
84984
85267
  cleaningLabel = (input === null || input === void 0 ? void 0 : input.cleanReferences) === true && removed.length ? "".concat(totalStaged, " change(s) - deletes ").concat(removed.length, " row(s) and removes their references (cannot be undone)") : undefined;
84985
85268
  _context21.t13 = ctx.autoApprove || preApproved;
84986
85269
  if (_context21.t13) {
84987
- _context21.next = 556;
85270
+ _context21.next = 566;
84988
85271
  break;
84989
85272
  }
84990
- _context21.next = 555;
85273
+ _context21.next = 565;
84991
85274
  return _entry2.requestAgentApproval(totalStaged, cleaningLabel, signal);
84992
- case 555:
85275
+ case 565:
84993
85276
  _context21.t13 = _context21.sent;
84994
- case 556:
85277
+ case 566:
84995
85278
  approved = _context21.t13;
84996
85279
  if (approved) {
84997
- _context21.next = 566;
85280
+ _context21.next = 578;
84998
85281
  break;
84999
85282
  }
85000
- _context21.next = 560;
85283
+ _context21.next = 570;
85001
85284
  return handle.rollback();
85002
- case 560:
85285
+ case 570:
85003
85286
  survived = survivingOperations();
85004
85287
  survivedCount = survived.changes.length + survived.addedRowIds.length + survived.removedRowIds.length;
85005
85288
  restoreUserFilter();
85289
+ // An aborted call (the client stopped waiting) withdraws the bar — that is no decision of the user.
85290
+ withdrawn = (signal === null || signal === void 0 ? void 0 : signal.aborted) === true;
85291
+ decision = withdrawn ? 'The approval bar was WITHDRAWN because the call was cancelled (the client stopped waiting) — the user did NOT decide' : 'The user DISCARDED the staged changes';
85006
85292
  if (survivedCount) {
85007
- _context21.next = 565;
85293
+ _context21.next = 577;
85008
85294
  break;
85009
85295
  }
85010
85296
  return _context21.abrupt("return", {
85011
85297
  applied: false,
85298
+ outcome: withdrawn ? 'WITHDRAWN' : 'DISCARDED',
85012
85299
  stagedCount: totalStaged,
85013
85300
  failed: failed.length ? summarizeFailures(failed) : undefined,
85014
- note: 'The user DISCARDED the staged changes — nothing was saved. Do NOT re-stage the same values; ask what to adjust instead.'
85301
+ note: withdrawn ? "".concat(decision, " and nothing was saved. Stage the same changes again and tell the user the bar is waiting for them.") : "".concat(decision, " \u2014 nothing was saved. Do NOT re-stage the same values; ask what to adjust instead.")
85015
85302
  });
85016
- case 565:
85303
+ case 577:
85017
85304
  return _context21.abrupt("return", {
85018
85305
  applied: true,
85019
85306
  appliedCount: survivedCount,
@@ -85028,9 +85315,10 @@ function createNavigationToolset(ctx) {
85028
85315
  }) : undefined,
85029
85316
  removedRowIds: survived.removedRowIds.length ? survived.removedRowIds : undefined,
85030
85317
  failed: failed.length ? summarizeFailures(failed) : undefined,
85031
- note: 'The user DISCARDED the staged changes, but the table had ALREADY SAVED the listed operations before the decision arrived ' + '(it saves pending edits by itself when the user clicks outside the grid), so the rollback found nothing to revert. ' + 'Report EXACTLY these operations as live on the server and ask the user whether to undo them — do NOT re-send them, and do not claim the discard took effect.'
85318
+ outcome: withdrawn ? 'WITHDRAWN' : 'DISCARDED',
85319
+ note: "".concat(decision, ", but the table had ALREADY SAVED the listed operations before that ") + '(it saves pending edits by itself when the user clicks outside the grid), so the rollback found nothing to revert. ' + 'Report EXACTLY these operations as live on the server and ask the user whether to undo them — do NOT re-send them, and do not claim the discard took effect.'
85032
85320
  });
85033
- case 566:
85321
+ case 578:
85034
85322
  // Trim the echoed row: drop `*DisplayTexts` mirrors, collapse localized objects to one language.
85035
85323
  trimEcho = function trimEcho(values) {
85036
85324
  var isLocalized = function isLocalized(v) {
@@ -85056,9 +85344,9 @@ function createNavigationToolset(ctx) {
85056
85344
  return [column, cellValueOf(_api2, node, column)];
85057
85345
  })) : undefined;
85058
85346
  }; // The commit REPORTS what the server confirmed; grid state cannot (a vanished rejected row gets no marker).
85059
- _context21.next = 570;
85347
+ _context21.next = 582;
85060
85348
  return handle.commitStagedChanges();
85061
- case 570:
85349
+ case 582:
85062
85350
  finalOutcome = _context21.sent;
85063
85351
  // Rows resolved by the sequential lookup pass above were already committed individually — merge
85064
85352
  // their outcomes in. When that pass never ran (the common case), this is exactly `finalOutcome`.
@@ -85094,14 +85382,8 @@ function createNavigationToolset(ctx) {
85094
85382
  })));
85095
85383
  }; // Translate a rejection quoting a raw .NET pattern into the length limit it encodes (original text kept).
85096
85384
  lengthLimitNote = function lengthLimitNote(rowId, texts) {
85097
- var _quoted$slice$match;
85098
- var quoted = texts.join(' ');
85099
- var quantifier = /\{0,(\d+)\}/.exec(quoted);
85100
- if (!quantifier) return undefined;
85101
- var upTo = Number(quantifier[1]);
85102
- // `[…][…]{0,29}` = one mandatory character plus up to 29 = 30; a lone `[…]{0,29}` = 29.
85103
- var leadingClasses = ((_quoted$slice$match = quoted.slice(0, quantifier.index).match(/\]/g)) !== null && _quoted$slice$match !== void 0 ? _quoted$slice$match : []).length;
85104
- var max = leadingClasses > 1 ? upTo + 1 : upTo;
85385
+ var max = patternLengthLimit(texts.join(' '));
85386
+ if (max === undefined) return undefined;
85105
85387
  var sent = sentValuesOf(rowId);
85106
85388
  var over = sent.filter(function (v) {
85107
85389
  return v.length > max;
@@ -85197,12 +85479,12 @@ function createNavigationToolset(ctx) {
85197
85479
  survivedAfterCommit = outcomeIsEmpty ? survivingOperations() : undefined;
85198
85480
  autoCommitted = !!survivedAfterCommit && survivedAfterCommit.changes.length + survivedAfterCommit.addedRowIds.length + survivedAfterCommit.removedRowIds.length > 0;
85199
85481
  if (!(outcomeIsEmpty && !autoCommitted && !serverErrors.length)) {
85200
- _context21.next = 596;
85482
+ _context21.next = 608;
85201
85483
  break;
85202
85484
  }
85203
- _context21.next = 594;
85485
+ _context21.next = 606;
85204
85486
  return handle.rollback();
85205
- case 594:
85487
+ case 606:
85206
85488
  restoreUserFilter();
85207
85489
  return _context21.abrupt("return", _objectSpread$A(_objectSpread$A({
85208
85490
  applied: false,
@@ -85211,13 +85493,13 @@ function createNavigationToolset(ctx) {
85211
85493
  }, remainingPart), {}, {
85212
85494
  note: 'NOTHING was saved: the commit reported no row as saved or rejected, and the grid holds none of the staged values any more ' + '(the table dropped the pending edits before they were sent). Do NOT report this as done — re-read the rows (readGridRows) and stage the batch again.'
85213
85495
  }));
85214
- case 596:
85496
+ case 608:
85215
85497
  autoCommittedOps = autoCommitted ? survivedAfterCommit : undefined;
85216
85498
  committedIds = new Set(autoCommittedOps ? [].concat(_toConsumableArray(autoCommittedOps.changes.map(function (change) {
85217
85499
  return change.rowId;
85218
85500
  })), _toConsumableArray(autoCommittedOps.addedRowIds), _toConsumableArray(autoCommittedOps.removedRowIds)) : (_outcome$committed = outcome === null || outcome === void 0 ? void 0 : outcome.committed) !== null && _outcome$committed !== void 0 ? _outcome$committed : []);
85219
85501
  if (!serverErrors.length) {
85220
- _context21.next = 675;
85502
+ _context21.next = 687;
85221
85503
  break;
85222
85504
  }
85223
85505
  failedIds = new Set(serverErrors.map(function (s) {
@@ -85251,9 +85533,9 @@ function createNavigationToolset(ctx) {
85251
85533
  _id: removedRecordIds.get(rowId)
85252
85534
  };
85253
85535
  }); // Clear the rejected leftovers (they would block the next staging).
85254
- _context21.next = 605;
85536
+ _context21.next = 617;
85255
85537
  return handle.rollback();
85256
- case 605:
85538
+ case 617:
85257
85539
  restoreUserFilter();
85258
85540
  // Partial failure: neither the commit report nor the rollback is reliable — read the server back per operation.
85259
85541
  hasIdColumn = !!_api2.getColumnDef('_id'); // A COUNT budget bounded nothing: one probe can spend three 8s row-waits, so 25 of them ran for ten
@@ -85341,9 +85623,9 @@ function createNavigationToolset(ctx) {
85341
85623
  verifiedChanges = [];
85342
85624
  verifiedAdds = [];
85343
85625
  verifiedRemovals = [];
85344
- _context21.prev = 616;
85626
+ _context21.prev = 628;
85345
85627
  _iterator38 = _createForOfIteratorHelper$i(editTargets);
85346
- _context21.prev = 618;
85628
+ _context21.prev = 630;
85347
85629
  _loop5 = /*#__PURE__*/_regeneratorRuntime.mark(function _loop5() {
85348
85630
  var _expectedValueOf, _target$from;
85349
85631
  var target, probe, serverValue, serverState;
@@ -85388,35 +85670,35 @@ function createNavigationToolset(ctx) {
85388
85670
  }, _loop5);
85389
85671
  });
85390
85672
  _iterator38.s();
85391
- case 621:
85673
+ case 633:
85392
85674
  if ((_step38 = _iterator38.n()).done) {
85393
- _context21.next = 627;
85675
+ _context21.next = 639;
85394
85676
  break;
85395
85677
  }
85396
- return _context21.delegateYield(_loop5(), "t14", 623);
85397
- case 623:
85678
+ return _context21.delegateYield(_loop5(), "t14", 635);
85679
+ case 635:
85398
85680
  if (!_context21.t14) {
85399
- _context21.next = 625;
85681
+ _context21.next = 637;
85400
85682
  break;
85401
85683
  }
85402
- return _context21.abrupt("continue", 625);
85403
- case 625:
85404
- _context21.next = 621;
85684
+ return _context21.abrupt("continue", 637);
85685
+ case 637:
85686
+ _context21.next = 633;
85405
85687
  break;
85406
- case 627:
85407
- _context21.next = 632;
85688
+ case 639:
85689
+ _context21.next = 644;
85408
85690
  break;
85409
- case 629:
85410
- _context21.prev = 629;
85411
- _context21.t15 = _context21["catch"](618);
85691
+ case 641:
85692
+ _context21.prev = 641;
85693
+ _context21.t15 = _context21["catch"](630);
85412
85694
  _iterator38.e(_context21.t15);
85413
- case 632:
85414
- _context21.prev = 632;
85695
+ case 644:
85696
+ _context21.prev = 644;
85415
85697
  _iterator38.f();
85416
- return _context21.finish(632);
85417
- case 635:
85698
+ return _context21.finish(644);
85699
+ case 647:
85418
85700
  _iterator39 = _createForOfIteratorHelper$i(addTargets);
85419
- _context21.prev = 636;
85701
+ _context21.prev = 648;
85420
85702
  _loop6 = /*#__PURE__*/_regeneratorRuntime.mark(function _loop6() {
85421
85703
  var target, probe;
85422
85704
  return _regeneratorRuntime.wrap(function _loop6$(_context12) {
@@ -85444,66 +85726,66 @@ function createNavigationToolset(ctx) {
85444
85726
  }, _loop6);
85445
85727
  });
85446
85728
  _iterator39.s();
85447
- case 639:
85729
+ case 651:
85448
85730
  if ((_step39 = _iterator39.n()).done) {
85449
- _context21.next = 643;
85731
+ _context21.next = 655;
85450
85732
  break;
85451
85733
  }
85452
- return _context21.delegateYield(_loop6(), "t16", 641);
85453
- case 641:
85454
- _context21.next = 639;
85734
+ return _context21.delegateYield(_loop6(), "t16", 653);
85735
+ case 653:
85736
+ _context21.next = 651;
85455
85737
  break;
85456
- case 643:
85457
- _context21.next = 648;
85738
+ case 655:
85739
+ _context21.next = 660;
85458
85740
  break;
85459
- case 645:
85460
- _context21.prev = 645;
85461
- _context21.t17 = _context21["catch"](636);
85741
+ case 657:
85742
+ _context21.prev = 657;
85743
+ _context21.t17 = _context21["catch"](648);
85462
85744
  _iterator39.e(_context21.t17);
85463
- case 648:
85464
- _context21.prev = 648;
85745
+ case 660:
85746
+ _context21.prev = 660;
85465
85747
  _iterator39.f();
85466
- return _context21.finish(648);
85467
- case 651:
85748
+ return _context21.finish(660);
85749
+ case 663:
85468
85750
  _iterator40 = _createForOfIteratorHelper$i(removalTargets);
85469
- _context21.prev = 652;
85751
+ _context21.prev = 664;
85470
85752
  _iterator40.s();
85471
- case 654:
85753
+ case 666:
85472
85754
  if ((_step40 = _iterator40.n()).done) {
85473
- _context21.next = 662;
85755
+ _context21.next = 674;
85474
85756
  break;
85475
85757
  }
85476
85758
  target = _step40.value;
85477
- _context21.next = 658;
85759
+ _context21.next = 670;
85478
85760
  return probeServerRow(target._id, function () {
85479
85761
  return true;
85480
85762
  });
85481
- case 658:
85763
+ case 670:
85482
85764
  probe = _context21.sent;
85483
85765
  verifiedRemovals.push({
85484
85766
  rowId: target.rowId,
85485
85767
  serverState: probe.state === 'missing' ? 'applied' : probe.state === 'found' ? 'reverted' : 'unknown'
85486
85768
  });
85487
- case 660:
85488
- _context21.next = 654;
85769
+ case 672:
85770
+ _context21.next = 666;
85489
85771
  break;
85490
- case 662:
85491
- _context21.next = 667;
85772
+ case 674:
85773
+ _context21.next = 679;
85492
85774
  break;
85493
- case 664:
85494
- _context21.prev = 664;
85495
- _context21.t18 = _context21["catch"](652);
85775
+ case 676:
85776
+ _context21.prev = 676;
85777
+ _context21.t18 = _context21["catch"](664);
85496
85778
  _iterator40.e(_context21.t18);
85497
- case 667:
85498
- _context21.prev = 667;
85779
+ case 679:
85780
+ _context21.prev = 679;
85499
85781
  _iterator40.f();
85500
- return _context21.finish(667);
85501
- case 670:
85502
- _context21.prev = 670;
85782
+ return _context21.finish(679);
85783
+ case 682:
85784
+ _context21.prev = 682;
85503
85785
  // The table belongs to the user again before we answer, whatever the probes did.
85504
85786
  restoreVerifyFilter();
85505
- return _context21.finish(670);
85506
- case 673:
85787
+ return _context21.finish(682);
85788
+ case 685:
85507
85789
  appliedCount = [].concat(verifiedChanges, verifiedAdds, verifiedRemovals).filter(function (v) {
85508
85790
  return v.serverState === 'applied';
85509
85791
  }).length;
@@ -85529,11 +85811,11 @@ function createNavigationToolset(ctx) {
85529
85811
  }, remainingPart), {}, {
85530
85812
  note: 'The SERVER REJECTED the listed rows. Every other operation was READ BACK from the server — its `serverState` is the truth: ' + 'applied = the effect IS on the server (do NOT re-send it), reverted = re-send it after fixing the rejection cause, ' + 'unknown = verify with readGridRows/locateRow before re-sending. Never re-send an applied or unknown operation blindly — that is how silent duplicates happen.' + (verifyDeadlineHit ? ' The read-back ran out of time, so some `unknown`s mean UNCHECKED rather than unanswered — check those yourself before deciding.' : '') + parentBindingNote
85531
85813
  }));
85532
- case 675:
85814
+ case 687:
85533
85815
  // Return the real _id so references are not built from grid rowIds; catalogs/packages list rows are new EDITORS.
85534
85816
  livePath = (_root$navigationState3 = root.navigationState.path) !== null && _root$navigationState3 !== void 0 ? _root$navigationState3 : '';
85535
85817
  editorPathFor = function editorPathFor(id) {
85536
- return !id ? undefined : _entry2.label === 'catalogs' && livePath.replace(/^\//, '') === 'catalogs' ? "catalogs/".concat(id, "/series") : _entry2.label === 'packages' && livePath.replace(/^\//, '') === 'packages' ? "packages/".concat(id, "/properties") : undefined;
85818
+ return !id ? undefined : _entry2.label === 'catalogs' && livePath.replace(/^\//, '') === 'catalogs' ? "catalogs/".concat(id, "/").concat(EDITOR_DEFAULT_VIEW.catalogs) : _entry2.label === 'packages' && livePath.replace(/^\//, '') === 'packages' ? "packages/".concat(id, "/").concat(EDITOR_DEFAULT_VIEW.packages) : undefined;
85537
85819
  }; // Above a handful of rows the receipt carries ids only — the values are the stored ones of the given columns.
85538
85820
  echoValues = addedRows.length <= 10;
85539
85821
  withServerIds = addedRows.map(function (a) {
@@ -85686,7 +85968,7 @@ function createNavigationToolset(ctx) {
85686
85968
  // The serie by NUMBER AND NAME, not by 24-hex id — the thing to check is whether this is serie 0.
85687
85969
  serieScope && (addedRows.length || staged.length || removed.length) ? " SERIE-SCOPED TABLE: these rows belong to ".concat(serieLabelOf(serieScope), " \u2014 the serie the VIEW's selector held, which AUTO-SELECTS THE FIRST serie when nobody chose one").concat(addedRows.length ? ', so a new row can land in the components serie without anyone deciding that' : '', ". CONFIRM it is the serie you meant before continuing.").concat(foreignSeries.length ? " MISMATCH: the saved record(s) report serieId ".concat(foreignSeries.join(', '), ", which is NOT this view's scope \u2014 read the rows back before doing anything else.") : '') : '') + (removed.length ? ' REMOVALS: deleting without cleanReferences is safe and IS the reference check on the catalog tables that check it (decisions, features, options, option groups, feature classes, items, series, partlists, formulas, price feature groups, finishes, detail infos, packages, pricelists): unreferenced → deleted; referenced → nothing changes and the answer lists every place by kind (first 100 + the total). Do not check references beforehand - delete, read the answer, then report the places and re-send with cleanReferences: true only after the user agreed (the answer says how many were removed; that delete cannot be undone), or re-wire the places first. ' + 'Other tables delete without checking: after such a delete read the referrers yourself - lintCatalog on the refreshed planner finds most dead pointers.' : '') + plannerStaleNote() + (stagingNotes.length ? " HOUSE-STYLE NOTES: ".concat(stagingNotes.join(' ')) : '')
85688
85970
  }));
85689
- case 690:
85971
+ case 702:
85690
85972
  // Thrown (not returned) so the refusal does NOT end the turn — the model tells the user to decide on the staged edits first.
85691
85973
  dirtyGrids = root.gridRegistry.entries.filter(function (entry) {
85692
85974
  var _entry$getHandle6;
@@ -85695,11 +85977,12 @@ function createNavigationToolset(ctx) {
85695
85977
  return entry.label;
85696
85978
  });
85697
85979
  if (!dirtyGrids.length) {
85698
- _context21.next = 693;
85980
+ _context21.next = 705;
85699
85981
  break;
85700
85982
  }
85701
85983
  throw new Error("Page reload refused: table(s) ".concat(dirtyGrids.join(', '), " still carry staged, unapproved edits that a reload would silently drop. Ask the user to \xDCbernehmen or Verwerfen them first, then call reloadPage again."));
85702
- case 693:
85984
+ case 705:
85985
+ rememberReloadSelection((_root$navigationState4 = root.navigationState.path) !== null && _root$navigationState4 !== void 0 ? _root$navigationState4 : '', (_ctx$getSelection = ctx.getSelection) === null || _ctx$getSelection === void 0 ? void 0 : _ctx$getSelection.call(ctx));
85703
85986
  // Deferred so the tool result reaches the chat and the turn is persisted (the stored endedByTool record is what
85704
85987
  // triggers the automatic 'Continue.' after the reload) before the document unloads.
85705
85988
  setTimeout(function () {
@@ -85709,31 +85992,31 @@ function createNavigationToolset(ctx) {
85709
85992
  ok: true,
85710
85993
  // Tells the bridge client not to wait for a settled context — this document is gone in 2 s.
85711
85994
  pageReload: true,
85712
- note: "Full page reload triggered — this turn ends here. The chat reopens on this conversation and an automatic 'Continue.' follows once the view is ready (if the agent panel is not open after the reload, it fires when the user opens it). Every planner instance is rebuilt from a FRESH article payload, so decisionRefs and media changes are now in effect — verify with listDecisions / getMediaInfo, do not assume."
85995
+ note: "Full page reload triggered — this turn ends here. The chat reopens on this conversation and an automatic 'Continue.' follows once the view is ready (if the agent panel is not open after the reload, it fires when the user opens it). The view comes back with the same serie/article selected. Every planner instance is rebuilt from a FRESH article payload, so decisionRefs and media changes are now in effect — verify with listDecisions / getMediaInfo, do not assume."
85713
85996
  });
85714
- case 695:
85715
- _livePath = (_root$navigationState4 = root.navigationState.path) !== null && _root$navigationState4 !== void 0 ? _root$navigationState4 : '';
85997
+ case 708:
85998
+ _livePath = (_root$navigationState5 = root.navigationState.path) !== null && _root$navigationState5 !== void 0 ? _root$navigationState5 : '';
85716
85999
  packageBase = (_livePath$match = _livePath.match(/^\/?packages\/([^/]+)/)) === null || _livePath$match === void 0 ? void 0 : _livePath$match[1];
85717
86000
  catalogBase = (_livePath$match2 = _livePath.match(/^\/?catalogs\/([^/]+)/)) === null || _livePath$match2 === void 0 ? void 0 : _livePath$match2[1];
85718
86001
  baseId = (_ref55 = (_ref56 = packageBase !== null && packageBase !== void 0 ? packageBase : catalogBase) !== null && _ref56 !== void 0 ? _ref56 : ctx.packageId) !== null && _ref55 !== void 0 ? _ref55 : ctx.catalogId;
85719
86002
  if (baseId) {
85720
- _context21.next = 701;
86003
+ _context21.next = 714;
85721
86004
  break;
85722
86005
  }
85723
86006
  return _context21.abrupt("return", {
85724
86007
  error: 'No catalog/package context — nothing to reload.'
85725
86008
  });
85726
- case 701:
86009
+ case 714:
85727
86010
  // Package views load the ENRICHER pack, catalog views the raw IDM catalog.
85728
86011
  isPack = baseId === packageBase || !packageBase && !catalogBase && baseId === ctx.packageId;
85729
86012
  _root$webplannerInsta = root.webplannerInstanceStore.invalidateByBase(baseId), destroyed = _root$webplannerInsta.destroyed, reloadTriggered = _root$webplannerInsta.reloadTriggered, knownKeys = _root$webplannerInsta.knownKeys;
85730
86013
  source = isPack ? "PACKAGE ".concat(baseId, " (enricher pack: pricelist factors and manual prices APPLY)") : "CATALOG ".concat(baseId, " (raw IDM catalog: enricher pricelists do NOT apply \u2014 to verify pack prices, navigateTo the package view first, then reloadPlanner there)"); // A base matching no instance key invalidates nothing — report that instead of claiming the discard happened.
85731
86014
  if (!(!destroyed && !reloadTriggered)) {
85732
- _context21.next = 708;
86015
+ _context21.next = 721;
85733
86016
  break;
85734
86017
  }
85735
86018
  if (knownKeys.length) {
85736
- _context21.next = 707;
86019
+ _context21.next = 720;
85737
86020
  break;
85738
86021
  }
85739
86022
  return _context21.abrupt("return", {
@@ -85743,7 +86026,7 @@ function createNavigationToolset(ctx) {
85743
86026
  environmentUnchanged: true,
85744
86027
  note: "NOTHING TO RELOAD \u2014 no planner instance is loaded for ".concat(baseId, ", so there was no stale snapshot to discard. The next planner use loads CURRENT data from ").concat(source, ".")
85745
86028
  });
85746
- case 707:
86029
+ case 720:
85747
86030
  return _context21.abrupt("return", {
85748
86031
  ok: false,
85749
86032
  destroyed: destroyed,
@@ -85752,32 +86035,32 @@ function createNavigationToolset(ctx) {
85752
86035
  knownKeys: knownKeys,
85753
86036
  error: "Nothing was invalidated: no loaded planner belongs to '".concat(baseId, "'. Loaded instance keys are [").concat(knownKeys.join(', '), "] ") + "(key = catalogId|serieNo|itemTypeNo|language). A key whose first segment is EMPTY or differs from '".concat(baseId, "' means the ") + "configurator was mounted without the catalog binding \u2014 reload the page to re-bind, then reloadPlanner again. Do NOT treat " + "planner reads as current until this succeeds."
85754
86037
  });
85755
- case 708:
86038
+ case 721:
85756
86039
  return _context21.abrupt("return", {
85757
86040
  ok: true,
85758
86041
  destroyed: destroyed,
85759
86042
  reloadTriggered: reloadTriggered,
85760
86043
  note: "Planner instances were discarded \u2014 the next planner use loads CURRENT data from ".concat(source) + (reloadTriggered ? ' (the open configurator reloads itself, and its stale instance is destroyed rather than re-adopted)' : '') + ". The turn ends here; an automatic 'Continue.' follows."
85761
86044
  });
85762
- case 709:
86045
+ case 722:
85763
86046
  _resolveGrid4 = resolveGrid(args.grid), _entry3 = _resolveGrid4.entry, _error3 = _resolveGrid4.error;
85764
86047
  if (!(_error3 || !_entry3)) {
85765
- _context21.next = 712;
86048
+ _context21.next = 725;
85766
86049
  break;
85767
86050
  }
85768
86051
  return _context21.abrupt("return", {
85769
86052
  error: _error3
85770
86053
  });
85771
- case 712:
86054
+ case 725:
85772
86055
  _handle = _entry3.getHandle();
85773
86056
  if (_handle) {
85774
- _context21.next = 715;
86057
+ _context21.next = 728;
85775
86058
  break;
85776
86059
  }
85777
86060
  return _context21.abrupt("return", {
85778
86061
  error: "Table '".concat(_entry3.label, "' is not ready.")
85779
86062
  });
85780
- case 715:
86063
+ case 728:
85781
86064
  actionName = String((_action = input === null || input === void 0 ? void 0 : input.action) !== null && _action !== void 0 ? _action : '');
85782
86065
  actionInput = String((_input = input === null || input === void 0 ? void 0 : input.input) !== null && _input !== void 0 ? _input : '').trim();
85783
86066
  _addTargets = _handle.getDivaColumnDefs().filter(isHeaderAddColumn);
@@ -85789,13 +86072,13 @@ function createNavigationToolset(ctx) {
85789
86072
  return action.name;
85790
86073
  })));
85791
86074
  if (available.includes(actionName)) {
85792
- _context21.next = 723;
86075
+ _context21.next = 736;
85793
86076
  break;
85794
86077
  }
85795
86078
  return _context21.abrupt("return", {
85796
86079
  error: "Action '".concat(actionName, "' is not available on '").concat(_entry3.label, "' \u2014 this table has: ").concat(available.join(', ') || 'no actions', " (listGrids shows each table's actions).")
85797
86080
  });
85798
- case 723:
86081
+ case 736:
85799
86082
  approve = /*#__PURE__*/function () {
85800
86083
  var _ref57 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee10(label) {
85801
86084
  return _regeneratorRuntime.wrap(function _callee10$(_context16) {
@@ -85903,336 +86186,336 @@ function createNavigationToolset(ctx) {
85903
86186
  return action.name === actionName;
85904
86187
  });
85905
86188
  if (!viewAction) {
85906
- _context21.next = 751;
86189
+ _context21.next = 764;
85907
86190
  break;
85908
86191
  }
85909
86192
  mutating = viewAction.mutating !== false;
85910
86193
  _context21.t19 = mutating;
85911
86194
  if (!_context21.t19) {
85912
- _context21.next = 737;
86195
+ _context21.next = 750;
85913
86196
  break;
85914
86197
  }
85915
- _context21.next = 736;
86198
+ _context21.next = 749;
85916
86199
  return approve("".concat(actionName, ": ").concat(actionInput || '(no input)'));
85917
- case 736:
86200
+ case 749:
85918
86201
  _context21.t19 = !_context21.sent;
85919
- case 737:
86202
+ case 750:
85920
86203
  if (!_context21.t19) {
85921
- _context21.next = 739;
86204
+ _context21.next = 752;
85922
86205
  break;
85923
86206
  }
85924
86207
  return _context21.abrupt("return", declined);
85925
- case 739:
85926
- _context21.prev = 739;
86208
+ case 752:
86209
+ _context21.prev = 752;
85927
86210
  _context21.t20 = "";
85928
- _context21.next = 743;
86211
+ _context21.next = 756;
85929
86212
  return viewAction.run(actionInput);
85930
- case 743:
86213
+ case 756:
85931
86214
  _context21.t21 = _context21.sent;
85932
86215
  _context21.t22 = _context21.t20.concat.call(_context21.t20, _context21.t21).concat(mutating ? autoNote : '');
85933
86216
  return _context21.abrupt("return", {
85934
86217
  applied: true,
85935
86218
  note: _context21.t22
85936
86219
  });
85937
- case 748:
85938
- _context21.prev = 748;
85939
- _context21.t23 = _context21["catch"](739);
86220
+ case 761:
86221
+ _context21.prev = 761;
86222
+ _context21.t23 = _context21["catch"](752);
85940
86223
  return _context21.abrupt("return", {
85941
86224
  error: _context21.t23 instanceof Error ? _context21.t23.message : String(_context21.t23)
85942
86225
  });
85943
- case 751:
86226
+ case 764:
85944
86227
  if (!(actionName === 'cloneCatalog')) {
85945
- _context21.next = 770;
86228
+ _context21.next = 783;
85946
86229
  break;
85947
86230
  }
85948
86231
  if (isRecordId(actionInput)) {
85949
- _context21.next = 754;
86232
+ _context21.next = 767;
85950
86233
  break;
85951
86234
  }
85952
86235
  return _context21.abrupt("return", {
85953
86236
  error: "input must be the catalog's _id (24-hex) — read it from the _id column (readGridRows)."
85954
86237
  });
85955
- case 754:
85956
- _context21.next = 756;
86238
+ case 767:
86239
+ _context21.next = 769;
85957
86240
  return approve("cloneCatalog: ".concat(actionInput));
85958
- case 756:
86241
+ case 769:
85959
86242
  if (_context21.sent) {
85960
- _context21.next = 758;
86243
+ _context21.next = 771;
85961
86244
  break;
85962
86245
  }
85963
86246
  return _context21.abrupt("return", declined);
85964
- case 758:
85965
- _context21.prev = 758;
85966
- _context21.next = 761;
86247
+ case 771:
86248
+ _context21.prev = 771;
86249
+ _context21.next = 774;
85967
86250
  return authorizedFetch("".concat(root.configurationStore.apiConfig.idmService, "/catalogs/").concat(actionInput, "/clone"), 'POST', '{}');
85968
- case 761:
85969
- _context21.next = 766;
86251
+ case 774:
86252
+ _context21.next = 779;
85970
86253
  break;
85971
- case 763:
85972
- _context21.prev = 763;
85973
- _context21.t24 = _context21["catch"](758);
86254
+ case 776:
86255
+ _context21.prev = 776;
86256
+ _context21.t24 = _context21["catch"](771);
85974
86257
  return _context21.abrupt("return", {
85975
86258
  error: _context21.t24 instanceof Error ? _context21.t24.message : String(_context21.t24)
85976
86259
  });
85977
- case 766:
85978
- _context21.next = 768;
86260
+ case 779:
86261
+ _context21.next = 781;
85979
86262
  return refreshAndSettle();
85980
- case 768:
86263
+ case 781:
85981
86264
  cloneSettled = _context21.sent;
85982
86265
  return _context21.abrupt("return", {
85983
86266
  applied: true,
85984
86267
  note: "Catalog cloned server-side \u2014 the table refreshes; the copy appears as a new row (readGridRows to find it and REPORT its name + _id).".concat(autoNote).concat(cloneSettled ? '' : unsettledNote)
85985
86268
  });
85986
- case 770:
86269
+ case 783:
85987
86270
  if (!(actionName === 'importGlobalFeatures')) {
85988
- _context21.next = 790;
86271
+ _context21.next = 803;
85989
86272
  break;
85990
86273
  }
85991
86274
  catalogId = String((_catalogId = ((_handle$getApplicatio7 = (_handle$getApplicatio8 = _handle.getApplicationData) === null || _handle$getApplicatio8 === void 0 ? void 0 : _handle$getApplicatio8.call(_handle)) !== null && _handle$getApplicatio7 !== void 0 ? _handle$getApplicatio7 : {}).catalogId) !== null && _catalogId !== void 0 ? _catalogId : '');
85992
86275
  if (catalogId) {
85993
- _context21.next = 774;
86276
+ _context21.next = 787;
85994
86277
  break;
85995
86278
  }
85996
86279
  return _context21.abrupt("return", {
85997
86280
  error: 'No catalog context on this table.'
85998
86281
  });
85999
- case 774:
86000
- _context21.next = 776;
86282
+ case 787:
86283
+ _context21.next = 789;
86001
86284
  return approve('importGlobalFeatures');
86002
- case 776:
86285
+ case 789:
86003
86286
  if (_context21.sent) {
86004
- _context21.next = 778;
86287
+ _context21.next = 791;
86005
86288
  break;
86006
86289
  }
86007
86290
  return _context21.abrupt("return", declined);
86008
- case 778:
86009
- _context21.prev = 778;
86010
- _context21.next = 781;
86291
+ case 791:
86292
+ _context21.prev = 791;
86293
+ _context21.next = 794;
86011
86294
  return authorizedFetch("".concat(root.configurationStore.apiConfig.idmService, "/catalogs/").concat(catalogId, "/features/global"), 'POST');
86012
- case 781:
86013
- _context21.next = 786;
86295
+ case 794:
86296
+ _context21.next = 799;
86014
86297
  break;
86015
- case 783:
86016
- _context21.prev = 783;
86017
- _context21.t25 = _context21["catch"](778);
86298
+ case 796:
86299
+ _context21.prev = 796;
86300
+ _context21.t25 = _context21["catch"](791);
86018
86301
  return _context21.abrupt("return", {
86019
86302
  error: _context21.t25 instanceof Error ? _context21.t25.message : String(_context21.t25)
86020
86303
  });
86021
- case 786:
86022
- _context21.next = 788;
86304
+ case 799:
86305
+ _context21.next = 801;
86023
86306
  return refreshAndSettle();
86024
- case 788:
86307
+ case 801:
86025
86308
  importSettled = _context21.sent;
86026
86309
  return _context21.abrupt("return", {
86027
86310
  applied: true,
86028
86311
  note: "Global features imported \u2014 the table refreshes with the added feature rows.".concat(autoNote).concat(importSettled ? '' : unsettledNote)
86029
86312
  });
86030
- case 790:
86313
+ case 803:
86031
86314
  if (!(actionName === 'setPriceFactor' || actionName === 'setPriceFactorPriority')) {
86032
- _context21.next = 851;
86315
+ _context21.next = 864;
86033
86316
  break;
86034
86317
  }
86035
86318
  app = (_handle$getApplicatio9 = (_handle$getApplicatio10 = _handle.getApplicationData) === null || _handle$getApplicatio10 === void 0 ? void 0 : _handle$getApplicatio10.call(_handle)) !== null && _handle$getApplicatio9 !== void 0 ? _handle$getApplicatio9 : {};
86036
86319
  serieNo = Number(app.serieNo);
86037
- _context21.prev = 793;
86320
+ _context21.prev = 806;
86038
86321
  _params2 = JSON.parse(actionInput || '{}');
86039
- _context21.next = 800;
86322
+ _context21.next = 813;
86040
86323
  break;
86041
- case 797:
86042
- _context21.prev = 797;
86043
- _context21.t26 = _context21["catch"](793);
86324
+ case 810:
86325
+ _context21.prev = 810;
86326
+ _context21.t26 = _context21["catch"](806);
86044
86327
  return _context21.abrupt("return", {
86045
86328
  error: "input must be a JSON object — listGrids shows this action's exact shape."
86046
86329
  });
86047
- case 800:
86330
+ case 813:
86048
86331
  scope = String((_params2$scope = _params2.scope) !== null && _params2$scope !== void 0 ? _params2$scope : '');
86049
86332
  if (scope in PRICE_FACTOR_FIELDS) {
86050
- _context21.next = 803;
86333
+ _context21.next = 816;
86051
86334
  break;
86052
86335
  }
86053
86336
  return _context21.abrupt("return", {
86054
86337
  error: "scope must be one of: ".concat(Object.keys(PRICE_FACTOR_FIELDS).join(', '), ".")
86055
86338
  });
86056
- case 803:
86339
+ case 816:
86057
86340
  _key4 = _params2.key === undefined ? undefined : String(_params2.key); // The factor maps live on the PRICELIST record — the write goes through the parent pricelists grid row.
86058
86341
  parent = resolveGrid('pricelists');
86059
86342
  if (!(parent.error || !parent.entry || !parent.api)) {
86060
- _context21.next = 807;
86343
+ _context21.next = 820;
86061
86344
  break;
86062
86345
  }
86063
86346
  return _context21.abrupt("return", {
86064
86347
  error: "The parent 'pricelists' table must be on screen for factor actions."
86065
86348
  });
86066
- case 807:
86349
+ case 820:
86067
86350
  parentHandle = parent.entry.getHandle();
86068
86351
  if (parentHandle) {
86069
- _context21.next = 810;
86352
+ _context21.next = 823;
86070
86353
  break;
86071
86354
  }
86072
86355
  return _context21.abrupt("return", {
86073
86356
  error: "Table 'pricelists' is not ready."
86074
86357
  });
86075
- case 810:
86358
+ case 823:
86076
86359
  parent.api.forEachNode(function (node) {
86077
86360
  var _node$data5;
86078
86361
  if (((_node$data5 = node.data) === null || _node$data5 === void 0 ? void 0 : _node$data5._id) === app.pricelistId) pricelistNode = node;
86079
86362
  });
86080
86363
  if ((_pricelistNode = pricelistNode) !== null && _pricelistNode !== void 0 && _pricelistNode.id) {
86081
- _context21.next = 813;
86364
+ _context21.next = 826;
86082
86365
  break;
86083
86366
  }
86084
86367
  return _context21.abrupt("return", {
86085
86368
  error: "Pricelist ".concat(app.pricelistId, " is not loaded in the 'pricelists' table.")
86086
86369
  });
86087
- case 813:
86088
- _context21.prev = 813;
86370
+ case 826:
86371
+ _context21.prev = 826;
86089
86372
  if (!(actionName === 'setPriceFactor')) {
86090
- _context21.next = 822;
86373
+ _context21.next = 835;
86091
86374
  break;
86092
86375
  }
86093
86376
  factors = _params2.factors;
86094
86377
  if (!(!Array.isArray(factors) || factors.some(function (f) {
86095
86378
  return typeof f !== 'number' || !Number.isFinite(f) || f <= 0;
86096
86379
  }))) {
86097
- _context21.next = 818;
86380
+ _context21.next = 831;
86098
86381
  break;
86099
86382
  }
86100
86383
  return _context21.abrupt("return", {
86101
86384
  error: 'factors must be an array of positive numbers (>1 = factor, <1 = discount fraction, e.g. 0.95 = 5% off); [] clears the entry.'
86102
86385
  });
86103
- case 818:
86386
+ case 831:
86104
86387
  patch = applyPriceFactor(pricelistNode.data, serieNo, scope, _key4, factors);
86105
86388
  label = "setPriceFactor ".concat(scope).concat(_key4 ? " ".concat(_key4) : '', " \u2192 [").concat(factors.join('; '), "] (Serie ").concat(serieNo, ")");
86106
- _context21.next = 828;
86389
+ _context21.next = 841;
86107
86390
  break;
86108
- case 822:
86391
+ case 835:
86109
86392
  if (!(typeof _params2.priority !== 'boolean')) {
86110
- _context21.next = 824;
86393
+ _context21.next = 837;
86111
86394
  break;
86112
86395
  }
86113
86396
  return _context21.abrupt("return", {
86114
86397
  error: 'priority must be true or false.'
86115
86398
  });
86116
- case 824:
86399
+ case 837:
86117
86400
  if (_key4) {
86118
- _context21.next = 826;
86401
+ _context21.next = 839;
86119
86402
  break;
86120
86403
  }
86121
86404
  return _context21.abrupt("return", {
86122
86405
  error: 'key is required (the pfg id / price group).'
86123
86406
  });
86124
- case 826:
86407
+ case 839:
86125
86408
  patch = applyPriceFactorPriority(pricelistNode.data, serieNo, scope, _key4, _params2.priority);
86126
86409
  label = "setPriceFactorPriority ".concat(scope, " ").concat(_key4, " \u2192 ").concat(_params2.priority, " (Serie ").concat(serieNo, ")");
86127
- case 828:
86128
- _context21.next = 833;
86410
+ case 841:
86411
+ _context21.next = 846;
86129
86412
  break;
86130
- case 830:
86131
- _context21.prev = 830;
86132
- _context21.t27 = _context21["catch"](813);
86413
+ case 843:
86414
+ _context21.prev = 843;
86415
+ _context21.t27 = _context21["catch"](826);
86133
86416
  return _context21.abrupt("return", {
86134
86417
  error: _context21.t27 instanceof Error ? _context21.t27.message : String(_context21.t27)
86135
86418
  });
86136
- case 833:
86137
- _context21.next = 835;
86419
+ case 846:
86420
+ _context21.next = 848;
86138
86421
  return approve(label);
86139
- case 835:
86422
+ case 848:
86140
86423
  if (_context21.sent) {
86141
- _context21.next = 837;
86424
+ _context21.next = 850;
86142
86425
  break;
86143
86426
  }
86144
86427
  return _context21.abrupt("return", declined);
86145
- case 837:
86428
+ case 850:
86146
86429
  pricelistRowId = pricelistNode.id;
86147
- _context21.next = 840;
86430
+ _context21.next = 853;
86148
86431
  return parentHandle.setNodeDataValue(pricelistRowId, patch, {
86149
86432
  suppressAutoCommit: true
86150
86433
  });
86151
- case 840:
86434
+ case 853:
86152
86435
  if (_context21.sent) {
86153
- _context21.next = 842;
86436
+ _context21.next = 855;
86154
86437
  break;
86155
86438
  }
86156
86439
  return _context21.abrupt("return", {
86157
86440
  error: 'The pricelist row rejected the update.'
86158
86441
  });
86159
- case 842:
86160
- _context21.next = 844;
86442
+ case 855:
86443
+ _context21.next = 857;
86161
86444
  return parentHandle.commitStagedChanges();
86162
- case 844:
86445
+ case 857:
86163
86446
  factorOutcome = _context21.sent;
86164
86447
  rejected = factorOutcome === null || factorOutcome === void 0 ? void 0 : factorOutcome.failed.find(function (failure) {
86165
86448
  return failure.rowId === pricelistRowId;
86166
86449
  });
86167
86450
  if (!rejected) {
86168
- _context21.next = 848;
86451
+ _context21.next = 861;
86169
86452
  break;
86170
86453
  }
86171
86454
  return _context21.abrupt("return", {
86172
86455
  error: "The server rejected the factor update: ".concat(rejected.errors.join(' ') || 'no reason given', ". Nothing was changed.")
86173
86456
  });
86174
- case 848:
86457
+ case 861:
86175
86458
  if (!(factorOutcome && !factorOutcome.committed.includes(pricelistRowId))) {
86176
- _context21.next = 850;
86459
+ _context21.next = 863;
86177
86460
  break;
86178
86461
  }
86179
86462
  return _context21.abrupt("return", {
86180
86463
  error: 'The factor update was NOT saved — the commit did not confirm the pricelist row. Re-read the pricelist (readGridRows) before retrying.'
86181
86464
  });
86182
- case 850:
86465
+ case 863:
86183
86466
  return _context21.abrupt("return", {
86184
86467
  applied: true,
86185
86468
  note: "Saved on the pricelist record and confirmed by the server (same path as the factor modal) \u2014 the prices table reflects it immediately.".concat(autoNote)
86186
86469
  });
86187
- case 851:
86470
+ case 864:
86188
86471
  if (!(actionName === 'deleteAllManualPrices')) {
86189
- _context21.next = 869;
86472
+ _context21.next = 882;
86190
86473
  break;
86191
86474
  }
86192
86475
  _app = (_handle$getApplicatio11 = (_handle$getApplicatio12 = _handle.getApplicationData) === null || _handle$getApplicatio12 === void 0 ? void 0 : _handle$getApplicatio12.call(_handle)) !== null && _handle$getApplicatio11 !== void 0 ? _handle$getApplicatio11 : {};
86193
- _context21.next = 855;
86476
+ _context21.next = 868;
86194
86477
  return approve("deleteAllManualPrices (Pricelist ".concat(_app.pricelistId, ", Serie ").concat(_app.serieNo, ")"));
86195
- case 855:
86478
+ case 868:
86196
86479
  if (_context21.sent) {
86197
- _context21.next = 857;
86480
+ _context21.next = 870;
86198
86481
  break;
86199
86482
  }
86200
86483
  return _context21.abrupt("return", declined);
86201
- case 857:
86202
- _context21.prev = 857;
86203
- _context21.next = 860;
86484
+ case 870:
86485
+ _context21.prev = 870;
86486
+ _context21.next = 873;
86204
86487
  return authorizedFetch("".concat(root.configurationStore.apiConfig.enricherService, "/packages/").concat(_app.packageId, "/pricelists/").concat(_app.pricelistId, "/serie/").concat(_app.serieNo, "/prices/manual"), 'DELETE');
86205
- case 860:
86206
- _context21.next = 865;
86488
+ case 873:
86489
+ _context21.next = 878;
86207
86490
  break;
86208
- case 862:
86209
- _context21.prev = 862;
86210
- _context21.t28 = _context21["catch"](857);
86491
+ case 875:
86492
+ _context21.prev = 875;
86493
+ _context21.t28 = _context21["catch"](870);
86211
86494
  return _context21.abrupt("return", {
86212
86495
  error: _context21.t28 instanceof Error ? _context21.t28.message : String(_context21.t28)
86213
86496
  });
86214
- case 865:
86215
- _context21.next = 867;
86497
+ case 878:
86498
+ _context21.next = 880;
86216
86499
  return refreshAndSettle();
86217
- case 867:
86500
+ case 880:
86218
86501
  pricesSettled = _context21.sent;
86219
86502
  return _context21.abrupt("return", {
86220
86503
  applied: true,
86221
86504
  note: "All manual price overrides of this pricelist+serie were deleted (irreversible) \u2014 the table refreshed; origPrices and factors now determine every cell.".concat(autoNote).concat(pricesSettled ? '' : unsettledNote)
86222
86505
  });
86223
- case 869:
86506
+ case 882:
86224
86507
  if (!(actionName === 'removeColumn')) {
86225
- _context21.next = 908;
86508
+ _context21.next = 921;
86226
86509
  break;
86227
86510
  }
86228
86511
  if (actionInput) {
86229
- _context21.next = 872;
86512
+ _context21.next = 885;
86230
86513
  break;
86231
86514
  }
86232
86515
  return _context21.abrupt("return", {
86233
86516
  error: "Provide input: the column to remove — its field id ('optionsSetRefs.2305') or the bare key ('2305'); listGrids shows the columns."
86234
86517
  });
86235
- case 872:
86518
+ case 885:
86236
86519
  removeTargetIn = function removeTargetIn(defs) {
86237
86520
  return defs.find(function (def) {
86238
86521
  return def.field === actionInput || def.colId === actionInput || String(def.field).endsWith(".".concat(actionInput));
@@ -86240,7 +86523,7 @@ function createNavigationToolset(ctx) {
86240
86523
  };
86241
86524
  _target3 = removeTargetIn(removeTargets);
86242
86525
  if (_target3) {
86243
- _context21.next = 876;
86526
+ _context21.next = 889;
86244
86527
  break;
86245
86528
  }
86246
86529
  return _context21.abrupt("return", {
@@ -86248,75 +86531,75 @@ function createNavigationToolset(ctx) {
86248
86531
  return "'".concat(def.field, "'");
86249
86532
  }).join(', ') || 'none', ".")
86250
86533
  });
86251
- case 876:
86534
+ case 889:
86252
86535
  _header = typeof _target3.headerName === 'string' ? root.t(_target3.headerName) : String(_target3.field);
86253
- _context21.next = 879;
86536
+ _context21.next = 892;
86254
86537
  return approve("removeColumn: ".concat(_header));
86255
- case 879:
86538
+ case 892:
86256
86539
  if (_context21.sent) {
86257
- _context21.next = 881;
86540
+ _context21.next = 894;
86258
86541
  break;
86259
86542
  }
86260
86543
  return _context21.abrupt("return", declined);
86261
- case 881:
86544
+ case 894:
86262
86545
  // The defs are rebuilt on every render, each onRemove closing over the feature list of ITS render — the
86263
86546
  // pre-wait closure would drop a feature the user added while the bar was open. Re-resolve after the wait.
86264
86547
  live = removeTargetIn(_handle.getDivaColumnDefs().filter(isRemovableColumn));
86265
86548
  if (live) {
86266
- _context21.next = 884;
86549
+ _context21.next = 897;
86267
86550
  break;
86268
86551
  }
86269
86552
  return _context21.abrupt("return", {
86270
86553
  applied: false,
86271
86554
  note: "'".concat(_target3.field, "' left the table while the approval was pending \u2014 nothing was removed. listGrids shows the current columns.")
86272
86555
  });
86273
- case 884:
86274
- _context21.prev = 884;
86275
- _context21.next = 887;
86556
+ case 897:
86557
+ _context21.prev = 897;
86558
+ _context21.next = 900;
86276
86559
  return live.headerComponentParams.onRemove();
86277
- case 887:
86560
+ case 900:
86278
86561
  saved = _context21.sent;
86279
- _context21.next = 893;
86562
+ _context21.next = 906;
86280
86563
  break;
86281
- case 890:
86282
- _context21.prev = 890;
86283
- _context21.t29 = _context21["catch"](884);
86564
+ case 903:
86565
+ _context21.prev = 903;
86566
+ _context21.t29 = _context21["catch"](897);
86284
86567
  return _context21.abrupt("return", {
86285
86568
  error: _context21.t29 instanceof Error ? _context21.t29.message : String(_context21.t29)
86286
86569
  });
86287
- case 893:
86570
+ case 906:
86288
86571
  if (!(saved === false)) {
86289
- _context21.next = 895;
86572
+ _context21.next = 908;
86290
86573
  break;
86291
86574
  }
86292
86575
  return _context21.abrupt("return", {
86293
86576
  applied: false,
86294
86577
  note: "The parent row did not take the new feature list \u2014 '".concat(_target3.field, "' was NOT removed. locateRow the parent row again so the view reloads, then retry.")
86295
86578
  });
86296
- case 895:
86579
+ case 908:
86297
86580
  // Poll until the column left the view — the parent entity's write and the rebuild are asynchronous.
86298
86581
  gone = false;
86299
86582
  attempt = 0;
86300
- case 897:
86583
+ case 910:
86301
86584
  if (!(attempt < 20 && !gone)) {
86302
- _context21.next = 904;
86585
+ _context21.next = 917;
86303
86586
  break;
86304
86587
  }
86305
- _context21.next = 900;
86588
+ _context21.next = 913;
86306
86589
  return sleep(100);
86307
- case 900:
86590
+ case 913:
86308
86591
  gone = !_handle.getDivaColumnDefs().some(function (def) {
86309
86592
  return def.field === _target3.field;
86310
86593
  });
86311
- case 901:
86594
+ case 914:
86312
86595
  attempt++;
86313
- _context21.next = 897;
86596
+ _context21.next = 910;
86314
86597
  break;
86315
- case 904:
86598
+ case 917:
86316
86599
  // The view declares what becomes of the rows' cells of a removed feature column.
86317
86600
  rowsNote = _target3.headerComponentParams.removeKeepsCells ? ' The rows KEEP their cells for that feature (hidden now, still exported) — re-add the column to see or clear them.' : " The server also strips that feature's cells from every row of this table.";
86318
86601
  if (gone) {
86319
- _context21.next = 907;
86602
+ _context21.next = 920;
86320
86603
  break;
86321
86604
  }
86322
86605
  return _context21.abrupt("return", {
@@ -86328,7 +86611,7 @@ function createNavigationToolset(ctx) {
86328
86611
  viewNotRebuilt: true,
86329
86612
  note: "The parent row took the new feature list, but '".concat(_target3.field, "' is still in the view after the wait \u2014 the rebuild is pending. Re-read the columns (listGrids) before touching this table again; do NOT retry the removal.") + rowsNote + autoNote
86330
86613
  });
86331
- case 907:
86614
+ case 920:
86332
86615
  return _context21.abrupt("return", {
86333
86616
  applied: true,
86334
86617
  removed: {
@@ -86337,25 +86620,25 @@ function createNavigationToolset(ctx) {
86337
86620
  },
86338
86621
  note: 'Column removed.' + rowsNote + autoNote
86339
86622
  });
86340
- case 908:
86623
+ case 921:
86341
86624
  // addColumn: one approval, sequential adds — parallel adds race the view rebuild.
86342
86625
  _target4 = _addTargets[0];
86343
86626
  markAdded = plannerStaleMarkFor(root);
86344
86627
  if (actionInput) {
86345
- _context21.next = 912;
86628
+ _context21.next = 925;
86346
86629
  break;
86347
86630
  }
86348
86631
  return _context21.abrupt("return", {
86349
86632
  error: "Provide input: the key(s) to add, comma-separated \u2014 readColumnOptions('".concat(_target4.field, "') lists the addable entries.")
86350
86633
  });
86351
- case 912:
86634
+ case 925:
86352
86635
  keys = actionInput.split(',').map(function (k) {
86353
86636
  return k.trim();
86354
86637
  }).filter(Boolean); // Resolve ALL keys BEFORE asking approval: the bar shows the real labels, invalid keys fail fast.
86355
86638
  resolved = [];
86356
- _context21.prev = 914;
86639
+ _context21.prev = 927;
86357
86640
  _iterator43 = _createForOfIteratorHelper$i(keys);
86358
- _context21.prev = 916;
86641
+ _context21.prev = 929;
86359
86642
  _loop9 = /*#__PURE__*/_regeneratorRuntime.mark(function _loop9() {
86360
86643
  var key, options, option;
86361
86644
  return _regeneratorRuntime.wrap(function _loop9$(_context19) {
@@ -86390,57 +86673,57 @@ function createNavigationToolset(ctx) {
86390
86673
  }, _loop9);
86391
86674
  });
86392
86675
  _iterator43.s();
86393
- case 919:
86676
+ case 932:
86394
86677
  if ((_step43 = _iterator43.n()).done) {
86395
- _context21.next = 926;
86678
+ _context21.next = 939;
86396
86679
  break;
86397
86680
  }
86398
- return _context21.delegateYield(_loop9(), "t30", 921);
86399
- case 921:
86681
+ return _context21.delegateYield(_loop9(), "t30", 934);
86682
+ case 934:
86400
86683
  _ret5 = _context21.t30;
86401
86684
  if (!_ret5) {
86402
- _context21.next = 924;
86685
+ _context21.next = 937;
86403
86686
  break;
86404
86687
  }
86405
86688
  return _context21.abrupt("return", _ret5.v);
86406
- case 924:
86407
- _context21.next = 919;
86689
+ case 937:
86690
+ _context21.next = 932;
86408
86691
  break;
86409
- case 926:
86410
- _context21.next = 931;
86692
+ case 939:
86693
+ _context21.next = 944;
86411
86694
  break;
86412
- case 928:
86413
- _context21.prev = 928;
86414
- _context21.t31 = _context21["catch"](916);
86695
+ case 941:
86696
+ _context21.prev = 941;
86697
+ _context21.t31 = _context21["catch"](929);
86415
86698
  _iterator43.e(_context21.t31);
86416
- case 931:
86417
- _context21.prev = 931;
86699
+ case 944:
86700
+ _context21.prev = 944;
86418
86701
  _iterator43.f();
86419
- return _context21.finish(931);
86420
- case 934:
86421
- _context21.next = 939;
86702
+ return _context21.finish(944);
86703
+ case 947:
86704
+ _context21.next = 952;
86422
86705
  break;
86423
- case 936:
86424
- _context21.prev = 936;
86425
- _context21.t32 = _context21["catch"](914);
86706
+ case 949:
86707
+ _context21.prev = 949;
86708
+ _context21.t32 = _context21["catch"](927);
86426
86709
  return _context21.abrupt("return", {
86427
86710
  error: _context21.t32 instanceof Error ? _context21.t32.message : String(_context21.t32)
86428
86711
  });
86429
- case 939:
86430
- _context21.next = 941;
86712
+ case 952:
86713
+ _context21.next = 954;
86431
86714
  return approve("addColumn: ".concat(resolved.map(function (r) {
86432
86715
  return r.label;
86433
86716
  }).join(', ')));
86434
- case 941:
86717
+ case 954:
86435
86718
  if (_context21.sent) {
86436
- _context21.next = 943;
86719
+ _context21.next = 956;
86437
86720
  break;
86438
86721
  }
86439
86722
  return _context21.abrupt("return", declined);
86440
- case 943:
86723
+ case 956:
86441
86724
  added = [];
86442
86725
  newColumns = [];
86443
- _context21.prev = 945;
86726
+ _context21.prev = 958;
86444
86727
  _loop10 = /*#__PURE__*/_regeneratorRuntime.mark(function _loop10() {
86445
86728
  var key, beforeFields, _attempt, newColumn;
86446
86729
  return _regeneratorRuntime.wrap(function _loop10$(_context20) {
@@ -86487,17 +86770,17 @@ function createNavigationToolset(ctx) {
86487
86770
  }, _loop10);
86488
86771
  });
86489
86772
  _i15 = 0, _resolved = resolved;
86490
- case 948:
86773
+ case 961:
86491
86774
  if (!(_i15 < _resolved.length)) {
86492
- _context21.next = 953;
86775
+ _context21.next = 966;
86493
86776
  break;
86494
86777
  }
86495
- return _context21.delegateYield(_loop10(), "t33", 950);
86496
- case 950:
86778
+ return _context21.delegateYield(_loop10(), "t33", 963);
86779
+ case 963:
86497
86780
  _i15++;
86498
- _context21.next = 948;
86781
+ _context21.next = 961;
86499
86782
  break;
86500
- case 953:
86783
+ case 966:
86501
86784
  // On a decision's option-combinations subtable the add also writes the decision's featureRefs.
86502
86785
  decisionSubtableNote = /optioncombination/i.test(_entry3.label) ? " NOTE: on a decision's option-combinations subtable this ALSO wrote the feature(s) into the decision's featureRefs — existing rows carry NO condition for it, which in a type-0/1 re-opens that feature entirely. Re-read the decision row; fill the rows or revert featureRefs if you only wanted to look." : '';
86503
86786
  partialNote = newColumns.length < resolved.length ? " ".concat(resolved.length - newColumns.length, " added column(s) did not surface a field id within the poll \u2014 listGrids shows the final columns.") : '';
@@ -86513,33 +86796,33 @@ function createNavigationToolset(ctx) {
86513
86796
  return "'".concat(c, "'");
86514
86797
  }).join(', '), ".") : 'Column(s) added — the table re-renders; listGrids shows the new columns and their field ids.') + partialNote + decisionSubtableNote + autoNote
86515
86798
  }));
86516
- case 958:
86517
- _context21.prev = 958;
86518
- _context21.t34 = _context21["catch"](945);
86799
+ case 971:
86800
+ _context21.prev = 971;
86801
+ _context21.t34 = _context21["catch"](958);
86519
86802
  // Sequential adds: everything before the failing key IS added — report the partial state.
86520
86803
  if (added.length) markAdded();
86521
86804
  return _context21.abrupt("return", {
86522
86805
  error: "".concat(_context21.t34 instanceof Error ? _context21.t34.message : String(_context21.t34)).concat(newColumns.length ? " \u2014 ".concat(newColumns.length, " column(s) were already added before the failure: ").concat(newColumns.join(', ')) : '')
86523
86806
  });
86524
- case 962:
86807
+ case 975:
86525
86808
  _resolveGrid5 = resolveGrid(args.grid), _entry4 = _resolveGrid5.entry, _api3 = _resolveGrid5.api, _error4 = _resolveGrid5.error;
86526
86809
  if (!(_error4 || !_api3 || !_entry4)) {
86527
- _context21.next = 965;
86810
+ _context21.next = 978;
86528
86811
  break;
86529
86812
  }
86530
86813
  return _context21.abrupt("return", {
86531
86814
  error: _error4
86532
86815
  });
86533
- case 965:
86816
+ case 978:
86534
86817
  _handle2 = _entry4.getHandle();
86535
86818
  if (_handle2) {
86536
- _context21.next = 968;
86819
+ _context21.next = 981;
86537
86820
  break;
86538
86821
  }
86539
86822
  return _context21.abrupt("return", {
86540
86823
  error: "Table '".concat(_entry4.label, "' is not ready.")
86541
86824
  });
86542
- case 968:
86825
+ case 981:
86543
86826
  _column7 = String((_column8 = input === null || input === void 0 ? void 0 : input.column) !== null && _column8 !== void 0 ? _column8 : '');
86544
86827
  search = String((_search = input === null || input === void 0 ? void 0 : input.search) !== null && _search !== void 0 ? _search : '');
86545
86828
  _limit = Math.min(Number(input === null || input === void 0 ? void 0 : input.limit) > 0 ? Number(input.limit) : 50, 200); // `exact` is one contract for every source below: action values and enum values as well as lookups.
@@ -86554,11 +86837,11 @@ function createNavigationToolset(ctx) {
86554
86837
  return action.name === _column7;
86555
86838
  });
86556
86839
  if (!optionAction) {
86557
- _context21.next = 990;
86840
+ _context21.next = 1003;
86558
86841
  break;
86559
86842
  }
86560
86843
  if (optionAction.options) {
86561
- _context21.next = 978;
86844
+ _context21.next = 991;
86562
86845
  break;
86563
86846
  }
86564
86847
  return _context21.abrupt("return", {
@@ -86567,11 +86850,11 @@ function createNavigationToolset(ctx) {
86567
86850
  hasMore: false,
86568
86851
  note: "'".concat(_column7, "' is a table ACTION with no value list \u2014 its input is described in listGrids: ").concat(optionAction.description)
86569
86852
  });
86570
- case 978:
86571
- _context21.prev = 978;
86572
- _context21.next = 981;
86853
+ case 991:
86854
+ _context21.prev = 991;
86855
+ _context21.next = 994;
86573
86856
  return optionAction.options(search, _limit);
86574
- case 981:
86857
+ case 994:
86575
86858
  _yield$optionAction$o = _context21.sent;
86576
86859
  options = _yield$optionAction$o.options;
86577
86860
  note = _yield$optionAction$o.note;
@@ -86584,20 +86867,20 @@ function createNavigationToolset(ctx) {
86584
86867
  } : {}), {}, {
86585
86868
  note: "Values for runTableAction('".concat(_column7, "', <input>) \u2014 pass the VALUE(s), not the label.").concat(note ? " ".concat(note) : '').concat(wantsExact ? ' exact:true — only options whose value or label equals the search.' : '')
86586
86869
  }));
86587
- case 987:
86588
- _context21.prev = 987;
86589
- _context21.t35 = _context21["catch"](978);
86870
+ case 1000:
86871
+ _context21.prev = 1000;
86872
+ _context21.t35 = _context21["catch"](991);
86590
86873
  return _context21.abrupt("return", {
86591
86874
  error: _context21.t35 instanceof Error ? _context21.t35.message : String(_context21.t35)
86592
86875
  });
86593
- case 990:
86876
+ case 1003:
86594
86877
  // Enum columns are answered here too: 'which values does this column take' is ONE question.
86595
86878
  enumDef = _handle2.getDivaColumnDefs().find(function (d) {
86596
86879
  return d.field === _column7;
86597
86880
  });
86598
86881
  enumData = enumEntriesOf(enumDef === null || enumDef === void 0 || (_enumDef$customParams = enumDef.customParams) === null || _enumDef$customParams === void 0 ? void 0 : _enumDef$customParams.enumData);
86599
86882
  if (!enumData.length) {
86600
- _context21.next = 994;
86883
+ _context21.next = 1007;
86601
86884
  break;
86602
86885
  }
86603
86886
  return _context21.abrupt("return", _objectSpread$A(_objectSpread$A({
@@ -86617,14 +86900,14 @@ function createNavigationToolset(ctx) {
86617
86900
  } : {}), {}, {
86618
86901
  note: "Enum column \u2014 this is the COMPLETE allowed set (also in listGrids). Stage the VALUE, not the label".concat(enumDef !== null && enumDef !== void 0 && (_enumDef$customParams2 = enumDef.customParams) !== null && _enumDef$customParams2 !== void 0 && _enumDef$customParams2.multiple ? ', comma-separated for multiple' : '', ".").concat(wantsExact ? ' exact:true — only options whose value or label equals the search.' : '')
86619
86902
  }));
86620
- case 994:
86903
+ case 1007:
86621
86904
  if (enumDef) {
86622
- _context21.next = 1001;
86905
+ _context21.next = 1014;
86623
86906
  break;
86624
86907
  }
86625
86908
  computedDef = divaDefOf(_handle2.getDivaColumnDefs(), _column7);
86626
86909
  if (!isComputedColumn(computedDef)) {
86627
- _context21.next = 999;
86910
+ _context21.next = 1012;
86628
86911
  break;
86629
86912
  }
86630
86913
  // Same source as listGrids, so the two cannot disagree about whether a new row may carry this column.
@@ -86635,16 +86918,16 @@ function createNavigationToolset(ctx) {
86635
86918
  hasMore: false,
86636
86919
  note: savedRowsOnly ? "'".concat(_column7, "' is a computed matrix cell \u2014 it has no option list, and addRows cannot set it. Create the row, then set it with stageTableEdits 'edits'.") : "'".concat(_column7, "' is a computed matrix cell \u2014 it has no option list; stage its value directly with stageTableEdits.")
86637
86920
  });
86638
- case 999:
86921
+ case 1012:
86639
86922
  _fields2 = _handle2.getDivaColumnDefs().map(function (d) {
86640
86923
  return d.field;
86641
86924
  }).filter(Boolean);
86642
86925
  return _context21.abrupt("return", {
86643
86926
  error: "Column '".concat(_column7, "' not found. Fields of '").concat(_entry4.label, "': ").concat(_fields2.join(', '), ".")
86644
86927
  });
86645
- case 1001:
86928
+ case 1014:
86646
86929
  if (!(enumDef.cellDataType === 'asset')) {
86647
- _context21.next = 1003;
86930
+ _context21.next = 1016;
86648
86931
  break;
86649
86932
  }
86650
86933
  return _context21.abrupt("return", {
@@ -86653,9 +86936,9 @@ function createNavigationToolset(ctx) {
86653
86936
  hasMore: false,
86654
86937
  note: "'".concat(_column7, "' is an ASSET cell \u2014 no option list; write it via uploadAsset + setAssetCell.")
86655
86938
  });
86656
- case 1003:
86939
+ case 1016:
86657
86940
  if (!(enumDef.cellDataType !== 'lookup' && !isHeaderAddColumn(enumDef))) {
86658
- _context21.next = 1005;
86941
+ _context21.next = 1018;
86659
86942
  break;
86660
86943
  }
86661
86944
  return _context21.abrupt("return", {
@@ -86664,10 +86947,21 @@ function createNavigationToolset(ctx) {
86664
86947
  hasMore: false,
86665
86948
  note: "'".concat(_column7, "' is a free-form ").concat((_enumDef$cellDataType = enumDef.cellDataType) !== null && _enumDef$cellDataType !== void 0 ? _enumDef$cellDataType : 'text', " column \u2014 it has no option list; stage a ").concat(enumDef.cellDataType === 'number' ? 'number' : 'value', " directly with stageTableEdits.")
86666
86949
  });
86667
- case 1005:
86668
- // Row-dependent url/filter templates resolve against a loaded row.
86669
- firstRow = _api3.getDisplayedRowAtIndex(0);
86670
- rowData = isRealRow(firstRow) ? (_data = firstRow.data) !== null && _data !== void 0 ? _data : {} : {}; // The server's contains-filter reads the search as a pattern: a bracket or a pipe in it returns nothing at all
86950
+ case 1018:
86951
+ // Row-dependent url/filter templates resolve against the row the options are for: the given rowId, else a NEW
86952
+ // row, whose empty data drops the row filters as the cell editor does — never an arbitrary loaded row, whose
86953
+ // values narrowed e.g. a pack's basedCatalogId list to that row's catalog.
86954
+ optionsRowId = (input === null || input === void 0 ? void 0 : input.rowId) != null ? String(input.rowId) : '';
86955
+ optionsRow = optionsRowId ? _api3.getRowNode(optionsRowId) : undefined;
86956
+ if (!(optionsRowId && !isRealRow(optionsRow))) {
86957
+ _context21.next = 1022;
86958
+ break;
86959
+ }
86960
+ return _context21.abrupt("return", {
86961
+ error: "No loaded row with rowId '".concat(optionsRowId, "' on '").concat(_entry4.label, "' \u2014 take the rowId from readGridRows, or omit it for the options of a NEW row.")
86962
+ });
86963
+ case 1022:
86964
+ rowData = (_optionsRow$data = optionsRow === null || optionsRow === void 0 ? void 0 : optionsRow.data) !== null && _optionsRow$data !== void 0 ? _optionsRow$data : {}; // The server's contains-filter reads the search as a pattern: a bracket or a pipe in it returns nothing at all
86671
86965
  // ('Bettbreite (90)' — measured as a false negative on an existence check). Query the longest plain word and
86672
86966
  // match the whole text here; `exact` is matched here as well.
86673
86967
  patternChars = /[()[\]{}|+*?^$\\]/;
@@ -86677,10 +86971,10 @@ function createNavigationToolset(ctx) {
86677
86971
  })[0]) !== null && _plainWords$sort$ !== void 0 ? _plainWords$sort$ : '' : search;
86678
86972
  matchLocally = remoteSearch !== search || wantsExact; // The local match only sees ONE capped fetch — a plain word with more hits than that can still hide the value.
86679
86973
  fetchLimit = matchLocally ? Math.max(_limit, 200) : _limit;
86680
- _context21.prev = 1012;
86681
- _context21.next = 1015;
86974
+ _context21.prev = 1028;
86975
+ _context21.next = 1031;
86682
86976
  return _handle2.fetchLookupOptions(_column7, remoteSearch, rowData, 0, fetchLimit);
86683
- case 1015:
86977
+ case 1031:
86684
86978
  fetched = _context21.sent;
86685
86979
  text = function text(o) {
86686
86980
  var _o$label2;
@@ -86708,104 +87002,104 @@ function createNavigationToolset(ctx) {
86708
87002
  } : {}), {}, {
86709
87003
  note: (isHeaderAddColumn(enumDef) ? "These entries are ADDABLE via runTableAction 'addColumn' (each becomes a table column) — they are not cell values to stage." : 'Stage this column with the VALUE(s) — comma-separated when the column is multi-select (see columnMeta.multiSelect).') + (remoteSearch !== search ? " The search contains characters the server filter reads as a pattern \u2014 the server was asked for '".concat(remoteSearch, "' and the full text '").concat(search, "' was matched here.") : '') + (wantsExact ? ' exact:true — only options whose value or label equals the search.' : '') + nestedLookupNote(enumDef) + (fetchCapped ? " The ".concat(wantsExact ? 'exact' : 'full-text', " check ran on the first ").concat(fetchLimit, " rows").concat(remoteSearch ? " matching '".concat(remoteSearch, "'") : '', " only \u2014 narrow the search if the value is not among them.") : '')
86710
87004
  }));
86711
- case 1022:
86712
- _context21.prev = 1022;
86713
- _context21.t36 = _context21["catch"](1012);
87005
+ case 1038:
87006
+ _context21.prev = 1038;
87007
+ _context21.t36 = _context21["catch"](1028);
86714
87008
  // A row-dependent lookup cannot run without its row values — teach the recovery instead of the opaque error.
86715
87009
  appScope = (_handle2$getApplicati = (_handle2$getApplicati2 = _handle2.getApplicationData) === null || _handle2$getApplicati2 === void 0 ? void 0 : _handle2$getApplicati2.call(_handle2)) !== null && _handle2$getApplicati !== void 0 ? _handle2$getApplicati : {};
86716
87010
  deps = lookupRowDeps(_handle2.lookupTemplateFields(_column7), _handle2.getDivaColumnDefs(), function (dep) {
86717
87011
  return [undefined, null, ''].includes(rowData[dep]) && appScope[dep] === undefined;
86718
87012
  });
86719
- hint = deps.length ? " This lookup's option list depends on row value(s) ".concat(deps.join(', '), " \u2014 the table's first row does not hold them, so it cannot be listed here: stage the add directly with the depending column in the SAME row (lookups resolve row-aware there).") : '';
87013
+ hint = deps.length ? " This lookup's option list depends on row value(s) ".concat(deps.join(', ')).concat(optionsRowId ? " \u2014 row '".concat(optionsRowId, "' does not hold them") : '', ": pass the rowId of a row that holds them, or stage the add directly with the depending column in the SAME row (lookups resolve row-aware there).") : '';
86720
87014
  return _context21.abrupt("return", {
86721
87015
  error: (_context21.t36 instanceof Error ? _context21.t36.message : String(_context21.t36)) + hint
86722
87016
  });
86723
- case 1028:
87017
+ case 1044:
86724
87018
  _resolveGrid6 = resolveGrid(args.grid), _api4 = _resolveGrid6.api, _error5 = _resolveGrid6.error;
86725
87019
  if (!(_error5 || !_api4)) {
86726
- _context21.next = 1031;
87020
+ _context21.next = 1047;
86727
87021
  break;
86728
87022
  }
86729
87023
  return _context21.abrupt("return", {
86730
87024
  error: _error5
86731
87025
  });
86732
- case 1031:
87026
+ case 1047:
86733
87027
  _api4.setFilterModel(null);
86734
87028
  return _context21.abrupt("return", {
86735
87029
  ok: true
86736
87030
  });
86737
- case 1033:
87031
+ case 1049:
86738
87032
  _resolveGrid7 = resolveGrid(args.grid), _entry5 = _resolveGrid7.entry, _error6 = _resolveGrid7.error;
86739
87033
  if (!(_error6 || !_entry5)) {
86740
- _context21.next = 1036;
87034
+ _context21.next = 1052;
86741
87035
  break;
86742
87036
  }
86743
87037
  return _context21.abrupt("return", {
86744
87038
  error: _error6
86745
87039
  });
86746
- case 1036:
87040
+ case 1052:
86747
87041
  _handle3 = _entry5.getHandle();
86748
87042
  if (_handle3) {
86749
- _context21.next = 1039;
87043
+ _context21.next = 1055;
86750
87044
  break;
86751
87045
  }
86752
87046
  return _context21.abrupt("return", {
86753
87047
  error: "Table '".concat(_entry5.label, "' is not ready.")
86754
87048
  });
86755
- case 1039:
87049
+ case 1055:
86756
87050
  if (_handle3.hasPendingChanges()) {
86757
- _context21.next = 1041;
87051
+ _context21.next = 1057;
86758
87052
  break;
86759
87053
  }
86760
87054
  return _context21.abrupt("return", {
86761
87055
  discarded: false,
86762
87056
  note: "Nothing is staged on '".concat(_entry5.label, "' \u2014 no staging blocks writes to it.")
86763
87057
  });
86764
- case 1041:
87058
+ case 1057:
86765
87059
  if (ctx.autoApprove) {
86766
- _context21.next = 1048;
87060
+ _context21.next = 1064;
86767
87061
  break;
86768
87062
  }
86769
87063
  awaitingApproval();
86770
87064
  // The bar's own buttons read Apply/Discard — the label says what Apply does, or Discard reads as the action.
86771
87065
  _label = "discardStagedChanges: every staged change on '".concat(_entry5.label, "' is dropped, the table returns to its last committed state");
86772
- _context21.next = 1046;
87066
+ _context21.next = 1062;
86773
87067
  return _entry5.requestAgentApproval(1, _label, signal);
86774
- case 1046:
87068
+ case 1062:
86775
87069
  if (_context21.sent) {
86776
- _context21.next = 1048;
87070
+ _context21.next = 1064;
86777
87071
  break;
86778
87072
  }
86779
87073
  return _context21.abrupt("return", {
86780
87074
  discarded: false,
86781
87075
  note: 'The user KEPT the staged changes — nothing was discarded. Ask what to do with them instead.'
86782
87076
  });
86783
- case 1048:
87077
+ case 1064:
86784
87078
  if (_handle3.hasPendingChanges()) {
86785
- _context21.next = 1050;
87079
+ _context21.next = 1066;
86786
87080
  break;
86787
87081
  }
86788
87082
  return _context21.abrupt("return", {
86789
87083
  discarded: false,
86790
87084
  note: "The table SAVED the staged changes on '".concat(_entry5.label, "' before the decision arrived (it saves pending edits by itself when the user clicks outside the grid) \u2014 nothing was discarded, those changes are live on the server. Read the rows back (readGridRows) and ask the user whether to undo them.")
86791
87085
  });
86792
- case 1050:
86793
- _context21.next = 1052;
87086
+ case 1066:
87087
+ _context21.next = 1068;
86794
87088
  return _handle3.rollback();
86795
- case 1052:
87089
+ case 1068:
86796
87090
  // Same transparency rule as runTableAction: a discard executed without the bar must be reported as such.
86797
87091
  _autoNote = ctx.autoApprove ? ' AUTO-APPROVE is on — executed WITHOUT the approval bar, so the user could not keep their own pending edits; mention that ONCE per reply, not per call.' : '';
86798
87092
  return _context21.abrupt("return", {
86799
87093
  discarded: true,
86800
87094
  note: "The staged changes on '".concat(_entry5.label, "' were discarded \u2014 the table is back at its last committed state, nothing was sent to the server, and writes to it are possible again.").concat(_autoNote)
86801
87095
  });
86802
- case 1054:
87096
+ case 1070:
86803
87097
  throw new Error("Unknown navigation tool: ".concat(name));
86804
- case 1055:
87098
+ case 1071:
86805
87099
  case "end":
86806
87100
  return _context21.stop();
86807
87101
  }
86808
- }, _callee13, null, [[37, 43], [64, 70], [137, 151, 154, 157], [319, 333, 336, 339], [369, 412, 415, 418], [379, 386], [427, 445, 448, 451], [452, 476, 479, 482], [522, 534, 537, 540], [616,, 670, 673], [618, 629, 632, 635], [636, 645, 648, 651], [652, 664, 667, 670], [739, 748], [758, 763], [778, 783], [793, 797], [813, 830], [857, 862], [884, 890], [914, 936], [916, 928, 931, 934], [945, 958], [978, 987], [1012, 1022]]);
87102
+ }, _callee13, null, [[42, 48], [69, 75], [142, 156, 159, 162], [327, 341, 344, 347], [379, 422, 425, 428], [389, 396], [437, 455, 458, 461], [462, 486, 489, 492], [532, 544, 547, 550], [628,, 682, 685], [630, 641, 644, 647], [648, 657, 660, 663], [664, 676, 679, 682], [752, 761], [771, 776], [791, 796], [806, 810], [826, 843], [870, 875], [897, 903], [927, 949], [929, 941, 944, 947], [958, 971], [991, 1000], [1028, 1038]]);
86809
87103
  }));
86810
87104
  function dispatch(_x20, _x21, _x22, _x23) {
86811
87105
  return _dispatch.apply(this, arguments);
@@ -87304,6 +87598,8 @@ var MAX_INLINE_ASSET_BYTES = 128 * 1024;
87304
87598
 
87305
87599
  /** Sequential batches stop starting new entries after this and hand the rest back as `remaining`. */
87306
87600
  var TIME_BUDGET_MS = 100000;
87601
+ /** IDM's media name (DETAIL_INFO INTERNAL_NAME, languagetext40) holds at most this many characters. */
87602
+ var IDM_MEDIA_NAME_MAX = 40;
87307
87603
 
87308
87604
  /** Batches stop at the turn's abort or time budget and hand the untouched rest back. */
87309
87605
  var stopBatch = function stopBatch(startedAt, budgetMs, signal) {
@@ -87343,7 +87639,7 @@ function decodeInlineBase64(raw) {
87343
87639
  }
87344
87640
  if (binary.length > MAX_INLINE_ASSET_BYTES) {
87345
87641
  return {
87346
- error: "Inline asset is ".concat(Math.round(binary.length / 1024), " KB \u2014 over the ").concat(MAX_INLINE_ASSET_BYTES / 1024, " KB inline cap. ") + 'Inline bytes travel through the conversation as base64, so a photo-sized file costs more context than the whole task. ' + "Serve the file over HTTP and pass it as 'url' instead: the BROWSER downloads it, so the bytes never enter the conversation " + '(a CORS-enabled static server on localhost is enough, and it scales to a whole folder).'
87642
+ error: "Inline asset is ".concat(Math.round(binary.length / 1024), " KB \u2014 over the ").concat(MAX_INLINE_ASSET_BYTES / 1024, " KB inline cap. ") + 'Inline bytes travel through the conversation as base64, so a photo-sized file costs more context than the whole task. ' + "Serve the file over HTTP and pass it as 'url' instead: the BROWSER downloads it, so the bytes never enter the conversation " + "(a static server on localhost works when it sends Access-Control-Allow-Origin and the user allows Chrome's 'local network' access " + '— Chrome versions that still enforce Private Network Access also need Access-Control-Allow-Private-Network: true — and it scales to a whole folder).'
87347
87643
  };
87348
87644
  }
87349
87645
  // Allocate the ArrayBuffer up front: a plain Uint8Array is not a valid BlobPart for File.
@@ -87447,7 +87743,7 @@ function _resolveUploadSource() {
87447
87743
  _context3.prev = 28;
87448
87744
  _context3.t0 = _context3["catch"](22);
87449
87745
  return _context3.abrupt("return", {
87450
- error: "".concat(fileName, ": the browser could not download the source URL (network/CORS \u2014 the host must allow cross-origin requests). ") + "Use a CORS-enabled source, pass the bytes inline via 'base64' if the file is small, or ask the user to upload it manually. " + "For a TEST/placeholder image, don't fetch one at all — GENERATE an SVG and upload it inline via the 'svg' parameter instead."
87746
+ error: "".concat(fileName, ": the browser could not download the source URL (network/CORS \u2014 the host must allow cross-origin requests). ") + "Use a CORS-enabled source, pass the bytes inline via 'base64' if the file is small, or ask the user to upload it manually. " + "From a localhost or private-network host Chrome also needs the user to allow 'local network' access for the page, " + 'and versions that still enforce Private Network Access need Access-Control-Allow-Private-Network: true on every response, the OPTIONS preflight included. ' + "For a TEST/placeholder image, don't fetch one at all — GENERATE an SVG and upload it inline via the 'svg' parameter instead."
87451
87747
  });
87452
87748
  case 31:
87453
87749
  if (source.ok) {
@@ -88150,37 +88446,44 @@ function _generateImageAsset() {
88150
88446
  engine: engine
88151
88447
  }), typeof args.temperature === 'number' ? {
88152
88448
  temperature: args.temperature
88153
- } : {});
88154
- _context10.prev = 57;
88155
- _context10.next = 60;
88449
+ } : {}); // A call cancelled before the request goes out sends nothing — that costs no budget.
88450
+ if (!(signal !== null && signal !== void 0 && signal.aborted)) {
88451
+ _context10.next = 59;
88452
+ break;
88453
+ }
88454
+ return _context10.abrupt("return", {
88455
+ error: 'The call was cancelled before the generation started — nothing was generated or charged.'
88456
+ });
88457
+ case 59:
88458
+ _context10.prev = 59;
88459
+ _context10.next = 62;
88156
88460
  return fetch("".concat(base, "/generate-image-with-references"), {
88157
88461
  method: 'POST',
88158
88462
  headers: {
88159
88463
  Authorization: "Bearer ".concat(jwt),
88160
88464
  'Content-Type': 'application/json'
88161
88465
  },
88162
- body: JSON.stringify(body),
88163
- signal: signal
88466
+ body: JSON.stringify(body)
88164
88467
  });
88165
- case 60:
88468
+ case 62:
88166
88469
  response = _context10.sent;
88167
- _context10.next = 66;
88470
+ _context10.next = 68;
88168
88471
  break;
88169
- case 63:
88170
- _context10.prev = 63;
88171
- _context10.t1 = _context10["catch"](57);
88472
+ case 65:
88473
+ _context10.prev = 65;
88474
+ _context10.t1 = _context10["catch"](59);
88172
88475
  return _context10.abrupt("return", {
88173
88476
  error: "The AI service could not be reached: ".concat(_context10.t1 instanceof Error ? _context10.t1.message : String(_context10.t1))
88174
88477
  });
88175
- case 66:
88176
- _context10.next = 68;
88478
+ case 68:
88479
+ _context10.next = 70;
88177
88480
  return response.text()["catch"](function () {
88178
88481
  return '';
88179
88482
  });
88180
- case 68:
88483
+ case 70:
88181
88484
  raw = _context10.sent;
88182
88485
  if (response.ok) {
88183
- _context10.next = 72;
88486
+ _context10.next = 74;
88184
88487
  break;
88185
88488
  }
88186
88489
  detail = raw.slice(0, 400);
@@ -88188,61 +88491,61 @@ function _generateImageAsset() {
88188
88491
  error: "Image generation failed: HTTP ".concat(response.status, " \u2014 ").concat(detail),
88189
88492
  hint: response.status === 429 ? "The organization's AI budget or the rate limit is exhausted — usage limits live under admin, this is not a retryable error." : response.status === 400 && /reference/i.test(detail) ? 'The service could not download a reference image — it must be publicly reachable FROM THE SERVER.' : undefined
88190
88493
  });
88191
- case 72:
88192
- _context10.prev = 72;
88494
+ case 74:
88495
+ _context10.prev = 74;
88193
88496
  payload = JSON.parse(raw);
88194
- _context10.next = 79;
88497
+ _context10.next = 81;
88195
88498
  break;
88196
- case 76:
88197
- _context10.prev = 76;
88198
- _context10.t2 = _context10["catch"](72);
88499
+ case 78:
88500
+ _context10.prev = 78;
88501
+ _context10.t2 = _context10["catch"](74);
88199
88502
  return _context10.abrupt("return", {
88200
88503
  error: "The AI service answered with a body this tool could not parse: ".concat(raw.slice(0, 200))
88201
88504
  });
88202
- case 79:
88505
+ case 81:
88203
88506
  images = Array.isArray((_payload = payload) === null || _payload === void 0 ? void 0 : _payload.images) ? payload.images : [];
88204
88507
  if (images.length) {
88205
- _context10.next = 82;
88508
+ _context10.next = 84;
88206
88509
  break;
88207
88510
  }
88208
88511
  return _context10.abrupt("return", {
88209
88512
  error: "The AI service returned no image".concat((_payload2 = payload) !== null && _payload2 !== void 0 && _payload2.error ? " (".concat(payload.error, ")") : '', "."),
88210
88513
  finalPrompt: (_payload3 = payload) === null || _payload3 === void 0 ? void 0 : _payload3.finalPrompt
88211
88514
  });
88212
- case 82:
88515
+ case 84:
88213
88516
  dataUrl = String((_images$0$url = (_images$ = images[0]) === null || _images$ === void 0 ? void 0 : _images$.url) !== null && _images$0$url !== void 0 ? _images$0$url : '');
88214
88517
  if (/^data:image\//i.test(dataUrl)) {
88215
- _context10.next = 85;
88518
+ _context10.next = 87;
88216
88519
  break;
88217
88520
  }
88218
88521
  return _context10.abrupt("return", {
88219
88522
  error: 'The generated image did not come back as image data.'
88220
88523
  });
88221
- case 85:
88222
- _context10.prev = 85;
88223
- _context10.next = 88;
88224
- return fetch(dataUrl);
88225
- case 88:
88524
+ case 87:
88525
+ _context10.prev = 87;
88226
88526
  _context10.next = 90;
88227
- return _context10.sent.blob();
88527
+ return fetch(dataUrl);
88228
88528
  case 90:
88529
+ _context10.next = 92;
88530
+ return _context10.sent.blob();
88531
+ case 92:
88229
88532
  blob = _context10.sent;
88230
88533
  file = new File([blob], fileName, {
88231
88534
  type: (_MIME_BY_EXTENSION$ex3 = MIME_BY_EXTENSION[extensionOf(fileName)]) !== null && _MIME_BY_EXTENSION$ex3 !== void 0 ? _MIME_BY_EXTENSION$ex3 : blob.type
88232
88535
  });
88233
- _context10.next = 97;
88536
+ _context10.next = 99;
88234
88537
  break;
88235
- case 94:
88236
- _context10.prev = 94;
88237
- _context10.t3 = _context10["catch"](85);
88538
+ case 96:
88539
+ _context10.prev = 96;
88540
+ _context10.t3 = _context10["catch"](87);
88238
88541
  return _context10.abrupt("return", {
88239
88542
  error: "The generated image could not be read: ".concat(_context10.t3 instanceof Error ? _context10.t3.message : String(_context10.t3))
88240
88543
  });
88241
- case 97:
88242
- _context10.prev = 97;
88243
- _context10.next = 100;
88244
- return uploadToMediaService(root, file, fileName, undefined, signal);
88245
- case 100:
88544
+ case 99:
88545
+ _context10.prev = 99;
88546
+ _context10.next = 102;
88547
+ return uploadToMediaService(root, file, fileName);
88548
+ case 102:
88246
88549
  uploaded = _context10.sent;
88247
88550
  return _context10.abrupt("return", _objectSpread$z(_objectSpread$z({}, uploaded), {}, {
88248
88551
  mode: mode,
@@ -88251,17 +88554,17 @@ function _generateImageAsset() {
88251
88554
  usage: (_payload$usageTrackin = (_payload6 = payload) === null || _payload6 === void 0 || (_payload6 = _payload6.usageTracking) === null || _payload6 === void 0 ? void 0 : _payload6.usageLimits) !== null && _payload$usageTrackin !== void 0 ? _payload$usageTrackin : undefined,
88252
88555
  note: 'Generated and uploaded — the bytes stayed in the browser. LOOK at it before using it: open the url, or set it with setAssetCell and ' + 'check the tile. It is unused until referenced.'
88253
88556
  }));
88254
- case 104:
88255
- _context10.prev = 104;
88256
- _context10.t4 = _context10["catch"](97);
88557
+ case 106:
88558
+ _context10.prev = 106;
88559
+ _context10.t4 = _context10["catch"](99);
88257
88560
  return _context10.abrupt("return", {
88258
88561
  error: "The image was generated but the upload failed: ".concat(_context10.t4 instanceof Error ? _context10.t4.message : String(_context10.t4))
88259
88562
  });
88260
- case 107:
88563
+ case 109:
88261
88564
  case "end":
88262
88565
  return _context10.stop();
88263
88566
  }
88264
- }, _callee10, null, [[20, 35, 38, 41], [57, 63], [72, 76], [85, 94], [97, 104]]);
88567
+ }, _callee10, null, [[20, 35, 38, 41], [59, 65], [74, 78], [87, 96], [99, 106]]);
88265
88568
  }));
88266
88569
  return _generateImageAsset.apply(this, arguments);
88267
88570
  }
@@ -88529,10 +88832,15 @@ function assetWriteVerdict(outcome, nodeId) {
88529
88832
  var failure = outcome === null || outcome === void 0 ? void 0 : outcome.failed.find(function (f) {
88530
88833
  return f.rowId === nodeId;
88531
88834
  });
88532
- if (failure) return {
88533
- state: 'rejected',
88534
- error: "the server rejected the write: ".concat(failure.errors.join('; ') || 'no reason given')
88535
- };
88835
+ if (failure) {
88836
+ // The server quotes a raw .NET pattern; an asset entry's text field is its media NAME (IDM caps it at 40 characters).
88837
+ var maxLength = patternLengthLimit(failure.errors.join(' '));
88838
+ var lengthNote = maxLength ? " \u2014 the media name holds at most ".concat(maxLength, " characters: shorten it, and run discardStagedChanges on this table first, because the refused entry stays staged in the cell") : '';
88839
+ return {
88840
+ state: 'rejected',
88841
+ error: "the server rejected the write: ".concat(failure.errors.join('; ') || 'no reason given').concat(lengthNote)
88842
+ };
88843
+ }
88536
88844
  if (outcome !== null && outcome !== void 0 && (_outcome$skipped = outcome.skipped) !== null && _outcome$skipped !== void 0 && _outcome$skipped.includes(nodeId)) return {
88537
88845
  state: 'skipped',
88538
88846
  error: SKIPPED_NOTE
@@ -89551,7 +89859,7 @@ function createMediaToolset(ctx) {
89551
89859
  toolNames: MEDIA_TOOL_NAMES,
89552
89860
  dispatch: function () {
89553
89861
  var _dispatch = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(name, input, signal) {
89554
- var args, notStartedNote, uploadOne, startedAt, results, remaining, _iterator, _step, _request$fileName, entry, request, fileName, failed, result, imageCount, host, approved, _startedAt, _results, _remaining, usage, _iterator2, _step2, _entry$fileName, _entry$prompt, raw, _entry, label, one, _failed, _args$mediaItemId, MODE_SYNONYMS, parseAssetMode, _args$keyColumn, _args$column, _topMode$mode, topMode, badEntryModes, batchEntries, invalidIds, mediaItemId, parsedMode, mode, _args$format, _args$fileName, _args$grid, _generated$canvasCm, storedStyle, response, fetched, recipe, _response, _fetched, active, _i, _Object$entries, _Object$entries$_i, key, value, generated, spec, inline, typeNo, format, extension, rawName, _fileName, uploaded, file, attachColumn, attachResult;
89862
+ var args, notStartedNote, _result$fileName, longNameNote, uploadOne, startedAt, results, remaining, _iterator, _step, _request$fileName, entry, request, fileName, failed, result, imageCount, host, approved, _startedAt, _results, _remaining, usage, _iterator2, _step2, _entry$fileName, _entry$prompt, raw, _entry, label, one, _failed, _args$mediaItemId, MODE_SYNONYMS, parseAssetMode, _args$keyColumn, _args$column, _topMode$mode, topMode, badEntryModes, batchEntries, invalidIds, mediaItemId, parsedMode, mode, _args$format, _args$fileName, _args$grid, _generated$canvasCm, storedStyle, response, fetched, recipe, _response, _fetched, active, _i, _Object$entries, _Object$entries$_i, key, value, generated, spec, inline, typeNo, format, extension, rawName, _fileName, uploaded, file, attachColumn, attachResult;
89555
89863
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
89556
89864
  while (1) switch (_context2.prev = _context2.next) {
89557
89865
  case 0:
@@ -89560,9 +89868,16 @@ function createMediaToolset(ctx) {
89560
89868
  return "".concat(signal !== null && signal !== void 0 && signal.aborted ? 'The turn was ABORTED' : 'TIME BUDGET reached', ": the ").concat(remaining.length, " entries in 'remaining' were NOT STARTED");
89561
89869
  };
89562
89870
  _context2.t0 = name;
89563
- _context2.next = _context2.t0 === 'uploadAsset' ? 5 : _context2.t0 === 'generateImageAsset' ? 48 : _context2.t0 === 'publishCatalogTestManifest' ? 99 : _context2.t0 === 'getAssetUrls' ? 100 : _context2.t0 === 'setAssetCell' ? 101 : _context2.t0 === 'generateArticleSvg' ? 129 : 229;
89871
+ _context2.next = _context2.t0 === 'uploadAsset' ? 5 : _context2.t0 === 'generateImageAsset' ? 49 : _context2.t0 === 'publishCatalogTestManifest' ? 100 : _context2.t0 === 'getAssetUrls' ? 101 : _context2.t0 === 'setAssetCell' ? 102 : _context2.t0 === 'generateArticleSvg' ? 130 : 230;
89564
89872
  break;
89565
89873
  case 5:
89874
+ // The upload takes any file name; an IDM asset cell refuses a media name over 40 characters later, in setAssetCell.
89875
+ longNameNote = function longNameNote(fileNames) {
89876
+ var tooLong = fileNames.filter(function (fileName) {
89877
+ return fileName.length > IDM_MEDIA_NAME_MAX;
89878
+ });
89879
+ return tooLong.length ? " NAME TOO LONG for an IDM asset cell (at most ".concat(IDM_MEDIA_NAME_MAX, " characters): ").concat(tooLong.join(', '), " \u2014 pass a shorter 'name' to setAssetCell.") : '';
89880
+ };
89566
89881
  uploadOne = /*#__PURE__*/function () {
89567
89882
  var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(request) {
89568
89883
  var resolved;
@@ -89603,65 +89918,65 @@ function createMediaToolset(ctx) {
89603
89918
  };
89604
89919
  }(); // BATCH: sequential on purpose — a parallel burst of three-request handshakes fails halfway.
89605
89920
  if (!Array.isArray(args.files)) {
89606
- _context2.next = 42;
89921
+ _context2.next = 43;
89607
89922
  break;
89608
89923
  }
89609
89924
  if (args.files.length) {
89610
- _context2.next = 9;
89925
+ _context2.next = 10;
89611
89926
  break;
89612
89927
  }
89613
89928
  return _context2.abrupt("return", {
89614
89929
  error: "'files' is empty — pass at least one {fileName, url|svg|base64} entry."
89615
89930
  });
89616
- case 9:
89931
+ case 10:
89617
89932
  // Stop before the bridge's hard timeout and hand the untouched rest back, or the receipt is lost while the files landed.
89618
89933
  startedAt = Date.now();
89619
89934
  results = [];
89620
89935
  remaining = [];
89621
89936
  _iterator = _createForOfIteratorHelper$h(args.files);
89622
- _context2.prev = 13;
89937
+ _context2.prev = 14;
89623
89938
  _iterator.s();
89624
- case 15:
89939
+ case 16:
89625
89940
  if ((_step = _iterator.n()).done) {
89626
- _context2.next = 32;
89941
+ _context2.next = 33;
89627
89942
  break;
89628
89943
  }
89629
89944
  entry = _step.value;
89630
89945
  request = entry !== null && entry !== void 0 ? entry : {};
89631
89946
  fileName = String((_request$fileName = request.fileName) !== null && _request$fileName !== void 0 ? _request$fileName : '').trim() || '(missing fileName)';
89632
89947
  if (!stopBatch(startedAt, TIME_BUDGET_MS, signal)) {
89633
- _context2.next = 22;
89948
+ _context2.next = 23;
89634
89949
  break;
89635
89950
  }
89636
89951
  remaining.push(fileName);
89637
- return _context2.abrupt("continue", 30);
89638
- case 22:
89952
+ return _context2.abrupt("continue", 31);
89953
+ case 23:
89639
89954
  _context2.t1 = results;
89640
89955
  _context2.t2 = _objectSpread$z;
89641
89956
  _context2.t3 = {
89642
89957
  fileName: fileName
89643
89958
  };
89644
- _context2.next = 27;
89959
+ _context2.next = 28;
89645
89960
  return uploadOne(request);
89646
- case 27:
89961
+ case 28:
89647
89962
  _context2.t4 = _context2.sent;
89648
89963
  _context2.t5 = (0, _context2.t2)(_context2.t3, _context2.t4);
89649
89964
  _context2.t1.push.call(_context2.t1, _context2.t5);
89650
- case 30:
89651
- _context2.next = 15;
89965
+ case 31:
89966
+ _context2.next = 16;
89652
89967
  break;
89653
- case 32:
89654
- _context2.next = 37;
89968
+ case 33:
89969
+ _context2.next = 38;
89655
89970
  break;
89656
- case 34:
89657
- _context2.prev = 34;
89658
- _context2.t6 = _context2["catch"](13);
89971
+ case 35:
89972
+ _context2.prev = 35;
89973
+ _context2.t6 = _context2["catch"](14);
89659
89974
  _iterator.e(_context2.t6);
89660
- case 37:
89661
- _context2.prev = 37;
89975
+ case 38:
89976
+ _context2.prev = 38;
89662
89977
  _iterator.f();
89663
- return _context2.finish(37);
89664
- case 40:
89978
+ return _context2.finish(38);
89979
+ case 41:
89665
89980
  failed = results.filter(function (r) {
89666
89981
  return r.error;
89667
89982
  });
@@ -89673,55 +89988,59 @@ function createMediaToolset(ctx) {
89673
89988
  }, remaining.length ? {
89674
89989
  remaining: remaining
89675
89990
  } : {}), {}, {
89676
- note: "".concat(results.length - failed.length, "/").concat(results.length, " uploaded.") + (failed.length ? ' The failed entries are listed with their reason — retry only those.' : '') + (remaining.length ? " ".concat(notStartedNote(remaining), " \u2014 re-call uploadAsset with only those. Everything in 'uploaded' is DONE; re-uploading it creates duplicates.") : '') + ' Assets are unused until referenced: write each mediaItemId into its asset column with setAssetCell.'
89991
+ note: "".concat(results.length - failed.length, "/").concat(results.length, " uploaded.") + (failed.length ? ' The failed entries are listed with their reason — retry only those.' : '') + (remaining.length ? " ".concat(notStartedNote(remaining), " \u2014 re-call uploadAsset with only those. Everything in 'uploaded' is DONE; re-uploading it creates duplicates.") : '') + ' Assets are unused until referenced: write each mediaItemId into its asset column with setAssetCell.' + longNameNote(results.filter(function (r) {
89992
+ return !r.error;
89993
+ }).map(function (r) {
89994
+ return String(r.fileName);
89995
+ }))
89677
89996
  }));
89678
- case 42:
89679
- _context2.next = 44;
89997
+ case 43:
89998
+ _context2.next = 45;
89680
89999
  return uploadOne(args);
89681
- case 44:
90000
+ case 45:
89682
90001
  result = _context2.sent;
89683
90002
  if (!('error' in result)) {
89684
- _context2.next = 47;
90003
+ _context2.next = 48;
89685
90004
  break;
89686
90005
  }
89687
90006
  return _context2.abrupt("return", result);
89688
- case 47:
90007
+ case 48:
89689
90008
  return _context2.abrupt("return", _objectSpread$z(_objectSpread$z({}, result), {}, {
89690
- note: 'Asset uploaded — reference it via setAssetCell (asset columns) using this mediaItemId. It is unused until referenced.'
90009
+ note: 'Asset uploaded — reference it via setAssetCell (asset columns) using this mediaItemId. It is unused until referenced.' + longNameNote([String((_result$fileName = result.fileName) !== null && _result$fileName !== void 0 ? _result$fileName : '')])
89691
90010
  }));
89692
- case 48:
90011
+ case 49:
89693
90012
  if (!(Array.isArray(args.batch) && !args.batch.length)) {
89694
- _context2.next = 50;
90013
+ _context2.next = 51;
89695
90014
  break;
89696
90015
  }
89697
90016
  return _context2.abrupt("return", {
89698
90017
  error: "'batch' is empty — pass at least one {prompt, fileName} entry."
89699
90018
  });
89700
- case 50:
90019
+ case 51:
89701
90020
  imageCount = Array.isArray(args.batch) ? args.batch.length : 1; // Unlike uploadAsset this is not free: every image is charged against the ORGANIZATION's AI budget and a
89702
90021
  // batch orders up to 50 in one call, so the only brake would otherwise be the service's 429. The bar is
89703
90022
  // about the SPEND, not about a write — the asset stays inert until setAssetCell references it — which is
89704
90023
  // why it is asked once for the whole call and names the number of images. A dryRun spends nothing (it
89705
90024
  // only returns the resolved prompt), so it asks for nothing and works without a table on screen.
89706
90025
  if (!(!ctx.autoApprove && !args.dryRun)) {
89707
- _context2.next = 60;
90026
+ _context2.next = 61;
89708
90027
  break;
89709
90028
  }
89710
90029
  host = findGrid(root);
89711
90030
  if (host) {
89712
- _context2.next = 55;
90031
+ _context2.next = 56;
89713
90032
  break;
89714
90033
  }
89715
90034
  return _context2.abrupt("return", {
89716
90035
  error: 'Generating images spends the organization’s AI budget and needs the user’s approval, and the approval bar lives on a table — ' + 'none is on screen. Ask the user to open a table view (or to enable auto-approve in the chat settings), then call again. ' + 'Nothing was generated.'
89717
90036
  });
89718
- case 55:
89719
- _context2.next = 57;
90037
+ case 56:
90038
+ _context2.next = 58;
89720
90039
  return host.requestAgentApproval(imageCount, "generateImageAsset: ".concat(imageCount, " image").concat(imageCount === 1 ? '' : 's', " (AI budget)"), signal);
89721
- case 57:
90040
+ case 58:
89722
90041
  approved = _context2.sent;
89723
90042
  if (approved) {
89724
- _context2.next = 60;
90043
+ _context2.next = 61;
89725
90044
  break;
89726
90045
  }
89727
90046
  return _context2.abrupt("return", {
@@ -89729,50 +90048,50 @@ function createMediaToolset(ctx) {
89729
90048
  applied: false,
89730
90049
  note: 'The user DECLINED — nothing was generated and no budget was spent. Do not retry; ask what to do instead.'
89731
90050
  });
89732
- case 60:
90051
+ case 61:
89733
90052
  if (!Array.isArray(args.batch)) {
89734
- _context2.next = 98;
90053
+ _context2.next = 99;
89735
90054
  break;
89736
90055
  }
89737
90056
  _startedAt = Date.now();
89738
90057
  _results = [];
89739
90058
  _remaining = [];
89740
90059
  _iterator2 = _createForOfIteratorHelper$h(args.batch);
89741
- _context2.prev = 65;
90060
+ _context2.prev = 66;
89742
90061
  _iterator2.s();
89743
- case 67:
90062
+ case 68:
89744
90063
  if ((_step2 = _iterator2.n()).done) {
89745
- _context2.next = 88;
90064
+ _context2.next = 89;
89746
90065
  break;
89747
90066
  }
89748
90067
  raw = _step2.value;
89749
90068
  _entry = raw !== null && raw !== void 0 ? raw : {};
89750
90069
  label = String((_entry$fileName = _entry.fileName) !== null && _entry$fileName !== void 0 ? _entry$fileName : '').trim() || String((_entry$prompt = _entry.prompt) !== null && _entry$prompt !== void 0 ? _entry$prompt : '').slice(0, 60) || '(unnamed)';
89751
90070
  if (!stopBatch(_startedAt, TIME_BUDGET_MS, signal)) {
89752
- _context2.next = 74;
90071
+ _context2.next = 75;
89753
90072
  break;
89754
90073
  }
89755
90074
  _remaining.push(label);
89756
- return _context2.abrupt("continue", 86);
89757
- case 74:
90075
+ return _context2.abrupt("continue", 87);
90076
+ case 75:
89758
90077
  // One throwing entry must not lose the receipts (and paid usage) of the images already generated.
89759
90078
  one = void 0;
89760
- _context2.prev = 75;
89761
- _context2.next = 78;
90079
+ _context2.prev = 76;
90080
+ _context2.next = 79;
89762
90081
  return generateImageAsset(root, _objectSpread$z(_objectSpread$z({}, args), {}, {
89763
90082
  batch: undefined
89764
90083
  }, _entry), signal);
89765
- case 78:
90084
+ case 79:
89766
90085
  one = _context2.sent;
89767
- _context2.next = 84;
90086
+ _context2.next = 85;
89768
90087
  break;
89769
- case 81:
89770
- _context2.prev = 81;
89771
- _context2.t7 = _context2["catch"](75);
90088
+ case 82:
90089
+ _context2.prev = 82;
90090
+ _context2.t7 = _context2["catch"](76);
89772
90091
  one = {
89773
90092
  error: _context2.t7 instanceof Error ? _context2.t7.message : String(_context2.t7)
89774
90093
  };
89775
- case 84:
90094
+ case 85:
89776
90095
  if (one.usage) {
89777
90096
  usage = one.usage;
89778
90097
  delete one.usage;
@@ -89780,21 +90099,21 @@ function createMediaToolset(ctx) {
89780
90099
  _results.push(_objectSpread$z({
89781
90100
  fileName: label
89782
90101
  }, one));
89783
- case 86:
89784
- _context2.next = 67;
90102
+ case 87:
90103
+ _context2.next = 68;
89785
90104
  break;
89786
- case 88:
89787
- _context2.next = 93;
90105
+ case 89:
90106
+ _context2.next = 94;
89788
90107
  break;
89789
- case 90:
89790
- _context2.prev = 90;
89791
- _context2.t8 = _context2["catch"](65);
90108
+ case 91:
90109
+ _context2.prev = 91;
90110
+ _context2.t8 = _context2["catch"](66);
89792
90111
  _iterator2.e(_context2.t8);
89793
- case 93:
89794
- _context2.prev = 93;
90112
+ case 94:
90113
+ _context2.prev = 94;
89795
90114
  _iterator2.f();
89796
- return _context2.finish(93);
89797
- case 96:
90115
+ return _context2.finish(94);
90116
+ case 97:
89798
90117
  _failed = _results.filter(function (r) {
89799
90118
  return r.error;
89800
90119
  });
@@ -89810,13 +90129,13 @@ function createMediaToolset(ctx) {
89810
90129
  } : {}), {}, {
89811
90130
  note: "".concat(_results.length - _failed.length, "/").concat(_results.length, " generated (usage = cumulative counters after the last one).") + (_failed.length ? ' Failed entries carry their reason — retry only those.' : '') + (_remaining.length ? " ".concat(notStartedNote(_remaining), " \u2014 re-call with only those; everything in 'generated' is DONE.") : '') + ' LOOK at the results before wiring (one contact sheet, not one review per file), then write them with setAssetCell cells.'
89812
90131
  }));
89813
- case 98:
89814
- return _context2.abrupt("return", generateImageAsset(root, args, signal));
89815
90132
  case 99:
89816
- return _context2.abrupt("return", publishCatalogTestManifest(root, args, signal));
90133
+ return _context2.abrupt("return", generateImageAsset(root, args, signal));
89817
90134
  case 100:
89818
- return _context2.abrupt("return", getAssetUrls(root, args, signal));
90135
+ return _context2.abrupt("return", publishCatalogTestManifest(root, args, signal));
89819
90136
  case 101:
90137
+ return _context2.abrupt("return", getAssetUrls(root, args, signal));
90138
+ case 102:
89820
90139
  // An unrecognized non-empty mode errors instead of silently APPENDING (the wrong write) — for the batch entries too.
89821
90140
  // Canonical names live in the same map as their synonyms, so the lookup is already typed.
89822
90141
  MODE_SYNONYMS = {
@@ -89839,26 +90158,26 @@ function createMediaToolset(ctx) {
89839
90158
  };
89840
90159
  }; // BULK: 'cells' turns N writes into ONE round-trip; entries inherit the top-level grid/column/mode.
89841
90160
  if (!Array.isArray(args.cells)) {
89842
- _context2.next = 119;
90161
+ _context2.next = 120;
89843
90162
  break;
89844
90163
  }
89845
90164
  if (args.cells.length) {
89846
- _context2.next = 106;
90165
+ _context2.next = 107;
89847
90166
  break;
89848
90167
  }
89849
90168
  return _context2.abrupt("return", {
89850
90169
  error: "'cells' is empty — pass at least one {keyValue, mediaItemId} entry."
89851
90170
  });
89852
- case 106:
90171
+ case 107:
89853
90172
  topMode = parseAssetMode(args.mode);
89854
90173
  if (!topMode.invalid) {
89855
- _context2.next = 109;
90174
+ _context2.next = 110;
89856
90175
  break;
89857
90176
  }
89858
90177
  return _context2.abrupt("return", {
89859
90178
  error: "mode must be 'append' (default), 'replace' or 'remove' \u2014 got '".concat(topMode.invalid, "'.")
89860
90179
  });
89861
- case 109:
90180
+ case 110:
89862
90181
  badEntryModes = args.cells.filter(function (cell) {
89863
90182
  return parseAssetMode(cell === null || cell === void 0 ? void 0 : cell.mode).invalid;
89864
90183
  }).map(function (cell) {
@@ -89866,13 +90185,13 @@ function createMediaToolset(ctx) {
89866
90185
  return "".concat((_cell$keyValue = cell === null || cell === void 0 ? void 0 : cell.keyValue) !== null && _cell$keyValue !== void 0 ? _cell$keyValue : '(missing keyValue)', ": '").concat(cell === null || cell === void 0 ? void 0 : cell.mode, "'");
89867
90186
  });
89868
90187
  if (!badEntryModes.length) {
89869
- _context2.next = 112;
90188
+ _context2.next = 113;
89870
90189
  break;
89871
90190
  }
89872
90191
  return _context2.abrupt("return", {
89873
90192
  error: "mode must be 'append' (default), 'replace' or 'remove' \u2014 invalid for: ".concat(badEntryModes.join(', '), ". Nothing was written.")
89874
90193
  });
89875
- case 112:
90194
+ case 113:
89876
90195
  batchEntries = args.cells.map(function (raw) {
89877
90196
  var _cell$keyValue2, _cell$mediaItemId;
89878
90197
  var cell = raw !== null && raw !== void 0 ? raw : {};
@@ -89892,47 +90211,47 @@ function createMediaToolset(ctx) {
89892
90211
  return e.keyValue || '(missing keyValue)';
89893
90212
  });
89894
90213
  if (!invalidIds.length) {
89895
- _context2.next = 116;
90214
+ _context2.next = 117;
89896
90215
  break;
89897
90216
  }
89898
90217
  return _context2.abrupt("return", {
89899
90218
  error: "mediaItemId must be a media item _id (uploadAsset returns it) \u2014 invalid for: ".concat(invalidIds.join(', '), ". Nothing was written.")
89900
90219
  });
89901
- case 116:
89902
- _context2.next = 118;
90220
+ case 117:
90221
+ _context2.next = 119;
89903
90222
  return writeAssetCellsBatch(root, args.grid, String((_args$keyColumn = args.keyColumn) !== null && _args$keyColumn !== void 0 ? _args$keyColumn : ''), String((_args$column = args.column) !== null && _args$column !== void 0 ? _args$column : ''), (_topMode$mode = topMode.mode) !== null && _topMode$mode !== void 0 ? _topMode$mode : 'append', batchEntries, ctx.autoApprove ? undefined : function (entry, stageable) {
89904
90223
  return entry.requestAgentApproval(stageable, "setAssetCell: ".concat(stageable, " cells"), signal);
89905
90224
  }, signal);
89906
- case 118:
89907
- return _context2.abrupt("return", _context2.sent);
89908
90225
  case 119:
90226
+ return _context2.abrupt("return", _context2.sent);
90227
+ case 120:
89909
90228
  mediaItemId = String((_args$mediaItemId = args.mediaItemId) !== null && _args$mediaItemId !== void 0 ? _args$mediaItemId : '').trim();
89910
90229
  parsedMode = parseAssetMode(args.mode);
89911
90230
  if (!parsedMode.invalid) {
89912
- _context2.next = 123;
90231
+ _context2.next = 124;
89913
90232
  break;
89914
90233
  }
89915
90234
  return _context2.abrupt("return", {
89916
90235
  error: "mode must be 'append' (default), 'replace' or 'remove' \u2014 got '".concat(args.mode, "'.")
89917
90236
  });
89918
- case 123:
90237
+ case 124:
89919
90238
  mode = parsedMode.mode; // Media item _ids are nanoids; legacy items may carry 24-hex ObjectIds — accept both.
89920
90239
  if (/^[A-Za-z0-9_-]{10,64}$/.test(mediaItemId)) {
89921
- _context2.next = 126;
90240
+ _context2.next = 127;
89922
90241
  break;
89923
90242
  }
89924
90243
  return _context2.abrupt("return", {
89925
90244
  error: 'mediaItemId must be a media item _id — uploadAsset returns it.'
89926
90245
  });
89927
- case 126:
90246
+ case 127:
89928
90247
  if (!(!args.keyColumn || args.keyValue === undefined || !args.column)) {
89929
- _context2.next = 128;
90248
+ _context2.next = 129;
89930
90249
  break;
89931
90250
  }
89932
90251
  return _context2.abrupt("return", {
89933
90252
  error: 'keyColumn, keyValue and column are required (the row is addressed by keyColumn=keyValue).'
89934
90253
  });
89935
- case 128:
90254
+ case 129:
89936
90255
  return _context2.abrupt("return", writeAssetCell(root, {
89937
90256
  grid: args.grid,
89938
90257
  keyColumn: String(args.keyColumn),
@@ -89947,122 +90266,122 @@ function createMediaToolset(ctx) {
89947
90266
  mode: mode !== null && mode !== void 0 ? mode : 'append',
89948
90267
  approve: agentApprove("setAssetCell: ".concat(args.column, " ").concat(mode !== null && mode !== void 0 ? mode : 'append', " ").concat(mediaItemId), signal)
89949
90268
  }));
89950
- case 129:
90269
+ case 130:
89951
90270
  if (!args.styleUrl) {
89952
- _context2.next = 147;
90271
+ _context2.next = 148;
89953
90272
  break;
89954
90273
  }
89955
- _context2.prev = 130;
89956
- _context2.next = 133;
90274
+ _context2.prev = 131;
90275
+ _context2.next = 134;
89957
90276
  return fetch(String(args.styleUrl), {
89958
90277
  signal: signal
89959
90278
  });
89960
- case 133:
90279
+ case 134:
89961
90280
  response = _context2.sent;
89962
90281
  if (response.ok) {
89963
- _context2.next = 136;
90282
+ _context2.next = 137;
89964
90283
  break;
89965
90284
  }
89966
90285
  return _context2.abrupt("return", {
89967
90286
  error: "styleUrl fetch failed (".concat(response.status, ") \u2014 is the URL a reachable style-config JSON (media item)?")
89968
90287
  });
89969
- case 136:
89970
- _context2.next = 138;
90288
+ case 137:
90289
+ _context2.next = 139;
89971
90290
  return response.json();
89972
- case 138:
90291
+ case 139:
89973
90292
  fetched = _context2.sent;
89974
90293
  if (!(!fetched || _typeof(fetched) !== 'object' || Array.isArray(fetched))) {
89975
- _context2.next = 141;
90294
+ _context2.next = 142;
89976
90295
  break;
89977
90296
  }
89978
90297
  return _context2.abrupt("return", {
89979
90298
  error: 'styleUrl JSON is not a style config — expected an object like {parts: {...}, cushionMode: "..."}.'
89980
90299
  });
89981
- case 141:
90300
+ case 142:
89982
90301
  storedStyle = fetched;
89983
- _context2.next = 147;
90302
+ _context2.next = 148;
89984
90303
  break;
89985
- case 144:
89986
- _context2.prev = 144;
89987
- _context2.t9 = _context2["catch"](130);
90304
+ case 145:
90305
+ _context2.prev = 145;
90306
+ _context2.t9 = _context2["catch"](131);
89988
90307
  return _context2.abrupt("return", {
89989
90308
  error: "styleUrl fetch failed (".concat(_context2.t9 instanceof Error ? _context2.t9.message : String(_context2.t9), ") \u2014 is the URL reachable from the browser (CORS)?")
89990
90309
  });
89991
- case 147:
90310
+ case 148:
89992
90311
  if (!args.recipeUrl) {
89993
- _context2.next = 167;
90312
+ _context2.next = 168;
89994
90313
  break;
89995
90314
  }
89996
- _context2.prev = 148;
89997
- _context2.next = 151;
90315
+ _context2.prev = 149;
90316
+ _context2.next = 152;
89998
90317
  return fetch(String(args.recipeUrl), {
89999
90318
  signal: signal
90000
90319
  });
90001
- case 151:
90320
+ case 152:
90002
90321
  _response = _context2.sent;
90003
90322
  if (_response.ok) {
90004
- _context2.next = 154;
90323
+ _context2.next = 155;
90005
90324
  break;
90006
90325
  }
90007
90326
  return _context2.abrupt("return", {
90008
90327
  error: "recipeUrl fetch failed (".concat(_response.status, ") \u2014 is the URL a reachable recipe JSON (media item)?")
90009
90328
  });
90010
- case 154:
90011
- _context2.next = 156;
90329
+ case 155:
90330
+ _context2.next = 157;
90012
90331
  return _response.json();
90013
- case 156:
90332
+ case 157:
90014
90333
  _fetched = _context2.sent;
90015
90334
  if (isArticleSvgRecipe(_fetched)) {
90016
- _context2.next = 159;
90335
+ _context2.next = 160;
90017
90336
  break;
90018
90337
  }
90019
90338
  return _context2.abrupt("return", {
90020
90339
  error: 'recipeUrl JSON is not a recipe — expected {description?, spec: {…}, style?}.'
90021
90340
  });
90022
- case 159:
90341
+ case 160:
90023
90342
  recipe = _fetched;
90024
- _context2.next = 165;
90343
+ _context2.next = 166;
90025
90344
  break;
90026
- case 162:
90027
- _context2.prev = 162;
90028
- _context2.t10 = _context2["catch"](148);
90345
+ case 163:
90346
+ _context2.prev = 163;
90347
+ _context2.t10 = _context2["catch"](149);
90029
90348
  return _context2.abrupt("return", {
90030
90349
  error: "recipeUrl fetch failed (".concat(_context2.t10 instanceof Error ? _context2.t10.message : String(_context2.t10), ") \u2014 is the URL reachable from the browser (CORS)?")
90031
90350
  });
90032
- case 165:
90033
- _context2.next = 177;
90351
+ case 166:
90352
+ _context2.next = 178;
90034
90353
  break;
90035
- case 167:
90354
+ case 168:
90036
90355
  if (!(typeof args.recipe === 'string')) {
90037
- _context2.next = 173;
90356
+ _context2.next = 174;
90038
90357
  break;
90039
90358
  }
90040
90359
  recipe = BUILT_IN_RECIPES[args.recipe];
90041
90360
  if (recipe) {
90042
- _context2.next = 171;
90361
+ _context2.next = 172;
90043
90362
  break;
90044
90363
  }
90045
90364
  return _context2.abrupt("return", {
90046
90365
  error: "Unknown built-in recipe '".concat(args.recipe, "' \u2014 available: ").concat(Object.keys(BUILT_IN_RECIPES).join(', '), ".")
90047
90366
  });
90048
- case 171:
90049
- _context2.next = 177;
90367
+ case 172:
90368
+ _context2.next = 178;
90050
90369
  break;
90051
- case 173:
90370
+ case 174:
90052
90371
  if (!(args.recipe !== undefined)) {
90053
- _context2.next = 177;
90372
+ _context2.next = 178;
90054
90373
  break;
90055
90374
  }
90056
90375
  if (isArticleSvgRecipe(args.recipe)) {
90057
- _context2.next = 176;
90376
+ _context2.next = 177;
90058
90377
  break;
90059
90378
  }
90060
90379
  return _context2.abrupt("return", {
90061
90380
  error: 'recipe must be a built-in name or {description?, spec: {…}, style?}.'
90062
90381
  });
90063
- case 176:
90064
- recipe = args.recipe;
90065
90382
  case 177:
90383
+ recipe = args.recipe;
90384
+ case 178:
90066
90385
  if (recipe) {
90067
90386
  active = recipe;
90068
90387
  if (active.style && args.style === undefined && !storedStyle) args.style = active.style;
@@ -90078,52 +90397,52 @@ function createMediaToolset(ctx) {
90078
90397
  }
90079
90398
  }
90080
90399
  if (!Array.isArray(args.batch)) {
90081
- _context2.next = 182;
90400
+ _context2.next = 183;
90082
90401
  break;
90083
90402
  }
90084
- _context2.next = 181;
90403
+ _context2.next = 182;
90085
90404
  return generateArticleSvgBatch(root, args, args.batch, storedStyle, signal);
90086
- case 181:
90087
- return _context2.abrupt("return", _context2.sent);
90088
90405
  case 182:
90089
- _context2.prev = 182;
90406
+ return _context2.abrupt("return", _context2.sent);
90407
+ case 183:
90408
+ _context2.prev = 183;
90090
90409
  spec = _objectSpread$z({}, args);
90091
90410
  if (storedStyle) {
90092
90411
  inline = _typeof(args.style) === 'object' && args.style ? args.style : undefined;
90093
90412
  spec.style = mergeArticleSvgStyles(storedStyle, inline);
90094
90413
  }
90095
90414
  generated = buildArticleTopViewSvg(spec);
90096
- _context2.next = 191;
90415
+ _context2.next = 192;
90097
90416
  break;
90098
- case 188:
90099
- _context2.prev = 188;
90100
- _context2.t11 = _context2["catch"](182);
90417
+ case 189:
90418
+ _context2.prev = 189;
90419
+ _context2.t11 = _context2["catch"](183);
90101
90420
  return _context2.abrupt("return", {
90102
90421
  error: _context2.t11 instanceof Error ? _context2.t11.message : String(_context2.t11)
90103
90422
  });
90104
- case 191:
90423
+ case 192:
90105
90424
  typeNo = args.typeNo === undefined ? undefined : String(args.typeNo); // 'jpg' = rasterized article-list picture (white background); 'svg' = planner top view.
90106
90425
  format = String((_args$format = args.format) !== null && _args$format !== void 0 ? _args$format : 'svg').trim().toLowerCase();
90107
90426
  if (['svg', 'jpg'].includes(format)) {
90108
- _context2.next = 195;
90427
+ _context2.next = 196;
90109
90428
  break;
90110
90429
  }
90111
90430
  return _context2.abrupt("return", {
90112
90431
  error: "format must be 'svg' (planner top view) or 'jpg' (article-list picture) \u2014 got '".concat(args.format, "'.")
90113
90432
  });
90114
- case 195:
90433
+ case 196:
90115
90434
  extension = format === 'jpg' ? '.jpg' : '.svg';
90116
90435
  rawName = String((_args$fileName = args.fileName) !== null && _args$fileName !== void 0 ? _args$fileName : typeNo ? "top-".concat(typeNo).concat(extension) : "top-view".concat(extension));
90117
90436
  _fileName = rawName.toLowerCase().endsWith(extension) ? rawName : "".concat(rawName.replace(/\.(svg|jpe?g)$/i, '')).concat(extension);
90118
- _context2.prev = 198;
90437
+ _context2.prev = 199;
90119
90438
  if (!(format === 'jpg')) {
90120
- _context2.next = 210;
90439
+ _context2.next = 211;
90121
90440
  break;
90122
90441
  }
90123
90442
  _context2.t13 = File;
90124
- _context2.next = 203;
90443
+ _context2.next = 204;
90125
90444
  return svgToJpegBlob(generated.svg, Math.max(64, Math.min(4096, Number(args.jpgSizePx) || 1024)));
90126
- case 203:
90445
+ case 204:
90127
90446
  _context2.t14 = _context2.sent;
90128
90447
  _context2.t15 = [_context2.t14];
90129
90448
  _context2.t16 = _fileName;
@@ -90131,31 +90450,31 @@ function createMediaToolset(ctx) {
90131
90450
  type: 'image/jpeg'
90132
90451
  };
90133
90452
  _context2.t12 = new _context2.t13(_context2.t15, _context2.t16, _context2.t17);
90134
- _context2.next = 211;
90453
+ _context2.next = 212;
90135
90454
  break;
90136
- case 210:
90455
+ case 211:
90137
90456
  _context2.t12 = new File([generated.svg], _fileName, {
90138
90457
  type: 'image/svg+xml'
90139
90458
  });
90140
- case 211:
90459
+ case 212:
90141
90460
  file = _context2.t12;
90142
- _context2.next = 214;
90461
+ _context2.next = 215;
90143
90462
  return uploadToMediaService(root, file, _fileName, undefined, signal);
90144
- case 214:
90463
+ case 215:
90145
90464
  uploaded = _context2.sent;
90146
- _context2.next = 220;
90465
+ _context2.next = 221;
90147
90466
  break;
90148
- case 217:
90149
- _context2.prev = 217;
90150
- _context2.t18 = _context2["catch"](198);
90467
+ case 218:
90468
+ _context2.prev = 218;
90469
+ _context2.t18 = _context2["catch"](199);
90151
90470
  return _context2.abrupt("return", {
90152
90471
  error: _context2.t18 instanceof Error ? _context2.t18.message : String(_context2.t18)
90153
90472
  });
90154
- case 220:
90473
+ case 221:
90155
90474
  // Canvas/list pictures belong in 'images'; the planner top view in 'svgs'.
90156
90475
  attachColumn = args.column ? String(args.column) : format === 'jpg' ? 'images' : 'svgs';
90157
90476
  if (!(!typeNo || args.attach === false)) {
90158
- _context2.next = 223;
90477
+ _context2.next = 224;
90159
90478
  break;
90160
90479
  }
90161
90480
  return _context2.abrupt("return", _objectSpread$z(_objectSpread$z(_objectSpread$z({}, uploaded), format === 'svg' && args.returnSvg !== false ? {
@@ -90167,8 +90486,8 @@ function createMediaToolset(ctx) {
90167
90486
  attached: false,
90168
90487
  note: "".concat(format.toUpperCase(), " generated + uploaded but NOT attached \u2014 setAssetCell it onto an item's ").concat(attachColumn, " column, or pass typeNo to attach directly.")
90169
90488
  }));
90170
- case 223:
90171
- _context2.next = 225;
90489
+ case 224:
90490
+ _context2.next = 226;
90172
90491
  return writeAssetCell(root, {
90173
90492
  grid: (_args$grid = args.grid) !== null && _args$grid !== void 0 ? _args$grid : 'items',
90174
90493
  keyColumn: 'typeNo',
@@ -90183,10 +90502,10 @@ function createMediaToolset(ctx) {
90183
90502
  mode: args.mode === 'replace' || args.mode === 'remove' ? args.mode : 'append',
90184
90503
  approve: agentApprove("generateArticleSvg \u2192 ".concat(typeNo, " (").concat(attachColumn, ")"), signal)
90185
90504
  });
90186
- case 225:
90505
+ case 226:
90187
90506
  attachResult = _context2.sent;
90188
90507
  if (!(attachResult.error || attachResult.applied === false)) {
90189
- _context2.next = 228;
90508
+ _context2.next = 229;
90190
90509
  break;
90191
90510
  }
90192
90511
  return _context2.abrupt("return", _objectSpread$z(_objectSpread$z(_objectSpread$z({}, uploaded), {}, {
@@ -90194,7 +90513,7 @@ function createMediaToolset(ctx) {
90194
90513
  }, attachResult), {}, {
90195
90514
  note: "".concat(format.toUpperCase(), " uploaded, but attaching to the item failed \u2014 the asset exists; fix the attach and setAssetCell it.")
90196
90515
  }));
90197
- case 228:
90516
+ case 229:
90198
90517
  return _context2.abrupt("return", {
90199
90518
  mediaItemId: uploaded.mediaItemId,
90200
90519
  url: uploaded.url,
@@ -90204,13 +90523,13 @@ function createMediaToolset(ctx) {
90204
90523
  attached: true,
90205
90524
  note: format === 'svg' ? "SVG attached to the item's svgs list. svgs[0] is the planner's TOP VIEW — check order if the item had SVGs before. Verify: select the article, then getMediaInfo/getDockingInfo." : "JPG attached to the item's ".concat(attachColumn, " list (article-list picture). For a serie-uniform scale, reuse canvasCm=").concat((_generated$canvasCm = generated.canvasCm) !== null && _generated$canvasCm !== void 0 ? _generated$canvasCm : '—', " on every article of the serie.")
90206
90525
  });
90207
- case 229:
90208
- throw new Error("Unknown media tool: ".concat(name));
90209
90526
  case 230:
90527
+ throw new Error("Unknown media tool: ".concat(name));
90528
+ case 231:
90210
90529
  case "end":
90211
90530
  return _context2.stop();
90212
90531
  }
90213
- }, _callee2, null, [[13, 34, 37, 40], [65, 90, 93, 96], [75, 81], [130, 144], [148, 162], [182, 188], [198, 217]]);
90532
+ }, _callee2, null, [[14, 35, 38, 41], [66, 91, 94, 97], [76, 82], [131, 145], [149, 163], [183, 189], [199, 218]]);
90214
90533
  }));
90215
90534
  function dispatch(_x43, _x44, _x45) {
90216
90535
  return _dispatch.apply(this, arguments);
@@ -90234,7 +90553,7 @@ var hasPlannedArticle = function hasPlannedArticle(planner) {
90234
90553
  return Object.keys((_planner$getDivaArtic = planner.getDivaArticles()) !== null && _planner$getDivaArtic !== void 0 ? _planner$getDivaArtic : {}).length > 0;
90235
90554
  };
90236
90555
  var DivaAgent = function DivaAgent(_ref) {
90237
- var _findRegisteredTool, _registeredTool$eleme, _registeredTool$eleme2, _registeredTool$param, _registeredTool$eleme3, _root$i18n$language, _root$navigationState, _core$state$organizat, _core$state$organizat2, _root$navigationState2, _catalogMatch$;
90556
+ var _findRegisteredTool, _registeredTool$eleme, _registeredTool$eleme2, _registeredTool$param, _registeredTool$eleme3, _root$i18n$language, _root$navigationState3, _core$state$organizat, _core$state$organizat2, _root$navigationState4, _catalogMatch$;
90238
90557
  var tool = _ref.tool;
90239
90558
  var root = useStore();
90240
90559
  var core = useDivaCore();
@@ -90286,6 +90605,15 @@ var DivaAgent = function DivaAgent(_ref) {
90286
90605
  _useState2 = _slicedToArray(_useState, 2),
90287
90606
  initError = _useState2[0],
90288
90607
  setInitError = _useState2[1];
90608
+ /** The agent panel: clicks and keys inside it do not stop the reload's selection restore. */
90609
+ var panelRef = useRef(null);
90610
+ /** An agent call picked a serie or article: a running reload restore must not revert it. */
90611
+ var agentSelected = useRef(false);
90612
+ /** A reload restore is running — the automatic 'Continue.' waits for it, its turn starts on the restored article. */
90613
+ var _useState3 = useState(false),
90614
+ _useState4 = _slicedToArray(_useState3, 2),
90615
+ restoringSelection = _useState4[0],
90616
+ setRestoringSelection = _useState4[1];
90289
90617
 
90290
90618
  // Protect the instance the chat is working on from LRU eviction (eviction destroys it).
90291
90619
  useEffect(function () {
@@ -90296,10 +90624,22 @@ var DivaAgent = function DivaAgent(_ref) {
90296
90624
  };
90297
90625
  }, [key]);
90298
90626
 
90627
+ // Read LIVE per call from the toolbar store (the same source listSeries reports) — the render-time
90628
+ // serie/item would go stale in old closures; the guard in the catalog toolset compares this against
90629
+ // the article the planner instance actually serves.
90630
+ var getExpectedSelection = useCallback(function () {
90631
+ var _findRegisteredTool2, _live$elementProps, _live$elementProps2;
90632
+ var live = (_findRegisteredTool2 = findRegisteredTool()) !== null && _findRegisteredTool2 !== void 0 ? _findRegisteredTool2 : tool;
90633
+ return {
90634
+ serieNo: (_live$elementProps = live.elementProps) === null || _live$elementProps === void 0 || (_live$elementProps = _live$elementProps.serie) === null || _live$elementProps === void 0 ? void 0 : _live$elementProps.serieNo,
90635
+ itemTypeNo: (_live$elementProps2 = live.elementProps) === null || _live$elementProps2 === void 0 || (_live$elementProps2 = _live$elementProps2.item) === null || _live$elementProps2 === void 0 ? void 0 : _live$elementProps2.typeNo
90636
+ };
90637
+ }, [findRegisteredTool, tool]);
90638
+
90299
90639
  // Selection + navigation/table toolsets, built per turn (auto-approve skips the approval bar).
90300
90640
  var extraToolsets = useCallback(function (settings) {
90301
90641
  var _tool$elementProps;
90302
- var base = createBackofficeToolset({
90642
+ var selection = createBackofficeToolset({
90303
90643
  parameters: liveParameters,
90304
90644
  elementProps: (_tool$elementProps = tool.elementProps) !== null && _tool$elementProps !== void 0 ? _tool$elementProps : {},
90305
90645
  apiConfig: root.configurationStore.apiConfig,
@@ -90308,7 +90648,7 @@ var DivaAgent = function DivaAgent(_ref) {
90308
90648
  // Resolved when the TOOL RUNS, from the toolbar store: a captured value would keep naming the previous
90309
90649
  // catalog and its setters. No registered tool = the current view has no binding, so no fallback.
90310
90650
  getBinding: function getBinding() {
90311
- var _live$parameters, _live$elementProps;
90651
+ var _live$parameters, _live$elementProps3;
90312
90652
  var live = findRegisteredTool();
90313
90653
  if (!live) return undefined;
90314
90654
  var params = (_live$parameters = live.parameters) !== null && _live$parameters !== void 0 ? _live$parameters : {};
@@ -90321,7 +90661,7 @@ var DivaAgent = function DivaAgent(_ref) {
90321
90661
  routeCatalogId: routeId
90322
90662
  })
90323
90663
  }),
90324
- elementProps: (_live$elementProps = live.elementProps) !== null && _live$elementProps !== void 0 ? _live$elementProps : {}
90664
+ elementProps: (_live$elementProps3 = live.elementProps) !== null && _live$elementProps3 !== void 0 ? _live$elementProps3 : {}
90325
90665
  };
90326
90666
  }
90327
90667
  });
@@ -90329,7 +90669,8 @@ var DivaAgent = function DivaAgent(_ref) {
90329
90669
  root: root,
90330
90670
  catalogId: catalogId,
90331
90671
  packageId: packageId,
90332
- autoApprove: !!settings.autoApprove
90672
+ autoApprove: !!settings.autoApprove,
90673
+ getSelection: getExpectedSelection
90333
90674
  });
90334
90675
  var media = createMediaToolset({
90335
90676
  root: root,
@@ -90339,10 +90680,50 @@ var DivaAgent = function DivaAgent(_ref) {
90339
90680
  root: root,
90340
90681
  autoApprove: !!settings.autoApprove
90341
90682
  });
90683
+ var base = settings.forRestore ? selection : _objectSpread$y(_objectSpread$y({}, selection), {}, {
90684
+ dispatch: function dispatch(name, input, signal, onProgress) {
90685
+ if (name === 'selectSerie' || name === 'selectItem') agentSelected.current = true;
90686
+ return selection.dispatch(name, input, signal, onProgress);
90687
+ }
90688
+ });
90342
90689
  return [mergeToolsets(base, [navigation, media, content])];
90343
90690
  },
90344
90691
  // liveParameters/catalogId track the ROUTE so the toolsets are rebuilt when navigation moves catalog.
90345
- [tool, language, liveParameters, catalogId, packageId]);
90692
+ [tool, language, liveParameters, catalogId, packageId, getExpectedSelection]);
90693
+
90694
+ // A reloadPage call left the view's serie/article behind: re-apply it, so the planner comes back on the same article.
90695
+ // Not aborted on cleanup — StrictMode runs this twice, and only the first run finds the stored selection. It stops once
90696
+ // the user clicks or types outside this panel (they may be picking a serie or article themselves), an agent call picks
90697
+ // a serie or article, or the user leaves the view.
90698
+ useEffect(function () {
90699
+ var _root$navigationState;
90700
+ var path = (_root$navigationState = root.navigationState.path) !== null && _root$navigationState !== void 0 ? _root$navigationState : '';
90701
+ var target = takeReloadSelection(path);
90702
+ if (!target) return;
90703
+ var _extraToolsets = extraToolsets({
90704
+ forRestore: true
90705
+ }),
90706
+ _extraToolsets2 = _slicedToArray(_extraToolsets, 1),
90707
+ toolset = _extraToolsets2[0];
90708
+ var userActed = false;
90709
+ var onUserInput = function onUserInput(event) {
90710
+ var _panelRef$current;
90711
+ if (!(event.target instanceof Node && (_panelRef$current = panelRef.current) !== null && _panelRef$current !== void 0 && _panelRef$current.contains(event.target))) userActed = true;
90712
+ };
90713
+ window.addEventListener('pointerdown', onUserInput, true);
90714
+ window.addEventListener('keydown', onUserInput, true);
90715
+ setRestoringSelection(true);
90716
+ restoreReloadSelection(toolset, target, getExpectedSelection, undefined, function () {
90717
+ var _root$navigationState2;
90718
+ return userActed || agentSelected.current || ((_root$navigationState2 = root.navigationState.path) !== null && _root$navigationState2 !== void 0 ? _root$navigationState2 : '') !== path;
90719
+ })["catch"](function (e) {
90720
+ return LOG$5.error(e);
90721
+ })["finally"](function () {
90722
+ window.removeEventListener('pointerdown', onUserInput, true);
90723
+ window.removeEventListener('keydown', onUserInput, true);
90724
+ setRestoringSelection(false);
90725
+ });
90726
+ }, []);
90346
90727
  var buildPlanner = /*#__PURE__*/function () {
90347
90728
  var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(carried) {
90348
90729
  return _regeneratorRuntime.wrap(function _callee$(_context) {
@@ -90468,7 +90849,7 @@ var DivaAgent = function DivaAgent(_ref) {
90468
90849
 
90469
90850
  // Hold the automatic 'Continue.' until an agent-triggered navigation lands; the timeout is the safety net.
90470
90851
  var pendingNav = pendingAgentNavigation.get();
90471
- var currentPath = (_root$navigationState = root.navigationState.path) === null || _root$navigationState === void 0 ? void 0 : _root$navigationState.replace(/^\//, '');
90852
+ var currentPath = (_root$navigationState3 = root.navigationState.path) === null || _root$navigationState3 === void 0 ? void 0 : _root$navigationState3.replace(/^\//, '');
90472
90853
  useEffect(function () {
90473
90854
  if (pendingNav && currentPath === pendingNav) pendingAgentNavigation.set(undefined);
90474
90855
  }, [pendingNav, currentPath]);
@@ -90508,18 +90889,6 @@ var DivaAgent = function DivaAgent(_ref) {
90508
90889
  return root.webplannerInstanceStore.active;
90509
90890
  }, [root]);
90510
90891
 
90511
- // Read LIVE per call from the toolbar store (the same source listSeries reports) — the render-time
90512
- // serie/item would go stale in old closures; the guard in the catalog toolset compares this against
90513
- // the article the planner instance actually serves.
90514
- var getExpectedSelection = useCallback(function () {
90515
- var _findRegisteredTool2, _live$elementProps2, _live$elementProps3;
90516
- var live = (_findRegisteredTool2 = findRegisteredTool()) !== null && _findRegisteredTool2 !== void 0 ? _findRegisteredTool2 : tool;
90517
- return {
90518
- serieNo: (_live$elementProps2 = live.elementProps) === null || _live$elementProps2 === void 0 || (_live$elementProps2 = _live$elementProps2.serie) === null || _live$elementProps2 === void 0 ? void 0 : _live$elementProps2.serieNo,
90519
- itemTypeNo: (_live$elementProps3 = live.elementProps) === null || _live$elementProps3 === void 0 || (_live$elementProps3 = _live$elementProps3.item) === null || _live$elementProps3 === void 0 ? void 0 : _live$elementProps3.typeNo
90520
- };
90521
- }, [findRegisteredTool, tool]);
90522
-
90523
90892
  // Clicked diva:// entity links in agent answers → navigate + highlight the row.
90524
90893
  var onEntityLink = useCallback(function (href) {
90525
90894
  void showEntityFromLink(root, href)["catch"](function (e) {
@@ -90530,7 +90899,7 @@ var DivaAgent = function DivaAgent(_ref) {
90530
90899
 
90531
90900
  // Chat pool is keyed per organization; the catalog/package context is only a TAG on each conversation.
90532
90901
  var contextKey = "organization:".concat((_core$state$organizat = (_core$state$organizat2 = core.state.organization) === null || _core$state$organizat2 === void 0 ? void 0 : _core$state$organizat2._id) !== null && _core$state$organizat !== void 0 ? _core$state$organizat : 'unknown');
90533
- var navPath = (_root$navigationState2 = root.navigationState.path) !== null && _root$navigationState2 !== void 0 ? _root$navigationState2 : '';
90902
+ var navPath = (_root$navigationState4 = root.navigationState.path) !== null && _root$navigationState4 !== void 0 ? _root$navigationState4 : '';
90534
90903
  var packageMatch = navPath.match(/^\/?packages\/([^/]+)/);
90535
90904
  var catalogMatch = navPath.match(/^\/?catalogs\/([^/]+)/);
90536
90905
  var contextTag = packageMatch ? "package:".concat(packageMatch[1]) : catalogMatch ? "catalog:".concat(catalogMatch[1]) : catalogId ? "catalog:".concat(catalogId) : undefined;
@@ -90549,6 +90918,7 @@ var DivaAgent = function DivaAgent(_ref) {
90549
90918
  errorCode: "BACKO_0005",
90550
90919
  children: /*#__PURE__*/jsx("div", {
90551
90920
  className: wrapper$1,
90921
+ ref: panelRef,
90552
90922
  children: /*#__PURE__*/jsx(AgentBridgeStandalone, {
90553
90923
  divaWebPlanner: planner,
90554
90924
  plannerInitError: initError,
@@ -90572,6 +90942,7 @@ var DivaAgent = function DivaAgent(_ref) {
90572
90942
  errorCode: "BACKO_0005",
90573
90943
  children: /*#__PURE__*/jsxs("div", {
90574
90944
  className: wrapper$1,
90945
+ ref: panelRef,
90575
90946
  children: [initError && /*#__PURE__*/jsxs("div", {
90576
90947
  className: empty,
90577
90948
  children: [t('backoffice.divaAgent.initError'), typeof initError === 'string' && initError !== 'unknown' && /*#__PURE__*/jsx("div", {
@@ -90593,7 +90964,7 @@ var DivaAgent = function DivaAgent(_ref) {
90593
90964
  contextKey: contextKey,
90594
90965
  contextTag: contextTag,
90595
90966
  contextLabel: contextLabel,
90596
- readyForAutoContinue: (!serie || !!planner || !!initError) && !pendingNav,
90967
+ readyForAutoContinue: (!serie || !!planner || !!initError) && !pendingNav && !restoringSelection,
90597
90968
  onEntityLink: onEntityLink,
90598
90969
  enableBridge: mcpPermitted,
90599
90970
  style: {
@@ -90904,15 +91275,6 @@ function ToolElement(_ref3) {
90904
91275
  });
90905
91276
  }
90906
91277
 
90907
- /**
90908
- * Where the editors lived in the backoffice (`/backoffice/catalogs/idmeditor/…`). The Data Engine mounts them at its
90909
- * root instead; old links under this prefix are redirected to the same page there.
90910
- */
90911
- var LEGACY_EDITOR_ROUTE_BASE = 'catalogs/idmeditor';
90912
-
90913
- /** Router base of the Data Engine component. */
90914
- var DATA_ENGINE_BASENAME = '/dataengine';
90915
-
90916
91278
  /**
90917
91279
  * Opens the Data Engine at the page a legacy backoffice link (`/backoffice/catalogs/idmeditor/…`) names.
90918
91280
  * Such links live on in support tickets and bookmarks; the Data Engine mounts the editors at its root, so the