@platforma-open/milaboratories.repertoire-mutation-heatmap.block 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,148 +1,184 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
23
- //#endregion
24
- //#region ../kind/dist/package.js
25
- var name = "@platforma-open/milaboratories.repertoire-mutation-heatmap.kind";
26
- var version$1 = "1.0.0";
27
- //#endregion
28
- //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/params.js
1
+ import { r as __toESM, t as __commonJSMin } from "./rolldown-runtime-DC62tzP2.js";
2
+ //#region ../model/dist/chart-state.js
29
3
  /**
30
- * Establish that a value is an object whose fields a kind can read — the half of a params
31
- * check every kind needs and no two kinds differ on.
32
- *
33
- * Params that arrived from a template file are `unknown`, and before a single field can be
34
- * read the value has to be an object. Worth a shared function because the check is easy to
35
- * get wrong by hand: `typeof null` is `"object"`, `Object.keys(5)` is `[]` and
36
- * `Object.keys(["a"])` is `["0"]`, so a naive test lets `null`, a number and an array through
37
- * as if they were empty params.
38
- *
39
- * What each field must *be* is the kind's own business and stays in the kind, as plain
40
- * TypeScript: this package deliberately carries no validation library, so a kind author owes
41
- * it no schema.
42
- *
43
- * A key the kind does not declare is NOT refused. A parser returns the params to use, so a
44
- * field it never read is dropped and never reaches the block — the only question was whether
45
- * to also complain, and complaining costs more than it catches. It would mean each kind
46
- * restating its own field list as strings, with nothing checking that the list stayed in step
47
- * with the type: a field added to the contract and read by the parser, but missed in the list,
48
- * would turn into a kind that refuses files that are correct. What an unexpected key can
49
- * actually mean is a params contract from a different version of the kind, and that is
50
- * guarded where it belongs — by the version in the entry's `{name}@{selector}` reference.
51
- *
52
- * An assertion rather than a parser that returns a copy, so a kind reads its fields off the
53
- * value it was handed:
54
- *
55
- * ```ts
56
- * function parseInitializationParams(value: unknown): BlockParams {
57
- * assertParamsObject(value);
4
+ * Default state for a mutation-landscape chart. Used by `init` for the placeholder and by the UI
5
+ * for each score a run produces, so the two look alike.
58
6
  *
59
- * const { numbers } = value;
60
- * if (numbers !== undefined && !isNumberArray(numbers)) {
61
- * throw new Error("'numbers' must be an array of numbers.");
62
- * }
63
- * return { numbers };
64
- * }
65
- * ```
7
+ * @param currentTab `"settings"` opens the Settings drawer, `null` leaves it closed
8
+ */
9
+ function makeLandscapeChartState(title, currentTab) {
10
+ return {
11
+ title,
12
+ template: "heatmap",
13
+ currentTab,
14
+ layersSettings: { heatmap: {
15
+ normalizationDirection: null,
16
+ transform: null,
17
+ NAValueAs: null
18
+ } },
19
+ axesSettings: {
20
+ axisX: {
21
+ cellSize: 20,
22
+ axisLabelsAngle: 45
23
+ },
24
+ axisY: {
25
+ hideAxisLabels: false,
26
+ cellSize: 20
27
+ }
28
+ }
29
+ };
30
+ }
31
+ /**
32
+ * Default state for a drill-down's partner map. Same shape as a landscape chart — one colour
33
+ * scale, no normalization, absent cells left empty — because it is the same map with one
34
+ * mutation held fixed.
35
+ */
36
+ /**
37
+ * The key a chart's saved aesthetic mapping uses for the region track, as it appears inside
38
+ * `dataBindAes`. The source id embeds the column's resolve path, so this matches it in both
39
+ * frames at once.
40
+ */
41
+ const REGION_AES_SOURCE = "region/region";
42
+ /**
43
+ * Drops a chart's saved colour mapping for the region track, so it is seeded afresh.
66
44
  *
67
- * Messages are finished sentences addressed to whoever wrote the file, because that is who
68
- * reads them: a kind's rejection is reported against the entry that carried the params.
45
+ * graph-maker reads the `pl7.app/graph/palette` annotation ONCE, when a mapping is created, and
46
+ * never reasserts it — "after that the mapping is the user's". A chart that already built its own
47
+ * mapping therefore keeps it, whatever the column now declares. Clearing the entry is the only
48
+ * way to let the pinned palette take effect on a chart that predates it.
49
+ */
50
+ function withRegionColoursReseeded(state) {
51
+ const aes = state.dataBindAes;
52
+ if (aes === void 0) return state;
53
+ const kept = Object.fromEntries(Object.entries(aes).filter(([source]) => !source.includes(REGION_AES_SOURCE)));
54
+ return {
55
+ ...state,
56
+ dataBindAes: kept
57
+ };
58
+ }
59
+ /**
60
+ * Pins "show empty rows/columns" on a drill-down chart.
69
61
  *
70
- * @param value The params as they arrived
71
- * @throws if `value` is not an object
62
+ * The partner map is sparse by nature — most positions carry no pair with the fixed mutation —
63
+ * and without this it draws only the few positions that do. The region band beneath it then
64
+ * shrinks to those, and the reader loses where in the parent they are looking. With the value
65
+ * column's axes declared dense, the full grid arrives; this is what makes it render.
72
66
  */
73
- function assertParamsObject(value) {
74
- if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Params must be an object, not ${describe(value)}.`);
67
+ function withEmptyCellsShown(state) {
68
+ return {
69
+ ...state,
70
+ layersSettings: {
71
+ ...state.layersSettings,
72
+ heatmap: {
73
+ ...state.layersSettings?.heatmap,
74
+ showEmptyRows: true,
75
+ showEmptyColumns: true
76
+ }
77
+ }
78
+ };
75
79
  }
76
- /** What a value is, for a message that has to say why it is not an object. */
77
- function describe(value) {
78
- if (value === null) return "null";
79
- if (value === void 0) return "nothing";
80
- if (Array.isArray(value)) return "an array";
81
- return `a ${typeof value} (${JSON.stringify(value) ?? String(value)})`;
80
+ function makeDrillDownChartState() {
81
+ const base = withEmptyCellsShown(makeLandscapeChartState("", null));
82
+ return {
83
+ ...base,
84
+ axesSettings: {
85
+ ...base.axesSettings,
86
+ title: {
87
+ ...base.axesSettings?.title,
88
+ mode: "hidden"
89
+ }
90
+ }
91
+ };
82
92
  }
83
- //#endregion
84
- //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/index.js
85
93
  /**
86
- * Define a block kind.
87
- *
88
- * `meta` is the kind's identity — its own `{ name, version }`. Source it from
89
- * the package's `package.json` rather than hand-typing literals, so the on-wire
90
- * `{name}@{version}` cannot drift from what npm publishes and what the S3
91
- * manifest records (all read the same `package.json`):
92
- *
93
- * ```ts
94
- * // a kind package's src/index.ts
95
- * import { name, version } from "../package.json" with { type: "json" };
96
- * export const kind = defineBlockKind<Params>({ name, version });
97
- * ```
98
- *
99
- * rolldown inlines the JSON import (tree-shaken to the two strings) into the
100
- * bundled `kind.js`, so no build-time injection is needed.
101
- *
102
- * A kind must also declare `parseInitializationParams` — the runtime check applied to params
103
- * that came from a template file rather than from typed code. See
104
- * {@link CompiledBlockKind} for what it must do.
105
- *
106
- * @typeParam BlockParams - shape of the params a block of this kind reads. Pinned both
107
- * as a type and by `parseInitializationParams`, whose return type is checked against it.
94
+ * Pins "Treat NA value as: empty" on a landscape chart's saved state.
95
+ *
96
+ * The landscape's cell axes are declared dense, so the grid now carries a record for every
97
+ * (position, state) and the substitutions no single mutant covered arrive with no value. They
98
+ * must stay empty. Seeding `makeLandscapeChartState` only reaches charts created from now on:
99
+ * graph-maker writes its whole merged layer settings back into the state it is bound to, so any
100
+ * chart opened before this change has the old default of 0 pinned in its own state, and would
101
+ * paint every uncovered substitution as a real zero-valued cell.
108
102
  */
109
- function defineBlockKind(meta) {
110
- return Object.freeze({
111
- kindSchema: "v1",
112
- name: meta.name,
113
- version: meta.version,
114
- parseInitializationParams: meta.parseInitializationParams
115
- });
103
+ function withEmptyNAValue(state) {
104
+ return {
105
+ ...state,
106
+ layersSettings: {
107
+ ...state.layersSettings,
108
+ heatmap: {
109
+ ...state.layersSettings?.heatmap,
110
+ NAValueAs: null
111
+ }
112
+ }
113
+ };
116
114
  }
117
- //#endregion
118
- //#region ../kind/dist/index.js
119
115
  /**
120
- * The same contract at runtime, for params that arrive from a template file
121
- * rather than from typed code.
116
+ * The parent-residue column's key inside both heat-map frames, as it appears inside a saved
117
+ * selector's source id. Distinct from the highlight flag's `parentFlag/isParentResidue`, which
118
+ * contains this word too but not this path.
119
+ */
120
+ const PARENT_RESIDUE_SOURCE = "parent/parentResidue";
121
+ const carriesParentResidue = (selectedSource) => selectedSource.includes(PARENT_RESIDUE_SOURCE);
122
+ /**
123
+ * Angles the X labels of a chart saved before the parent residue joined the axis, and moves the
124
+ * source across.
122
125
  *
123
- * The contract names no fields, so there is nothing to read and nothing to
124
- * validate beyond the value being an object at all. Keys a template supplies
125
- * anyway are dropped by not being read. The return type holds this in step: the
126
- * moment `BlockParams` declares a required field, `return {}` stops compiling.
126
+ * The move is belt and braces — graph-maker reapplies a default whose value has changed, so it
127
+ * would arrive anyway — but the angle is not a default option. It lives in the chart's own axes
128
+ * settings, which are seeded once when the chart is created, so without this an existing chart gets
129
+ * the two-part label flat and overlapping under a 20px column.
130
+ *
131
+ * Keyed on the parent still being an annotation track, which is what "saved before this" looks
132
+ * like. The region track is deliberately left where it is.
127
133
  */
128
- function parseInitializationParams(value) {
129
- assertParamsObject(value);
130
- return {};
134
+ function withParentOnXAxis(state) {
135
+ const options = state.optionsState;
136
+ if (options?.type !== "heatmap") return state;
137
+ const annotations = options.components.annotationsX.selectorStates;
138
+ const parent = annotations.find((selector) => carriesParentResidue(selector.selectedSource));
139
+ if (!parent) return state;
140
+ const alreadyOnX = options.components.x.selectorStates.some((selector) => carriesParentResidue(selector.selectedSource));
141
+ return {
142
+ ...state,
143
+ optionsState: {
144
+ ...options,
145
+ components: {
146
+ ...options.components,
147
+ x: alreadyOnX ? options.components.x : {
148
+ type: "simple",
149
+ selectorStates: [...options.components.x.selectorStates, parent]
150
+ },
151
+ annotationsX: {
152
+ type: "simple",
153
+ selectorStates: annotations.filter((selector) => selector !== parent)
154
+ }
155
+ }
156
+ },
157
+ axesSettings: {
158
+ ...state.axesSettings,
159
+ axisX: {
160
+ ...state.axesSettings?.axisX,
161
+ axisLabelsAngle: 45
162
+ }
163
+ }
164
+ };
165
+ }
166
+ function mapChartStates(data, rewrite) {
167
+ return {
168
+ compositionHeatmapState: rewrite(data.compositionHeatmapState),
169
+ singleMutantHeatmapState: rewrite(data.singleMutantHeatmapState),
170
+ singleMutantHeatmapStates: Object.fromEntries(Object.entries(data.singleMutantHeatmapStates).map(([key, state]) => [key, rewrite(state)]))
171
+ };
131
172
  }
132
- const kind = defineBlockKind({
133
- name,
134
- version: version$1,
135
- parseInitializationParams
136
- });
137
173
  //#endregion
138
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/plugin_handle.js
174
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/plugin_handle.js
139
175
  const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
140
176
  /** Construct the output key for a plugin output in the block outputs map. */
141
177
  function pluginOutputKey(handle, outputKey) {
142
178
  return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
143
179
  }
144
180
  //#endregion
145
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/block_storage.js
181
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_storage.js
146
182
  /**
147
183
  * Discriminator key for BlockStorage format detection.
148
184
  * This unique hash-based key identifies data as BlockStorage vs legacy formats.
@@ -612,13 +648,14 @@ const errorMap = (issue, _ctx) => {
612
648
  message = `Invalid date`;
613
649
  break;
614
650
  case ZodIssueCode.invalid_string:
615
- if (typeof issue.validation === "object") if ("includes" in issue.validation) {
616
- message = `Invalid input: must include "${issue.validation.includes}"`;
617
- if (typeof issue.validation.position === "number") message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
618
- } else if ("startsWith" in issue.validation) message = `Invalid input: must start with "${issue.validation.startsWith}"`;
619
- else if ("endsWith" in issue.validation) message = `Invalid input: must end with "${issue.validation.endsWith}"`;
620
- else util.assertNever(issue.validation);
621
- else if (issue.validation !== "regex") message = `Invalid ${issue.validation}`;
651
+ if (typeof issue.validation === "object") {
652
+ if ("includes" in issue.validation) {
653
+ message = `Invalid input: must include "${issue.validation.includes}"`;
654
+ if (typeof issue.validation.position === "number") message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
655
+ } else if ("startsWith" in issue.validation) message = `Invalid input: must start with "${issue.validation.startsWith}"`;
656
+ else if ("endsWith" in issue.validation) message = `Invalid input: must end with "${issue.validation.endsWith}"`;
657
+ else util.assertNever(issue.validation);
658
+ } else if (issue.validation !== "regex") message = `Invalid ${issue.validation}`;
622
659
  else message = "Invalid";
623
660
  break;
624
661
  case ZodIssueCode.too_small:
@@ -783,8 +820,10 @@ var ParseInputLazyPath = class {
783
820
  this._key = key;
784
821
  }
785
822
  get path() {
786
- if (!this._cachedPath.length) if (Array.isArray(this._key)) this._cachedPath.push(...this._path, ...this._key);
787
- else this._cachedPath.push(...this._path, this._key);
823
+ if (!this._cachedPath.length) {
824
+ if (Array.isArray(this._key)) this._cachedPath.push(...this._path, ...this._key);
825
+ else this._cachedPath.push(...this._path, this._key);
826
+ }
788
827
  return this._cachedPath;
789
828
  }
790
829
  };
@@ -883,11 +922,12 @@ var ZodType = class {
883
922
  data,
884
923
  parsedType: getParsedType(data)
885
924
  };
886
- return handleResult(ctx, this._parseSync({
925
+ const result = this._parseSync({
887
926
  data,
888
927
  path: ctx.path,
889
928
  parent: ctx
890
- }));
929
+ });
930
+ return handleResult(ctx, result);
891
931
  }
892
932
  "~validate"(data) {
893
933
  const ctx = {
@@ -944,7 +984,8 @@ var ZodType = class {
944
984
  path: ctx.path,
945
985
  parent: ctx
946
986
  });
947
- return handleResult(ctx, await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult)));
987
+ const result = await (isAsync(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
988
+ return handleResult(ctx, result);
948
989
  }
949
990
  refine(check, message) {
950
991
  const getIssueProperties = (val) => {
@@ -3497,7 +3538,8 @@ var ZodPromise = class extends ZodType {
3497
3538
  });
3498
3539
  return INVALID;
3499
3540
  }
3500
- return OK((ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data)).then((data) => {
3541
+ const promisified = ctx.parsedType === ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);
3542
+ return OK(promisified.then((data) => {
3501
3543
  return this._def.type.parseAsync(data, {
3502
3544
  path: ctx.path,
3503
3545
  errorMap: ctx.common.contextualErrorMap
@@ -3595,30 +3637,32 @@ var ZodEffects = class extends ZodType {
3595
3637
  });
3596
3638
  });
3597
3639
  }
3598
- if (effect.type === "transform") if (ctx.common.async === false) {
3599
- const base = this._def.schema._parseSync({
3640
+ if (effect.type === "transform") {
3641
+ if (ctx.common.async === false) {
3642
+ const base = this._def.schema._parseSync({
3643
+ data: ctx.data,
3644
+ path: ctx.path,
3645
+ parent: ctx
3646
+ });
3647
+ if (!isValid(base)) return INVALID;
3648
+ const result = effect.transform(base.value, checkCtx);
3649
+ if (result instanceof Promise) throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
3650
+ return {
3651
+ status: status.value,
3652
+ value: result
3653
+ };
3654
+ } else return this._def.schema._parseAsync({
3600
3655
  data: ctx.data,
3601
3656
  path: ctx.path,
3602
3657
  parent: ctx
3658
+ }).then((base) => {
3659
+ if (!isValid(base)) return INVALID;
3660
+ return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
3661
+ status: status.value,
3662
+ value: result
3663
+ }));
3603
3664
  });
3604
- if (!isValid(base)) return INVALID;
3605
- const result = effect.transform(base.value, checkCtx);
3606
- if (result instanceof Promise) throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
3607
- return {
3608
- status: status.value,
3609
- value: result
3610
- };
3611
- } else return this._def.schema._parseAsync({
3612
- data: ctx.data,
3613
- path: ctx.path,
3614
- parent: ctx
3615
- }).then((base) => {
3616
- if (!isValid(base)) return INVALID;
3617
- return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
3618
- status: status.value,
3619
- value: result
3620
- }));
3621
- });
3665
+ }
3622
3666
  util.assertNever(effect);
3623
3667
  }
3624
3668
  };
@@ -3924,12 +3968,34 @@ ZodOptional.create;
3924
3968
  ZodNullable.create;
3925
3969
  ZodEffects.createWithPreprocess;
3926
3970
  ZodPipeline.create;
3971
+ const coerce = {
3972
+ string: ((arg) => ZodString.create({
3973
+ ...arg,
3974
+ coerce: true
3975
+ })),
3976
+ number: ((arg) => ZodNumber.create({
3977
+ ...arg,
3978
+ coerce: true
3979
+ })),
3980
+ boolean: ((arg) => ZodBoolean.create({
3981
+ ...arg,
3982
+ coerce: true
3983
+ })),
3984
+ bigint: ((arg) => ZodBigInt.create({
3985
+ ...arg,
3986
+ coerce: true
3987
+ })),
3988
+ date: ((arg) => ZodDate.create({
3989
+ ...arg,
3990
+ coerce: true
3991
+ }))
3992
+ };
3927
3993
  objectType({
3928
3994
  type: literalType("plain"),
3929
3995
  content: stringType()
3930
3996
  });
3931
3997
  //#endregion
3932
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3998
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3933
3999
  /**
3934
4000
  * Compose a {@link BlockKindReference} from a kind's `name`/`version`.
3935
4001
  *
@@ -3945,12 +4011,19 @@ objectType({
3945
4011
  to: numberType().min(1)
3946
4012
  });
3947
4013
  //#endregion
3948
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/util.js
4014
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/util.js
3949
4015
  function assertNever(x) {
3950
4016
  throw new Error("Unexpected object: " + x);
3951
4017
  }
4018
+ /**
4019
+ * Return unique entries of the array by the provided id
4020
+ * For each id, the last entry is kept
4021
+ */
4022
+ function uniqueBy(array, makeId) {
4023
+ return [...new Map(array.map((e) => [makeId(e), e])).values()];
4024
+ }
3952
4025
  //#endregion
3953
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
4026
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
3954
4027
  /**
3955
4028
  * Type guard function that checks if the given value is a valid DataInfo.
3956
4029
  *
@@ -4019,9 +4092,7 @@ function visitDataInfo(dataInfo, cb) {
4019
4092
  cb(chunk.values);
4020
4093
  });
4021
4094
  break;
4022
- case "ParquetPartitioned":
4023
- Object.values(dataInfo.parts).forEach(cb);
4024
- break;
4095
+ case "ParquetPartitioned": Object.values(dataInfo.parts).forEach(cb);
4025
4096
  }
4026
4097
  }
4027
4098
  /**
@@ -4141,7 +4212,7 @@ function entriesToDataInfo(dataInfoEntries) {
4141
4212
  }
4142
4213
  }
4143
4214
  //#endregion
4144
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/errors.js
4215
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/errors.js
4145
4216
  var ServiceError = class extends Error {
4146
4217
  name = "ServiceError";
4147
4218
  };
@@ -4165,7 +4236,7 @@ function ensureError(value) {
4165
4236
  return new Error(stringifyValue(value));
4166
4237
  }
4167
4238
  //#endregion
4168
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/json.js
4239
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/json.js
4169
4240
  var import_canonicalize = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
4170
4241
  module.exports = function serialize(object) {
4171
4242
  if (typeof object === "number" && isNaN(object)) throw new Error("NaN is not allowed");
@@ -4198,7 +4269,7 @@ function parseJsonSafely(value, fallback) {
4198
4269
  }
4199
4270
  }
4200
4271
  //#endregion
4201
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4272
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4202
4273
  function readMetadata(metadata, key) {
4203
4274
  return metadata?.[key];
4204
4275
  }
@@ -4220,6 +4291,36 @@ function readMetadataJson(metadata, metadataJson, key) {
4220
4291
  return;
4221
4292
  }
4222
4293
  }
4294
+ /**
4295
+ * Domain keys whose value is the id of a block, rather than a qualifier of the data.
4296
+ *
4297
+ * Applying a template repoints these at the blocks of the project being built: an axis a block
4298
+ * produced names that block in its domain, so an axis left naming the exported-from project
4299
+ * resolves to nothing. Listing the keys is what makes that safe — a template's entry ids are
4300
+ * arbitrary non-empty strings, so a hand-written template may name an entry `closest`, and a
4301
+ * qualifier that happens to read `closest` must not be mistaken for a reference to it.
4302
+ *
4303
+ * A key absent from here is simply left alone, which is the behaviour from before relocation
4304
+ * reached domains at all. Adding one is therefore safe; omitting one costs only that a template
4305
+ * carrying it applies still pointing at the project it came from.
4306
+ */
4307
+ const BlockScopedDomain = /* @__PURE__ */ new Set([
4308
+ "pl7.app/blockId",
4309
+ "pl7.app/block",
4310
+ "pl7.app/redefined-by",
4311
+ "pl7.app/annotationRunId",
4312
+ "pl7.app/clonotypeAnnotationRunId",
4313
+ "pl7.app/clustering/blockId",
4314
+ "pl7.app/umap/blockId",
4315
+ "pl7.app/peptide/extractionRunId",
4316
+ "pl7.app/repertoire/extractionRunId",
4317
+ "pl7.app/antibodyVariantDesigner/designRunId",
4318
+ "pl7.app/vdj/clonotypingRunId",
4319
+ "pl7.app/vdj/clustering/blockId",
4320
+ "pl7.app/vdj/integration/blockId",
4321
+ "pl7.app/vdj/spatiotemporalAnalysis/blockId",
4322
+ "pl7.app/vdj/libraryId"
4323
+ ]);
4223
4324
  const Annotation = {
4224
4325
  AxisNature: "pl7.app/axisNature",
4225
4326
  Alphabet: "pl7.app/alphabet",
@@ -4237,6 +4338,7 @@ const Annotation = {
4237
4338
  IsDenseAxis: "pl7.app/graph/isDenseAxis",
4238
4339
  IsVirtual: "pl7.app/graph/isVirtual",
4239
4340
  Palette: "pl7.app/graph/palette",
4341
+ Shape: "pl7.app/graph/shape",
4240
4342
  Thresholds: "pl7.app/graph/thresholds",
4241
4343
  TreatAbsentValuesAs: "pl7.app/graph/treatAbsentValuesAs"
4242
4344
  },
@@ -4292,9 +4394,14 @@ const AnnotationJson = {
4292
4394
  [Annotation.Graph.Axis.SymmetricRange]: booleanType(),
4293
4395
  [Annotation.Graph.IsDenseAxis]: booleanType(),
4294
4396
  [Annotation.Graph.Palette]: objectType({
4295
- mapping: recordType(numberType()),
4296
- name: stringType()
4397
+ name: stringType(),
4398
+ mapping: recordType(coerce.number()).optional(),
4399
+ midPoint: numberType().optional(),
4400
+ min: numberType().optional(),
4401
+ max: numberType().optional(),
4402
+ log: booleanType().optional()
4297
4403
  }),
4404
+ [Annotation.Graph.Shape]: objectType({ mapping: recordType(stringType()) }),
4298
4405
  [Annotation.Graph.Thresholds]: arrayType(objectType({
4299
4406
  columnId: objectType({
4300
4407
  valueType: ValueTypeSchema,
@@ -4490,7 +4597,22 @@ function matchAxisId(query, target) {
4490
4597
  return query.name === target.name && matchDomain$1(query.domain, target.domain) && matchDomain$1(query.contextDomain, target.contextDomain);
4491
4598
  }
4492
4599
  //#endregion
4493
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4600
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4601
+ const BOOLEAN_TYPES = /* @__PURE__ */ new Set([
4602
+ "numericComparison",
4603
+ "stringEquals",
4604
+ "stringContains",
4605
+ "stringContainsFuzzy",
4606
+ "stringRegex",
4607
+ "isNull",
4608
+ "not",
4609
+ "and",
4610
+ "or",
4611
+ "isIn"
4612
+ ]);
4613
+ function isBooleanExpression(expr) {
4614
+ return BOOLEAN_TYPES.has(expr.type);
4615
+ }
4494
4616
  /**
4495
4617
  * Recursively traverses a SpecQuery tree bottom-up, applying visitor callbacks.
4496
4618
  *
@@ -4570,8 +4692,17 @@ function traverseQuerySpec(query, visitor) {
4570
4692
  function mapSpecQueryColumns(query, visitor) {
4571
4693
  return traverseQuerySpec(query, visitor);
4572
4694
  }
4695
+ /** Collects all column references from a SpecQuery tree. */
4696
+ function collectSpecQueryColumns(query) {
4697
+ const result = [];
4698
+ traverseQuerySpec(query, { column: (c) => {
4699
+ result.push(c);
4700
+ return c;
4701
+ } });
4702
+ return result;
4703
+ }
4573
4704
  //#endregion
4574
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4705
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4575
4706
  function mapPTableDef(def, cb) {
4576
4707
  return {
4577
4708
  ...def,
@@ -4614,7 +4745,21 @@ function mapJoinEntry(entry, cb) {
4614
4745
  }
4615
4746
  }
4616
4747
  //#endregion
4617
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4748
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
4749
+ function getPTableColumnId(spec) {
4750
+ switch (spec.type) {
4751
+ case "axis": return {
4752
+ type: "axis",
4753
+ id: spec.id
4754
+ };
4755
+ case "column": return {
4756
+ type: "column",
4757
+ id: spec.id
4758
+ };
4759
+ }
4760
+ }
4761
+ //#endregion
4762
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4618
4763
  function stringifyColumnFilteredId(key) {
4619
4764
  return canonicalizeJson(createColumnFilteredKey(key));
4620
4765
  }
@@ -4647,7 +4792,7 @@ function applyAxisFilters(spec, axisFilters) {
4647
4792
  };
4648
4793
  }
4649
4794
  //#endregion
4650
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4795
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4651
4796
  function isPObjectId(value) {
4652
4797
  if (typeof value !== "string") return false;
4653
4798
  return isPObjectKey(parseJsonSafely(value));
@@ -4729,7 +4874,39 @@ function extractAllColumns(entry) {
4729
4874
  addAllColumns(entry);
4730
4875
  return [...columns.values()];
4731
4876
  }
4877
+ //#endregion
4878
+ //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.5/node_modules/@milaboratories/helpers/dist/utils.js
4879
+ function isNil$1(v) {
4880
+ return v === null || v === void 0;
4881
+ }
4732
4882
  Array.isArray;
4883
+ function isObject(value) {
4884
+ return typeof value === "object" && value !== null;
4885
+ }
4886
+ /**
4887
+ * Checks if the given value is a plain object.
4888
+ *
4889
+ * A plain object is defined as an object created by the `{}` literal,
4890
+ * an object created with `Object.create(null)`, or an object with a
4891
+ * prototype that resolves to `Object.prototype`.
4892
+ *
4893
+ * @param value - The value to check.
4894
+ * @returns `true` if the value is a plain object, otherwise `false`.
4895
+ *
4896
+ * @example
4897
+ * ```typescript
4898
+ * isPlainObject({}); // true
4899
+ * isPlainObject(Object.create(null)); // true
4900
+ * isPlainObject(new Date()); // false
4901
+ * isPlainObject(null); // false
4902
+ * isPlainObject([]); // false
4903
+ * ```
4904
+ */
4905
+ function isPlainObject$1(value) {
4906
+ if (!isObject(value)) return false;
4907
+ const prototype = Object.getPrototypeOf(value);
4908
+ return prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null;
4909
+ }
4733
4910
  //#endregion
4734
4911
  //#region ../node_modules/.pnpm/@milaboratories+helpers@1.14.5/node_modules/@milaboratories/helpers/dist/error.js
4735
4912
  function throwError(v) {
@@ -4737,7 +4914,7 @@ function throwError(v) {
4737
4914
  else throw v;
4738
4915
  }
4739
4916
  //#endregion
4740
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4917
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4741
4918
  function isColumnDiscoveredKey(obj) {
4742
4919
  return typeof obj === "object" && obj !== null && "__isDiscovered" in obj;
4743
4920
  }
@@ -4757,56 +4934,252 @@ function stringifyColumnDiscoveredId(id) {
4757
4934
  }));
4758
4935
  }
4759
4936
  //#endregion
4760
- //#region ../node_modules/.pnpm/es-toolkit@1.48.1/node_modules/es-toolkit/dist/predicate/isFunction.mjs
4937
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/array/uniq.mjs
4761
4938
  /**
4762
- * Checks if `value` is a function.
4939
+ * Creates a duplicate-free version of an array.
4763
4940
  *
4764
- * @param value The value to check.
4765
- * @returns Returns `true` if `value` is a function, else `false`.
4941
+ * This function takes an array and returns a new array containing only the unique values
4942
+ * from the original array, preserving the order of first occurrence.
4943
+ *
4944
+ * @template T - The type of elements in the array.
4945
+ * @param arr - The array to process.
4946
+ * @returns A new array with only unique values from the original array.
4766
4947
  *
4767
4948
  * @example
4768
- * isFunction(Array.prototype.slice); // true
4769
- * isFunction(async function () {}); // true
4770
- * isFunction(function* () {}); // true
4771
- * isFunction(Proxy); // true
4772
- * isFunction(Int8Array); // true
4949
+ * const array = [1, 2, 2, 3, 4, 4, 5];
4950
+ * const result = uniq(array);
4951
+ * // result will be [1, 2, 3, 4, 5]
4773
4952
  */
4774
- function isFunction(value) {
4775
- return typeof value === "function";
4953
+ function uniq(arr) {
4954
+ return [...new Set(arr)];
4776
4955
  }
4777
4956
  //#endregion
4778
- //#region ../node_modules/.pnpm/es-toolkit@1.48.1/node_modules/es-toolkit/dist/predicate/isNil.mjs
4957
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/array/uniqBy.mjs
4779
4958
  /**
4780
- * Checks if a given value is null or undefined.
4959
+ * Returns a new array containing only the unique elements from the original array,
4960
+ * based on the values returned by the mapper function.
4781
4961
  *
4782
- * This function tests whether the provided value is either `null` or `undefined`.
4783
- * It returns `true` if the value is `null` or `undefined`, and `false` otherwise.
4962
+ * When duplicates are found, the first occurrence is kept and the rest are discarded.
4784
4963
  *
4785
- * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `null` or `undefined`.
4964
+ * @template T - The type of elements in the array.
4965
+ * @template U - The type of mapped elements.
4966
+ * @param arr - The array to process.
4967
+ * @param mapper - The function used to convert the array elements.
4968
+ * @returns A new array containing only the unique elements from the original array, based on the values returned by the mapper function.
4786
4969
  *
4787
- * @param x - The value to test for null or undefined.
4788
- * @returns `true` if the value is null or undefined, `false` otherwise.
4970
+ * @example
4971
+ * ```ts
4972
+ * uniqBy([1.2, 1.5, 2.1, 3.2, 5.7, 5.3, 7.19], Math.floor);
4973
+ * // [1.2, 2.1, 3.2, 5.7, 7.19]
4974
+ * ```
4789
4975
  *
4790
4976
  * @example
4791
- * const value1 = null;
4792
- * const value2 = undefined;
4793
- * const value3 = 42;
4794
- * const result1 = isNil(value1); // true
4795
- * const result2 = isNil(value2); // true
4796
- * const result3 = isNil(value3); // false
4977
+ * const array = [
4978
+ * { category: 'fruit', name: 'apple' },
4979
+ * { category: 'fruit', name: 'banana' },
4980
+ * { category: 'vegetable', name: 'carrot' },
4981
+ * ];
4982
+ * uniqBy(array, item => item.category).length
4983
+ * // 2
4984
+ * ```
4797
4985
  */
4798
- function isNil(x) {
4799
- return x == null;
4986
+ function uniqBy(arr, mapper) {
4987
+ const map = /* @__PURE__ */ new Map();
4988
+ for (let i = 0; i < arr.length; i++) {
4989
+ const item = arr[i];
4990
+ const key = mapper(item, i, arr);
4991
+ if (!map.has(key)) map.set(key, item);
4992
+ }
4993
+ return Array.from(map.values());
4800
4994
  }
4801
4995
  //#endregion
4802
- //#region ../node_modules/.pnpm/es-toolkit@1.48.1/node_modules/es-toolkit/dist/predicate/isString.mjs
4996
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/_internal/globalThis.mjs
4997
+ const globalThis_ = typeof globalThis === "object" && globalThis || typeof window === "object" && window || typeof self === "object" && self || typeof global === "object" && global || (function() {
4998
+ return this;
4999
+ })();
5000
+ //#endregion
5001
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isTypedArray.mjs
4803
5002
  /**
4804
- * Checks if a given value is string.
5003
+ * Checks if a value is a TypedArray.
5004
+ * @param x The value to check.
5005
+ * @returns Returns true if `x` is a TypedArray, false otherwise.
4805
5006
  *
4806
- * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `string`.
5007
+ * @example
5008
+ * const arr = new Uint8Array([1, 2, 3]);
5009
+ * isTypedArray(arr); // true
4807
5010
  *
4808
- * @param value The value to check if it is string.
4809
- * @returns Returns `true` if `value` is a string, else `false`.
5011
+ * const regularArray = [1, 2, 3];
5012
+ * isTypedArray(regularArray); // false
5013
+ *
5014
+ * const buffer = new ArrayBuffer(16);
5015
+ * isTypedArray(buffer); // false
5016
+ */
5017
+ function isTypedArray$1(x) {
5018
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
5019
+ }
5020
+ //#endregion
5021
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isBuffer.mjs
5022
+ /**
5023
+ * Checks if the given value is a Buffer instance.
5024
+ *
5025
+ * This function tests whether the provided value is an instance of Buffer.
5026
+ * It returns `true` if the value is a Buffer, and `false` otherwise.
5027
+ *
5028
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `Buffer`.
5029
+ *
5030
+ * @param x - The value to check if it is a Buffer.
5031
+ * @returns Returns `true` if `x` is a Buffer, else `false`.
5032
+ *
5033
+ * @example
5034
+ * const buffer = Buffer.from("test");
5035
+ * console.log(isBuffer(buffer)); // true
5036
+ *
5037
+ * const notBuffer = "not a buffer";
5038
+ * console.log(isBuffer(notBuffer)); // false
5039
+ */
5040
+ function isBuffer(x) {
5041
+ return typeof globalThis_.Buffer !== "undefined" && globalThis_.Buffer.isBuffer(x);
5042
+ }
5043
+ //#endregion
5044
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/_internal/getTag.mjs
5045
+ /**
5046
+ * Gets the `toStringTag` of `value`.
5047
+ *
5048
+ * @private
5049
+ * @param {T} value The value to query.
5050
+ * @returns {string} Returns the `Object.prototype.toString.call` result.
5051
+ */
5052
+ function getTag(value) {
5053
+ if (value == null) return value === void 0 ? "[object Undefined]" : "[object Null]";
5054
+ return Object.prototype.toString.call(value);
5055
+ }
5056
+ //#endregion
5057
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isPlainObject.mjs
5058
+ /**
5059
+ * Checks if a given value is a plain object.
5060
+ *
5061
+ * @param value - The value to check.
5062
+ * @returns True if the value is a plain object, otherwise false.
5063
+ *
5064
+ * @example
5065
+ * ```typescript
5066
+ * // ✅👇 True
5067
+ *
5068
+ * isPlainObject({ }); // ✅
5069
+ * isPlainObject({ key: 'value' }); // ✅
5070
+ * isPlainObject({ key: new Date() }); // ✅
5071
+ * isPlainObject(new Object()); // ✅
5072
+ * isPlainObject(Object.create(null)); // ✅
5073
+ * isPlainObject({ nested: { key: true} }); // ✅
5074
+ * isPlainObject(new Proxy({}, {})); // ✅
5075
+ * isPlainObject({ [Symbol('tag')]: 'A' }); // ✅
5076
+ *
5077
+ * // ✅👇 (cross-realms, node context, workers, ...)
5078
+ * const runInNewContext = await import('node:vm').then(
5079
+ * (mod) => mod.runInNewContext
5080
+ * );
5081
+ * isPlainObject(runInNewContext('({})')); // ✅
5082
+ *
5083
+ * // ❌👇 False
5084
+ *
5085
+ * class Test { };
5086
+ * isPlainObject(new Test()) // ❌
5087
+ * isPlainObject(10); // ❌
5088
+ * isPlainObject(null); // ❌
5089
+ * isPlainObject('hello'); // ❌
5090
+ * isPlainObject([]); // ❌
5091
+ * isPlainObject(new Date()); // ❌
5092
+ * isPlainObject(new Uint8Array([1])); // ❌
5093
+ * isPlainObject(Buffer.from('ABC')); // ❌
5094
+ * isPlainObject(Promise.resolve({})); // ❌
5095
+ * isPlainObject(Object.create({})); // ❌
5096
+ * isPlainObject(new (class Cls {})); // ❌
5097
+ * isPlainObject(globalThis); // ❌,
5098
+ * ```
5099
+ */
5100
+ function isPlainObject(value) {
5101
+ if (!value || typeof value !== "object") return false;
5102
+ const proto = Object.getPrototypeOf(value);
5103
+ if (!(proto === null || proto === Object.prototype || Object.getPrototypeOf(proto) === null)) return false;
5104
+ return Object.prototype.toString.call(value) === "[object Object]";
5105
+ }
5106
+ //#endregion
5107
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isFunction.mjs
5108
+ /**
5109
+ * Checks if `value` is a function.
5110
+ *
5111
+ * @param value The value to check.
5112
+ * @returns Returns `true` if `value` is a function, else `false`.
5113
+ *
5114
+ * @example
5115
+ * isFunction(Array.prototype.slice); // true
5116
+ * isFunction(async function () {}); // true
5117
+ * isFunction(function* () {}); // true
5118
+ * isFunction(Proxy); // true
5119
+ * isFunction(Int8Array); // true
5120
+ */
5121
+ function isFunction(value) {
5122
+ return typeof value === "function";
5123
+ }
5124
+ //#endregion
5125
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isLength.mjs
5126
+ /**
5127
+ * Checks if a given value is a valid length.
5128
+ *
5129
+ * A valid length is of type `number`, is a non-negative integer, and is less than or equal to
5130
+ * JavaScript's maximum safe integer (`Number.MAX_SAFE_INTEGER`).
5131
+ * It returns `true` if the value is a valid length, and `false` otherwise.
5132
+ *
5133
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the
5134
+ * argument to a valid length (`number`).
5135
+ *
5136
+ * @param value The value to check.
5137
+ * @returns Returns `true` if `value` is a valid length, else `false`.
5138
+ *
5139
+ * @example
5140
+ * isLength(0); // true
5141
+ * isLength(42); // true
5142
+ * isLength(-1); // false
5143
+ * isLength(1.5); // false
5144
+ * isLength(Number.MAX_SAFE_INTEGER); // true
5145
+ * isLength(Number.MAX_SAFE_INTEGER + 1); // false
5146
+ */
5147
+ function isLength(value) {
5148
+ return Number.isSafeInteger(value) && value >= 0;
5149
+ }
5150
+ //#endregion
5151
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isNil.mjs
5152
+ /**
5153
+ * Checks if a given value is null or undefined.
5154
+ *
5155
+ * This function tests whether the provided value is either `null` or `undefined`.
5156
+ * It returns `true` if the value is `null` or `undefined`, and `false` otherwise.
5157
+ *
5158
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `null` or `undefined`.
5159
+ *
5160
+ * @param x - The value to test for null or undefined.
5161
+ * @returns `true` if the value is null or undefined, `false` otherwise.
5162
+ *
5163
+ * @example
5164
+ * const value1 = null;
5165
+ * const value2 = undefined;
5166
+ * const value3 = 42;
5167
+ * const result1 = isNil(value1); // true
5168
+ * const result2 = isNil(value2); // true
5169
+ * const result3 = isNil(value3); // false
5170
+ */
5171
+ function isNil(x) {
5172
+ return x == null;
5173
+ }
5174
+ //#endregion
5175
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/predicate/isString.mjs
5176
+ /**
5177
+ * Checks if a given value is string.
5178
+ *
5179
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to `string`.
5180
+ *
5181
+ * @param value The value to check if it is string.
5182
+ * @returns Returns `true` if `value` is a string, else `false`.
4810
5183
  *
4811
5184
  * @example
4812
5185
  * const value1 = 'abc';
@@ -4821,7 +5194,7 @@ function isString(value) {
4821
5194
  return typeof value === "string";
4822
5195
  }
4823
5196
  //#endregion
4824
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
5197
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
4825
5198
  /**
4826
5199
  * Canonically serializes a column key to a branded string id. Accepts both
4827
5200
  * the new {@link ColumnUniversalKey} and the deprecated {@link UniversalPColumnId}
@@ -4995,7 +5368,7 @@ function extractPObjectId(id) {
4995
5368
  throw new Error(`extractPObjectId: unrecognized column id structure: ${JSON.stringify(id)}`);
4996
5369
  }
4997
5370
  //#endregion
4998
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
5371
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
4999
5372
  function isColumnOverriddenKey(obj) {
5000
5373
  return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
5001
5374
  }
@@ -5117,7 +5490,7 @@ function mergeRecord(a, b) {
5117
5490
  };
5118
5491
  }
5119
5492
  //#endregion
5120
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5493
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5121
5494
  function axisKey(axis) {
5122
5495
  return (0, import_canonicalize.default)(getAxisId(axis));
5123
5496
  }
@@ -5363,7 +5736,7 @@ function isAnchorAxisRef(value) {
5363
5736
  return typeof value === "object" && "anchor" in value;
5364
5737
  }
5365
5738
  //#endregion
5366
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5739
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5367
5740
  /**
5368
5741
  * Determines if an axis ID matches an axis selector.
5369
5742
  *
@@ -5444,7 +5817,7 @@ function legacyColumnSelectorsToPredicate(predicateOrSelectors) {
5444
5817
  else return (spec) => isPColumnSpec(spec) && matchPColumn(spec, predicateOrSelectors);
5445
5818
  }
5446
5819
  //#endregion
5447
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5820
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5448
5821
  function deriveNativeId(spec) {
5449
5822
  const result = {
5450
5823
  kind: spec.kind,
@@ -5456,7 +5829,7 @@ function deriveNativeId(spec) {
5456
5829
  return (0, import_canonicalize.default)(result);
5457
5830
  }
5458
5831
  //#endregion
5459
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5832
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5460
5833
  var LinkerMap = class LinkerMap {
5461
5834
  /** Graph of linkers connected by axes (single or grouped by parents) */
5462
5835
  data;
@@ -5591,7 +5964,6 @@ var LinkerMap = class LinkerMap {
5591
5964
  switch (axesSpec.length) {
5592
5965
  case 0: return [];
5593
5966
  case 1: return [[axesSpec[0]]];
5594
- default: break;
5595
5967
  }
5596
5968
  const axisKeys = axesSpec.map((spec) => canonicalizeJson(getAxisId(spec)));
5597
5969
  const axisParentsIdxs = axesSpec.map((spec) => new Set(spec.parentAxesSpec.map((spec) => canonicalizeJson(getAxisId(spec))).map((el) => {
@@ -5634,7 +6006,7 @@ var LinkerMap = class LinkerMap {
5634
6006
  }
5635
6007
  };
5636
6008
  //#endregion
5637
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
6009
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5638
6010
  /**
5639
6011
  * Required PFrames version. Bump this in lockstep with the `@milaboratories/pframes-rs-*`
5640
6012
  * version in `pnpm-workspace.yaml` so blocks built against the new SDK refuse to load on
@@ -5677,7 +6049,7 @@ function withEnrichments(ref, requireEnrichments = true) {
5677
6049
  }
5678
6050
  }
5679
6051
  //#endregion
5680
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
6052
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5681
6053
  function mapValueInVOE(voe, cb) {
5682
6054
  return voe.ok ? {
5683
6055
  ok: true,
@@ -5685,7 +6057,7 @@ function mapValueInVOE(voe, cb) {
5685
6057
  } : voe;
5686
6058
  }
5687
6059
  //#endregion
5688
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
6060
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
5689
6061
  /** Well-known resource type names used across the platform. */
5690
6062
  const ResourceTypeName = {
5691
6063
  StreamManager: "StreamManager",
@@ -5729,7 +6101,7 @@ const ResourceTypeName = {
5729
6101
  SharedEnvelope: "SharedEnvelope"
5730
6102
  };
5731
6103
  //#endregion
5732
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
6104
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5733
6105
  const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
5734
6106
  const { service, isNodeService, isWasmService, isMainService, getServiceKind, getServiceModelMethods, getServiceUiMethods } = (() => {
5735
6107
  const typeMap = /* @__PURE__ */ new Map();
@@ -5768,7 +6140,7 @@ const { service, isNodeService, isWasmService, isMainService, getServiceKind, ge
5768
6140
  };
5769
6141
  })();
5770
6142
  //#endregion
5771
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
6143
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5772
6144
  const Services = {
5773
6145
  PFrameSpec: service()({
5774
6146
  type: "wasm",
@@ -5862,7 +6234,7 @@ function resolveRequiredServices(flags) {
5862
6234
  }
5863
6235
  Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
5864
6236
  //#endregion
5865
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
6237
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
5866
6238
  function buildMethodMap(pick) {
5867
6239
  const result = {};
5868
6240
  for (const id of Object.values(Services)) result[id] = [...pick(id)];
@@ -5871,7 +6243,7 @@ function buildMethodMap(pick) {
5871
6243
  buildMethodMap(getServiceUiMethods);
5872
6244
  buildMethodMap(getServiceModelMethods);
5873
6245
  //#endregion
5874
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
6246
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
5875
6247
  /** Resource types that hold column collections — DFS stops here and collects. */
5876
6248
  const COLLECT_TYPES = [ResourceTypeName.PFrame];
5877
6249
  /** Resource types DFS descends through when looking for PFrames. */
@@ -5979,7 +6351,7 @@ function indexPoolBlock(block) {
5979
6351
  return result;
5980
6352
  }
5981
6353
  //#endregion
5982
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6354
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
5983
6355
  /**
5984
6356
  * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
5985
6357
  * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
@@ -6016,7 +6388,48 @@ var ColumnRegistry = class {
6016
6388
  }
6017
6389
  };
6018
6390
  //#endregion
6019
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6391
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
6392
+ /**
6393
+ * Two-track dedup over an item stream keyed by `ColumnUniversalId`:
6394
+ *
6395
+ * - **Raw `PObjectId`s** are deduped by `deriveNativeId(spec)`. The same
6396
+ * physical column reached via outputs vs. result_pool has different
6397
+ * id shapes but identical nativeId — first occurrence wins so the
6398
+ * provider order (outputs before pool) decides which id is canonical.
6399
+ * - **Non-`PObjectId` ids** (e.g. `SUniversalPColumnUniversalId`,
6400
+ * `ColumnDiscoveredId`) keep raw-id dedup — they legitimately share
6401
+ * nativeId with siblings.
6402
+ *
6403
+ * When `getSpec` returns `undefined` for a `PObjectId`, falls back to raw-id
6404
+ * dedup (so an unresolvable id still survives instead of dropping silently).
6405
+ *
6406
+ * Shared by sandbox-side `extractColumns` (column_providers) and host-side
6407
+ * `ColumnsCollectionDriverImpl.getColumns` — both layers need identical
6408
+ * dedup semantics, but operate on different concrete item types (DataColumnRecipe
6409
+ * vs. raw ColumnUniversalId).
6410
+ */
6411
+ function dedupColumns(items, getId, getSpec) {
6412
+ const seenNative = /* @__PURE__ */ new Set();
6413
+ const seenId = /* @__PURE__ */ new Set();
6414
+ const out = [];
6415
+ for (const item of items) {
6416
+ const id = getId(item);
6417
+ if (seenId.has(id)) continue;
6418
+ if (isPObjectId(id)) {
6419
+ const spec = getSpec(item);
6420
+ if (spec !== void 0) {
6421
+ const nativeId = deriveNativeId(spec);
6422
+ if (seenNative.has(nativeId)) continue;
6423
+ seenNative.add(nativeId);
6424
+ }
6425
+ }
6426
+ seenId.add(id);
6427
+ out.push(item);
6428
+ }
6429
+ return out;
6430
+ }
6431
+ //#endregion
6432
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6020
6433
  /**
6021
6434
  * Generic entries provider over a single accessor root. Walks `<root>` once
6022
6435
  * from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
@@ -6073,7 +6486,7 @@ var ResultPoolEntriesProvider = class {
6073
6486
  }
6074
6487
  };
6075
6488
  //#endregion
6076
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6489
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6077
6490
  /**
6078
6491
  * Whether `value` is a reference in the readable spelling.
6079
6492
  *
@@ -6142,7 +6555,7 @@ function expandTemplatePlRef(ref) {
6142
6555
  };
6143
6556
  }
6144
6557
  //#endregion
6145
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.48.0/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6558
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6146
6559
  /**
6147
6560
  * Point every column identifier in a block's params at the blocks of the project being built.
6148
6561
  *
@@ -6158,8 +6571,13 @@ function expandTemplatePlRef(ref) {
6158
6571
  *
6159
6572
  * Rewriting is structural, never textual: an identifier is taken apart, its `blockId` fields
6160
6573
  * are replaced, and it is rebuilt canonically. That is what keeps a value that merely *looks*
6161
- * like an id — a `domain` entry, an axis filter — from being rewritten along with it, and
6162
- * what re-sorts a qualifications map whose keys are identifiers.
6574
+ * like an id — an axis filter, a domain this package can see belongs to an identifier it
6575
+ * knows — from being rewritten along with it, and what re-sorts a qualifications map whose
6576
+ * keys are identifiers.
6577
+ *
6578
+ * A domain reached on its own is the exception, and `relocateDomain` below says why: an axis is
6579
+ * qualified by the block that produced it. Only the domain keys known to name a block are
6580
+ * repointed — matching an entry id is not on its own evidence of a reference.
6163
6581
  *
6164
6582
  * An id the map does not mention is left as it is. That is the ordering rule doing its work:
6165
6583
  * a caller building the map as it creates blocks passes only the entries already created, so
@@ -6177,13 +6595,27 @@ function relocateBlockIds(params, blockIds) {
6177
6595
  if (typeof node === "string") return remapColumnIdBlockIds(node, remapBlockId);
6178
6596
  if (isColumnUniversalKey(node)) return remapColumnIdBlockIds(node, remapBlockId);
6179
6597
  if (Array.isArray(node)) return node.map(walk);
6180
- if (typeof node === "object" && node !== null) return Object.fromEntries(Object.entries(node).map(([key, value]) => [remapColumnIdBlockIds(key, remapBlockId), walk(value)]));
6598
+ if (typeof node === "object" && node !== null) return Object.fromEntries(Object.entries(node).map(([key, value]) => [remapColumnIdBlockIds(key, remapBlockId), key === "domain" && isPlainObject(value) ? relocateDomain(value) : walk(value)]));
6181
6599
  return node;
6182
6600
  };
6601
+ /**
6602
+ * The block-naming entries of a domain, repointed at the project being built: an axis a block
6603
+ * produced names that block in its domain, so those are references like any other.
6604
+ *
6605
+ * Only the keys {@link BlockScopedDomain} lists, because a template's entry ids are arbitrary
6606
+ * non-empty strings — a hand-written template may name an entry `closest`, and a qualifier
6607
+ * reading `closest` is not a reference to it. Matching the map is not on its own enough to
6608
+ * tell one from the other; the key is.
6609
+ *
6610
+ * Reached only from the generic object case — inside an identifier this package recognizes a
6611
+ * domain is spec data and stays as it is, which is what keeps an overridden column's
6612
+ * `specOverrides.domain` untouched.
6613
+ */
6614
+ const relocateDomain = (domain) => Object.fromEntries(Object.entries(domain).map(([key, value]) => [key, typeof value === "string" && BlockScopedDomain.has(key) ? remapBlockId(value) : walk(value)]));
6183
6615
  return walk(params);
6184
6616
  }
6185
6617
  //#endregion
6186
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/block_migrations.js
6618
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_migrations.js
6187
6619
  /** Create a DataVersioned wrapper with correct shape */
6188
6620
  function makeVersionedData(version, data) {
6189
6621
  return {
@@ -6761,7 +7193,7 @@ var DataModel = class DataModel {
6761
7193
  }
6762
7194
  };
6763
7195
  //#endregion
6764
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/internal.js
7196
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/internal.js
6765
7197
  /** Utility code helping to identify whether the code is running in actual UI environment */
6766
7198
  function isInUI() {
6767
7199
  return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
@@ -6831,7 +7263,7 @@ function registerFutureAwait(handle, onResolve) {
6831
7263
  futureResolves.get(handle).push(onResolve);
6832
7264
  }
6833
7265
  //#endregion
6834
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
7266
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
6835
7267
  /**
6836
7268
  * All facade callback names as constants.
6837
7269
  * These are the source of truth - the interface is derived from these.
@@ -6869,7 +7301,23 @@ function registerFacadeCallbacks(callbacks) {
6869
7301
  for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
6870
7302
  }
6871
7303
  //#endregion
6872
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/future.js
7304
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/services/block_services.js
7305
+ /**
7306
+ * Services required by all V3 blocks by default.
7307
+ * Edit this when a new service should be available to all blocks.
7308
+ *
7309
+ * Standalone module to avoid circular dependencies between block_model.ts
7310
+ * and service type resolution.
7311
+ */
7312
+ const BLOCK_SERVICE_FLAGS = {
7313
+ requiresPFrameSpec: true,
7314
+ requiresPFrame: true,
7315
+ requiresDialog: true,
7316
+ requiresColumnsCollection: true
7317
+ };
7318
+ resolveRequiredServices(BLOCK_SERVICE_FLAGS);
7319
+ //#endregion
7320
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/future.js
6873
7321
  var FutureRef = class FutureRef {
6874
7322
  handle;
6875
7323
  postProcess;
@@ -6897,7 +7345,7 @@ var FutureRef = class FutureRef {
6897
7345
  }
6898
7346
  };
6899
7347
  //#endregion
6900
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/accessor.js
7348
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/accessor.js
6901
7349
  function ifDef(value, cb) {
6902
7350
  return value === void 0 ? void 0 : cb(value);
6903
7351
  }
@@ -7147,11 +7595,11 @@ var TreeNodeAccessor = class TreeNodeAccessor {
7147
7595
  }
7148
7596
  };
7149
7597
  //#endregion
7150
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/internal.js
7598
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/internal.js
7151
7599
  const MainAccessorName = "main";
7152
7600
  const StagingAccessorName = "staging";
7153
7601
  //#endregion
7154
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7602
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7155
7603
  function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7156
7604
  const sortedFilters = [...axisFilters].sort((a, b) => b[0] - a[0]);
7157
7605
  const { type } = dataInfoEntries;
@@ -7215,7 +7663,7 @@ function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7215
7663
  }
7216
7664
  }
7217
7665
  //#endregion
7218
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7666
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7219
7667
  /**
7220
7668
  * Structural postfix derivation for linked columns (phase 2 of `deriveDistinctLabels`).
7221
7669
  *
@@ -7398,7 +7846,7 @@ function derivePostfixes(entries, format = defaultLinkerFormatter) {
7398
7846
  });
7399
7847
  }
7400
7848
  //#endregion
7401
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7849
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7402
7850
  const DISTANCE_PENALTY = .001;
7403
7851
  const LABEL_TYPE = "__LABEL__";
7404
7852
  const LABEL_TYPE_FULL = "__LABEL__@1";
@@ -7686,7 +8134,7 @@ function repairBareByPresence(labels, minimized, records, stats, forcedSet, forc
7686
8134
  return patched;
7687
8135
  }
7688
8136
  //#endregion
7689
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/util/label.js
8137
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/label.js
7690
8138
  /** @deprecated Use deriveDistinctLabels */
7691
8139
  function deriveLabels(values, getSpec, options = {}) {
7692
8140
  return deriveDistinctLabels(values.map(getSpec), options).map((label, i) => ({
@@ -7695,7 +8143,7 @@ function deriveLabels(values, getSpec, options = {}) {
7695
8143
  }));
7696
8144
  }
7697
8145
  //#endregion
7698
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
8146
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
7699
8147
  const RT_RESOURCE_MAP = "PColumnData/ResourceMap";
7700
8148
  const RT_RESOURCE_MAP_PARTITIONED = "PColumnData/Partitioned/ResourceMap";
7701
8149
  const RT_JSON_PARTITIONED = "PColumnData/JsonPartitioned";
@@ -7736,9 +8184,7 @@ function getPartitionKeysList(acc) {
7736
8184
  break;
7737
8185
  case RT_BINARY_SUPER_PARTITIONED:
7738
8186
  case RT_JSON_SUPER_PARTITIONED:
7739
- case RT_PARQUET_SUPER_PARTITIONED:
7740
- keyLength = meta["superPartitionKeyLength"] + meta["partitionKeyLength"];
7741
- break;
8187
+ case RT_PARQUET_SUPER_PARTITIONED: keyLength = meta["superPartitionKeyLength"] + meta["partitionKeyLength"];
7742
8188
  }
7743
8189
  switch (rt) {
7744
8190
  case RT_RESOURCE_MAP:
@@ -7754,20 +8200,18 @@ function getPartitionKeysList(acc) {
7754
8200
  case RT_RESOURCE_MAP_PARTITIONED:
7755
8201
  case RT_BINARY_SUPER_PARTITIONED:
7756
8202
  case RT_JSON_SUPER_PARTITIONED:
7757
- case RT_PARQUET_SUPER_PARTITIONED:
7758
- for (const supKeyStr of acc.listInputFields()) {
7759
- const keyPrefix = [...JSON.parse(supKeyStr)];
7760
- const value = acc.resolve({
7761
- field: supKeyStr,
7762
- assertFieldType: "Input"
7763
- });
7764
- if (value !== void 0) for (let keyStr of value.listInputFields()) {
7765
- if (rt === "PColumnData/Partitioned/BinaryPartitioned") keyStr = removeIndexSuffix(keyStr).baseKey;
7766
- const key = [...keyPrefix, ...JSON.parse(keyStr)];
7767
- data.push(key);
7768
- }
8203
+ case RT_PARQUET_SUPER_PARTITIONED: for (const supKeyStr of acc.listInputFields()) {
8204
+ const keyPrefix = [...JSON.parse(supKeyStr)];
8205
+ const value = acc.resolve({
8206
+ field: supKeyStr,
8207
+ assertFieldType: "Input"
8208
+ });
8209
+ if (value !== void 0) for (let keyStr of value.listInputFields()) {
8210
+ if (rt === "PColumnData/Partitioned/BinaryPartitioned") keyStr = removeIndexSuffix(keyStr).baseKey;
8211
+ const key = [...keyPrefix, ...JSON.parse(keyStr)];
8212
+ data.push(key);
7769
8213
  }
7770
- break;
8214
+ }
7771
8215
  }
7772
8216
  return {
7773
8217
  data,
@@ -7993,7 +8437,7 @@ function allPColumnsReady(columns) {
7993
8437
  return columns.every(isPColumnReady);
7994
8438
  }
7995
8439
  //#endregion
7996
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
8440
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
7997
8441
  function isPColumnValues(value) {
7998
8442
  if (!Array.isArray(value)) return false;
7999
8443
  if (value.length === 0) return true;
@@ -8271,23 +8715,7 @@ var PColumnCollection = class {
8271
8715
  }
8272
8716
  };
8273
8717
  //#endregion
8274
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/services/block_services.js
8275
- /**
8276
- * Services required by all V3 blocks by default.
8277
- * Edit this when a new service should be available to all blocks.
8278
- *
8279
- * Standalone module to avoid circular dependencies between block_model.ts
8280
- * and service type resolution.
8281
- */
8282
- const BLOCK_SERVICE_FLAGS = {
8283
- requiresPFrameSpec: true,
8284
- requiresPFrame: true,
8285
- requiresDialog: true,
8286
- requiresColumnsCollection: true
8287
- };
8288
- resolveRequiredServices(BLOCK_SERVICE_FLAGS);
8289
- //#endregion
8290
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8718
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8291
8719
  /**
8292
8720
  * Builds a ServiceProxy from a ServiceDispatch.
8293
8721
  * Each service method call is forwarded to dispatch.callServiceMethod.
@@ -8296,7 +8724,7 @@ function createServiceProxy(dispatch) {
8296
8724
  return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
8297
8725
  }
8298
8726
  //#endregion
8299
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/services/get_services.js
8727
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/services/get_services.js
8300
8728
  const cachedServices = /* @__PURE__ */ new WeakMap();
8301
8729
  function getService(name, deps) {
8302
8730
  const ctx = deps?.ctx ?? getCfgRenderCtx();
@@ -8310,7 +8738,7 @@ function getService(name, deps) {
8310
8738
  })();
8311
8739
  }
8312
8740
  //#endregion
8313
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8741
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8314
8742
  function patchInSetFilters(filters) {
8315
8743
  const inSetToOrEqual = (predicate) => {
8316
8744
  if (predicate.operator !== "InSet") return predicate;
@@ -8348,7 +8776,7 @@ function patchInSetFilters(filters) {
8348
8776
  return filters.map((filter) => mapFilter(filter, inSetToOrEqual));
8349
8777
  }
8350
8778
  //#endregion
8351
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/render/api.js
8779
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/api.js
8352
8780
  /**
8353
8781
  * Helper function to match domain objects
8354
8782
  * @param query Optional domain to match against
@@ -8797,27 +9225,27 @@ var PluginRenderCtx = class extends RenderCtxBase {
8797
9225
  }
8798
9226
  };
8799
9227
  //#endregion
8800
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/version.js
8801
- const PlatformaSDKVersion = "1.82.0";
9228
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/plugin_model.js
9229
+ /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
9230
+ * identical across multiple `@platforma-sdk/model` copies in one process. */
9231
+ const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
9232
+ //#endregion
9233
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/version.js
9234
+ const PlatformaSDKVersion = "1.84.1";
8802
9235
  //#endregion
8803
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/bconfig/types.js
9236
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/bconfig/types.js
8804
9237
  function isConfigLambda(cfgOrFh) {
8805
9238
  return cfgOrFh.__renderLambda === true;
8806
9239
  }
8807
9240
  //#endregion
8808
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
9241
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
8809
9242
  function downgradeCfgOrLambda(data) {
8810
9243
  if (data === void 0) return void 0;
8811
9244
  if (isConfigLambda(data)) return data.handle;
8812
9245
  return data;
8813
9246
  }
8814
9247
  //#endregion
8815
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/plugin_model.js
8816
- /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
8817
- * identical across multiple `@platforma-sdk/model` copies in one process. */
8818
- const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
8819
- //#endregion
8820
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
9248
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
8821
9249
  /**
8822
9250
  * BlockStorage Callback Implementations - wired to facade callbacks in BlockModelV3.done().
8823
9251
  *
@@ -9171,7 +9599,7 @@ function deriveTemplateParamsFromStorage(storageJson, deriveTemplateParams) {
9171
9599
  }
9172
9600
  }
9173
9601
  //#endregion
9174
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/block_model.js
9602
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_model.js
9175
9603
  /**
9176
9604
  * Merges two feature flag objects with type-aware logic:
9177
9605
  * - `supports*` (boolean): OR — `true` if either side is `true`
@@ -9537,7 +9965,7 @@ var BlockModelV3 = class BlockModelV3 {
9537
9965
  }
9538
9966
  };
9539
9967
  //#endregion
9540
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9968
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9541
9969
  /** Create id for column copy with added keys in axes domains */
9542
9970
  const colId = (id, domains, contextDomains) => {
9543
9971
  let wid = id.toString();
@@ -9643,7 +10071,7 @@ function getAdditionalColumnsForColumn(blockAxes, column) {
9643
10071
  })];
9644
10072
  }
9645
10073
  //#endregion
9646
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
10074
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
9647
10075
  /**
9648
10076
  * Replace every column leaf whose id equals `fromId` with `toId`, leaving
9649
10077
  * other column refs (linkers, sub-anchors) intact. Wrapper recipes
@@ -9661,29 +10089,38 @@ function rebrandLeafId(node, fromId, toId) {
9661
10089
  return mapSpecQueryColumns(node, { column: (id) => id === fromId ? toId : id });
9662
10090
  }
9663
10091
  //#endregion
9664
- //#region ../node_modules/.pnpm/lru-cache@11.5.1/node_modules/lru-cache/dist/esm/browser/index.min.js
9665
- var L = { hasSubscribers: !1 }, S = L, W = L;
10092
+ //#region ../node_modules/.pnpm/lru-cache@11.5.3/node_modules/lru-cache/dist/esm/browser/index.min.js
10093
+ var L = { hasSubscribers: !1 };
10094
+ var S = L;
10095
+ var W = L;
9666
10096
  var M = typeof performance == "object" && performance && typeof performance.now == "function" ? performance : Date;
9667
- var D = () => S.hasSubscribers || W.hasSubscribers, j = /* @__PURE__ */ new Set(), I = typeof process == "object" && process ? process : {}, P = (u, e, t, i) => {
9668
- typeof I.emitWarning == "function" ? I.emitWarning(u, e, t, i) : console.error(`[${t}] ${e}: ${u}`);
9669
- }, k = (u) => !j.has(u);
9670
- var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(u) ? u <= Math.pow(2, 8) ? Uint8Array : u <= Math.pow(2, 16) ? Uint16Array : u <= Math.pow(2, 32) ? Uint32Array : u <= Number.MAX_SAFE_INTEGER ? O : null : null, O = class extends Array {
10097
+ var R = () => S.hasSubscribers || W.hasSubscribers;
10098
+ var j = /* @__PURE__ */ new Set();
10099
+ var I = typeof process == "object" && process ? process : {};
10100
+ var P = (d, e, t, i) => {
10101
+ typeof I.emitWarning == "function" ? I.emitWarning(d, e, t, i) : console.error(`[${t}] ${e}: ${d}`);
10102
+ };
10103
+ var k = (d) => !j.has(d);
10104
+ var T = (d) => !!d && d === Math.floor(d) && d > 0 && isFinite(d);
10105
+ var G = (d) => T(d) ? d <= Math.pow(2, 8) ? Uint8Array : d <= Math.pow(2, 16) ? Uint16Array : d <= Math.pow(2, 32) ? Uint32Array : d <= Number.MAX_SAFE_INTEGER ? O : null : null;
10106
+ var O = class extends Array {
9671
10107
  constructor(e) {
9672
10108
  super(e), this.fill(0);
9673
10109
  }
9674
- }, R = class u {
10110
+ };
10111
+ var x = class d {
9675
10112
  heap;
9676
10113
  length;
9677
10114
  static #o = !1;
9678
10115
  static create(e) {
9679
10116
  let t = G(e);
9680
10117
  if (!t) return [];
9681
- u.#o = !0;
9682
- let i = new u(e, t);
9683
- return u.#o = !1, i;
10118
+ d.#o = !0;
10119
+ let i = new d(e, t);
10120
+ return d.#o = !1, i;
9684
10121
  }
9685
10122
  constructor(e, t) {
9686
- if (!u.#o) throw new TypeError("instantiate Stack using Stack.create(n)");
10123
+ if (!d.#o) throw new TypeError("instantiate Stack using Stack.create(n)");
9687
10124
  this.heap = new t(e), this.length = 0;
9688
10125
  }
9689
10126
  push(e) {
@@ -9692,7 +10129,8 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
9692
10129
  pop() {
9693
10130
  return this.heap[--this.length];
9694
10131
  }
9695
- }, U = class u {
10132
+ };
10133
+ var U = class d {
9696
10134
  #o;
9697
10135
  #c;
9698
10136
  #S;
@@ -9738,7 +10176,7 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
9738
10176
  #T;
9739
10177
  #U;
9740
10178
  #f;
9741
- #x;
10179
+ #D;
9742
10180
  static unsafeExposeInternals(e) {
9743
10181
  return {
9744
10182
  starts: e.#F,
@@ -9793,87 +10231,90 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
9793
10231
  return this.#w;
9794
10232
  }
9795
10233
  constructor(e) {
9796
- let { max: t = 0, ttl: i, ttlResolution: s = 1, ttlAutopurge: n, updateAgeOnGet: r, updateAgeOnHas: h, allowStale: a, dispose: o, onInsert: d, disposeAfter: y, noDisposeOnSet: _, noUpdateTTL: c, maxSize: g = 0, maxEntrySize: f = 0, sizeCalculation: b, fetchMethod: l, memoMethod: w, noDeleteOnFetchRejection: F, noDeleteOnStaleGet: m, allowStaleOnFetchRejection: p, allowStaleOnFetchAbort: A, ignoreFetchAbort: z, backgroundFetchSize: C = 1, perf: E } = e;
10234
+ let { max: t = 0, ttl: i, ttlResolution: s = 1, ttlAutopurge: n, updateAgeOnGet: o, updateAgeOnHas: l, allowStale: h, dispose: r, onInsert: c, disposeAfter: m, noDisposeOnSet: _, noUpdateTTL: u, maxSize: g = 0, maxEntrySize: f = 0, sizeCalculation: y, fetchMethod: a, memoMethod: w, noDeleteOnFetchRejection: F, noDeleteOnStaleGet: b, allowStaleOnFetchRejection: p, allowStaleOnFetchAbort: A, ignoreFetchAbort: z, backgroundFetchSize: C = 1, perf: E } = e;
9797
10235
  if (this.backgroundFetchSize = C, E !== void 0 && typeof E?.now != "function") throw new TypeError("perf option must have a now() method if specified");
9798
10236
  if (this.#m = E ?? M, t !== 0 && !T(t)) throw new TypeError("max option must be a nonnegative integer");
9799
10237
  let v = t ? G(t) : Array;
9800
10238
  if (!v) throw new Error("invalid max value: " + t);
9801
- if (this.#o = t, this.#c = g, this.maxEntrySize = f || this.#c, this.sizeCalculation = b, this.sizeCalculation) {
10239
+ if (this.#o = t, this.#c = g, this.maxEntrySize = f || this.#c, this.sizeCalculation = y, this.sizeCalculation) {
9802
10240
  if (!this.#c && !this.maxEntrySize) throw new TypeError("cannot set sizeCalculation without setting maxSize or maxEntrySize");
9803
10241
  if (typeof this.sizeCalculation != "function") throw new TypeError("sizeCalculation set to non-function");
9804
10242
  }
9805
10243
  if (w !== void 0 && typeof w != "function") throw new TypeError("memoMethod must be a function if defined");
9806
- if (this.#I = w, l !== void 0 && typeof l != "function") throw new TypeError("fetchMethod must be a function if specified");
9807
- if (this.#M = l, this.#U = !!l, this.#s = /* @__PURE__ */ new Map(), this.#i = Array.from({ length: t }).fill(void 0), this.#t = Array.from({ length: t }).fill(void 0), this.#l = new v(t), this.#u = new v(t), this.#a = 0, this.#h = 0, this.#y = R.create(t), this.#n = 0, this.#b = 0, typeof o == "function" && (this.#S = o), typeof d == "function" && (this.#O = d), typeof y == "function" ? (this.#w = y, this.#r = []) : (this.#w = void 0, this.#r = void 0), this.#T = !!this.#S, this.#x = !!this.#O, this.#f = !!this.#w, this.noDisposeOnSet = !!_, this.noUpdateTTL = !!c, this.noDeleteOnFetchRejection = !!F, this.allowStaleOnFetchRejection = !!p, this.allowStaleOnFetchAbort = !!A, this.ignoreFetchAbort = !!z, this.maxEntrySize !== 0) {
10244
+ if (this.#I = w, a !== void 0 && typeof a != "function") throw new TypeError("fetchMethod must be a function if specified");
10245
+ if (this.#M = a, this.#U = !!a, this.#s = /* @__PURE__ */ new Map(), this.#i = Array.from({ length: t }).fill(void 0), this.#t = Array.from({ length: t }).fill(void 0), this.#l = new v(t), this.#u = new v(t), this.#a = 0, this.#h = 0, this.#y = x.create(t), this.#n = 0, this.#b = 0, typeof r == "function" && (this.#S = r), typeof c == "function" && (this.#O = c), typeof m == "function" ? (this.#w = m, this.#r = []) : (this.#w = void 0, this.#r = void 0), this.#T = !!this.#S, this.#D = !!this.#O, this.#f = !!this.#w, this.noDisposeOnSet = !!_, this.noUpdateTTL = !!u, this.noDeleteOnFetchRejection = !!F, this.allowStaleOnFetchRejection = !!p, this.allowStaleOnFetchAbort = !!A, this.ignoreFetchAbort = !!z, this.maxEntrySize !== 0) {
9808
10246
  if (this.#c !== 0 && !T(this.#c)) throw new TypeError("maxSize must be a positive integer if specified");
9809
10247
  if (!T(this.maxEntrySize)) throw new TypeError("maxEntrySize must be a positive integer if specified");
9810
10248
  this.#X();
9811
10249
  }
9812
- if (this.allowStale = !!a, this.noDeleteOnStaleGet = !!m, this.updateAgeOnGet = !!r, this.updateAgeOnHas = !!h, this.ttlResolution = T(s) || s === 0 ? s : 1, this.ttlAutopurge = !!n, this.ttl = i || 0, this.ttl) {
10250
+ if (this.allowStale = !!h, this.noDeleteOnStaleGet = !!b, this.updateAgeOnGet = !!o, this.updateAgeOnHas = !!l, this.ttlResolution = T(s) || s === 0 ? s : 1, this.ttlAutopurge = !!n, this.ttl = i || 0, this.ttl) {
9813
10251
  if (!T(this.ttl)) throw new TypeError("ttl must be a positive integer if specified");
9814
10252
  this.#k();
9815
10253
  }
9816
10254
  if (this.#o === 0 && this.ttl === 0 && this.#c === 0) throw new TypeError("At least one of max, maxSize, or ttl is required");
9817
10255
  if (!this.ttlAutopurge && !this.#o && !this.#c) {
9818
- let x = "LRU_CACHE_UNBOUNDED";
9819
- k(x) && (j.add(x), P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.", "UnboundedCacheWarning", x, u));
10256
+ let D = "LRU_CACHE_UNBOUNDED";
10257
+ k(D) && (j.add(D), P("TTL caching without ttlAutopurge, max, or maxSize can result in unbounded memory consumption.", "UnboundedCacheWarning", D, d));
9820
10258
  }
9821
10259
  }
9822
10260
  getRemainingTTL(e) {
9823
- return this.#s.has(e) ? Infinity : 0;
10261
+ return this.#s.has(e) ? 1 / 0 : 0;
9824
10262
  }
9825
10263
  #k() {
9826
10264
  let e = new O(this.#o), t = new O(this.#o);
9827
10265
  this.#d = e, this.#F = t;
9828
10266
  let i = this.ttlAutopurge ? Array.from({ length: this.#o }) : void 0;
9829
- this.#g = i, this.#H = (h, a, o = this.#m.now()) => {
9830
- t[h] = a !== 0 ? o : 0, e[h] = a, s(h, a);
9831
- }, this.#D = (h) => {
10267
+ this.#g = i, this.#H = (h, r, c = this.#m.now()) => {
10268
+ t[h] = r !== 0 ? c : 0, e[h] = r, s(h, r);
10269
+ }, this.#R = (h) => {
9832
10270
  t[h] = e[h] !== 0 ? this.#m.now() : 0, s(h, e[h]);
9833
10271
  };
9834
- let s = this.ttlAutopurge ? (h, a) => {
9835
- if (i?.[h] && (clearTimeout(i[h]), i[h] = void 0), a && a !== 0 && i) {
9836
- let o = setTimeout(() => {
9837
- this.#p(h) && this.#E(this.#i[h], "expire");
9838
- }, a + 1);
9839
- o.unref && o.unref(), i[h] = o;
10272
+ let s = this.ttlAutopurge ? (h, r) => {
10273
+ if (i?.[h] && (clearTimeout(i[h]), i[h] = void 0), r && r !== 0 && i) {
10274
+ let c = setTimeout(() => {
10275
+ this.#p(h) ? (this.#E(this.#i[h], "expire"), i[h] = void 0) : s(h, l(h));
10276
+ }, r + 1);
10277
+ c.unref && c.unref(), i[h] = c;
9840
10278
  }
9841
10279
  } : () => {};
9842
- this.#v = (h, a) => {
9843
- if (e[a]) {
9844
- let o = e[a], d = t[a];
9845
- if (!o || !d) return;
9846
- h.ttl = o, h.start = d, h.now = n || r();
9847
- h.remainingTTL = o - (h.now - d);
10280
+ this.#v = (h, r) => {
10281
+ if (e[r]) {
10282
+ let c = e[r], m = t[r];
10283
+ if (!c || !m) return;
10284
+ h.ttl = c, h.start = m, h.now = n || o();
10285
+ h.remainingTTL = c - (h.now - m);
9848
10286
  }
9849
10287
  };
9850
- let n = 0, r = () => {
10288
+ let n = 0, o = () => {
9851
10289
  let h = this.#m.now();
9852
10290
  if (this.ttlResolution > 0) {
9853
10291
  n = h;
9854
- let a = setTimeout(() => n = 0, this.ttlResolution);
9855
- a.unref && a.unref();
10292
+ let r = setTimeout(() => n = 0, this.ttlResolution);
10293
+ r.unref && r.unref();
9856
10294
  }
9857
10295
  return h;
9858
10296
  };
9859
10297
  this.getRemainingTTL = (h) => {
9860
- let a = this.#s.get(h);
9861
- if (a === void 0) return 0;
9862
- let o = e[a], d = t[a];
9863
- if (!o || !d) return Infinity;
9864
- return o - ((n || r()) - d);
9865
- }, this.#p = (h) => {
9866
- let a = t[h], o = e[h];
9867
- return !!o && !!a && (n || r()) - a > o;
10298
+ let r = this.#s.get(h);
10299
+ return r === void 0 ? 0 : l(r);
10300
+ };
10301
+ let l = (h) => {
10302
+ let r = e[h], c = t[h];
10303
+ if (!r || !c) return 1 / 0;
10304
+ return r - ((n || o()) - c);
10305
+ };
10306
+ this.#p = (h) => {
10307
+ let r = t[h], c = e[h];
10308
+ return !!c && !!r && (n || o()) - r > c;
9868
10309
  };
9869
10310
  }
9870
- #D = () => {};
10311
+ #R = () => {};
9871
10312
  #v = () => {};
9872
10313
  #H = () => {};
9873
10314
  #p = () => !1;
9874
10315
  #X() {
9875
10316
  let e = new O(this.#o);
9876
- this.#b = 0, this.#_ = e, this.#R = (t) => {
10317
+ this.#b = 0, this.#_ = e, this.#x = (t) => {
9877
10318
  this.#b -= e[t], e[t] = 0;
9878
10319
  }, this.#N = (t, i, s, n) => {
9879
10320
  if (!T(s)) {
@@ -9892,7 +10333,7 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
9892
10333
  this.#b += e[t], s && (s.entrySize = i, s.totalCalculatedSize = this.#b);
9893
10334
  };
9894
10335
  }
9895
- #R = (e) => {};
10336
+ #x = (e) => {};
9896
10337
  #j = (e, t, i) => {};
9897
10338
  #N = (e, t, i, s) => {
9898
10339
  if (i || s) throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
@@ -9965,8 +10406,8 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
9965
10406
  if (s === void 0) return;
9966
10407
  let n = { value: s };
9967
10408
  if (this.#d && this.#F) {
9968
- let r = this.#d[t], h = this.#F[t];
9969
- if (r && h) n.ttl = r - (this.#m.now() - h), n.start = Date.now();
10409
+ let o = this.#d[t], l = this.#F[t];
10410
+ if (o && l) n.ttl = o - (this.#m.now() - l), n.start = Date.now();
9970
10411
  }
9971
10412
  return this.#_ && (n.size = this.#_[t]), n;
9972
10413
  }
@@ -9975,13 +10416,13 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
9975
10416
  for (let t of this.#A({ allowStale: !0 })) {
9976
10417
  let i = this.#i[t], s = this.#t[t], n = this.#e(s) ? s.__staleWhileFetching : s;
9977
10418
  if (n === void 0 || i === void 0) continue;
9978
- let r = { value: n };
10419
+ let o = { value: n };
9979
10420
  if (this.#d && this.#F) {
9980
- r.ttl = this.#d[t];
9981
- let h = this.#m.now() - this.#F[t];
9982
- r.start = Math.floor(Date.now() - h);
10421
+ o.ttl = this.#d[t];
10422
+ let l = this.#m.now() - this.#F[t];
10423
+ o.start = Math.floor(Date.now() - l);
9983
10424
  }
9984
- this.#_ && (r.size = this.#_[t]), e.unshift([i, r]);
10425
+ this.#_ && (o.size = this.#_[t]), e.unshift([i, o]);
9985
10426
  }
9986
10427
  return e;
9987
10428
  }
@@ -10002,19 +10443,19 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10002
10443
  return s && S.hasSubscribers && S.publish(s), n;
10003
10444
  }
10004
10445
  #W(e, t, i, s) {
10005
- let { ttl: n = this.ttl, start: r, noDisposeOnSet: h = this.noDisposeOnSet, sizeCalculation: a = this.sizeCalculation, status: o } = i, d = this.#e(t);
10006
- if (t === void 0) return o && (o.set = "deleted"), this.delete(e), this;
10007
- let { noUpdateTTL: y = this.noUpdateTTL } = i;
10008
- o && !d && (o.value = t);
10009
- let _ = this.#N(e, t, i.size || 0, a, o);
10010
- if (this.maxEntrySize && _ > this.maxEntrySize) return this.#E(e, "set"), o && (o.set = "miss", o.maxEntrySizeExceeded = !0), this;
10011
- let c = this.#n === 0 ? void 0 : this.#s.get(e);
10012
- if (c === void 0) c = this.#n === 0 ? this.#h : this.#y.length !== 0 ? this.#y.pop() : this.#n === this.#o ? this.#G(!1) : this.#n, this.#i[c] = e, this.#t[c] = t, this.#s.set(e, c), this.#l[this.#h] = c, this.#u[c] = this.#h, this.#h = c, this.#n++, this.#j(c, _, o), o && (o.set = "add"), y = !1, this.#x && !d && this.#O?.(t, e, "add");
10446
+ let { ttl: n = this.ttl, start: o, noDisposeOnSet: l = this.noDisposeOnSet, sizeCalculation: h = this.sizeCalculation, status: r } = i, c = this.#e(t);
10447
+ if (t === void 0) return r && (r.set = "deleted"), this.delete(e), this;
10448
+ let { noUpdateTTL: m = this.noUpdateTTL } = i;
10449
+ r && !c && (r.value = t);
10450
+ let _ = this.#N(e, t, i.size || 0, h, r);
10451
+ if (this.maxEntrySize && _ > this.maxEntrySize) return this.#E(e, "set"), r && (r.set = "miss", r.maxEntrySizeExceeded = !0), this;
10452
+ let u = this.#n === 0 ? void 0 : this.#s.get(e);
10453
+ if (u === void 0) u = this.#n === 0 ? this.#h : this.#y.length !== 0 ? this.#y.pop() : this.#n === this.#o ? this.#G(!1) : this.#n, this.#i[u] = e, this.#t[u] = t, this.#s.set(e, u), this.#l[this.#h] = u, this.#u[u] = this.#h, this.#h = u, this.#n++, this.#j(u, _, r), r && (r.set = "add"), m = !1, this.#D && !c && this.#O?.(t, e, "add");
10013
10454
  else {
10014
- this.#L(c);
10015
- let g = this.#t[c];
10455
+ this.#L(u);
10456
+ let g = this.#t[u];
10016
10457
  if (t !== g) {
10017
- if (!h) if (this.#e(g)) {
10458
+ if (!l) if (this.#e(g)) {
10018
10459
  g !== s && g.__abortController.abort(/* @__PURE__ */ new Error("replaced"));
10019
10460
  let { __staleWhileFetching: f } = g;
10020
10461
  f !== void 0 && f !== t && (this.#T && this.#S?.(f, e, "set"), this.#f && this.#r?.push([
@@ -10027,13 +10468,13 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10027
10468
  e,
10028
10469
  "set"
10029
10470
  ]);
10030
- if (this.#R(c), this.#j(c, _, o), this.#t[c] = t, !d) {
10031
- let f = g && this.#e(g) ? g.__staleWhileFetching : g, b = f === void 0 ? "add" : t !== f ? "replace" : "update";
10032
- o && (o.set = b, f !== void 0 && (o.oldValue = f)), this.#x && this.onInsert?.(t, e, b);
10471
+ if (this.#x(u), this.#j(u, _, r), this.#t[u] = t, !c) {
10472
+ let f = g && this.#e(g) ? g.__staleWhileFetching : g, y = f === void 0 ? "add" : t !== f ? "replace" : "update";
10473
+ r && (r.set = y, f !== void 0 && (r.oldValue = f)), this.#D && this.onInsert?.(t, e, y);
10033
10474
  }
10034
- } else d || (o && (o.set = "update"), this.#x && this.onInsert?.(t, e, "update"));
10475
+ } else c || (r && (r.set = "update"), this.#D && this.onInsert?.(t, e, "update"));
10035
10476
  }
10036
- if (n !== 0 && !this.#d && this.#k(), this.#d && (y || this.#H(c, n, r), o && this.#v(o, c)), !h && this.#f && this.#r) {
10477
+ if (n !== 0 && !this.#d && this.#k(), this.#d && (m || this.#H(u, n, o), r && this.#v(r, u)), !l && this.#f && this.#r) {
10037
10478
  let g = this.#r, f;
10038
10479
  for (; f = g?.shift();) this.#w?.(...f);
10039
10480
  }
@@ -10057,12 +10498,12 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10057
10498
  #G(e) {
10058
10499
  let t = this.#a, i = this.#i[t], s = this.#t[t], n = this.#e(s);
10059
10500
  n && s.__abortController.abort(/* @__PURE__ */ new Error("evicted"));
10060
- let r = n ? s.__staleWhileFetching : s;
10061
- return (this.#T || this.#f) && r !== void 0 && (this.#T && this.#S?.(r, i, "evict"), this.#f && this.#r?.push([
10062
- r,
10501
+ let o = n ? s.__staleWhileFetching : s;
10502
+ return (this.#T || this.#f) && o !== void 0 && (this.#T && this.#S?.(o, i, "evict"), this.#f && this.#r?.push([
10503
+ o,
10063
10504
  i,
10064
10505
  "evict"
10065
- ])), this.#R(t), this.#g?.[t] && (clearTimeout(this.#g[t]), this.#g[t] = void 0), e && (this.#i[t] = void 0, this.#t[t] = void 0, this.#y.push(t)), this.#n === 1 ? (this.#a = this.#h = 0, this.#y.length = 0) : this.#a = this.#l[t], this.#s.delete(i), this.#n--, t;
10506
+ ])), this.#x(t), this.#g?.[t] && (clearTimeout(this.#g[t]), this.#g[t] = void 0), e && (this.#i[t] = void 0, this.#t[t] = void 0, this.#y.push(t)), this.#n === 1 ? (this.#a = this.#h = 0, this.#y.length = 0) : this.#a = this.#l[t], this.#s.delete(i), this.#n--, t;
10066
10507
  }
10067
10508
  has(e, t = {}) {
10068
10509
  let { status: i = S.hasSubscribers ? {} : void 0 } = t;
@@ -10073,15 +10514,15 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10073
10514
  #Y(e, t = {}) {
10074
10515
  let { updateAgeOnHas: i = this.updateAgeOnHas, status: s } = t, n = this.#s.get(e);
10075
10516
  if (n !== void 0) {
10076
- let r = this.#t[n];
10077
- if (this.#e(r) && r.__staleWhileFetching === void 0) return !1;
10517
+ let o = this.#t[n];
10518
+ if (this.#e(o) && o.__staleWhileFetching === void 0) return !1;
10078
10519
  if (this.#p(n)) s && (s.has = "stale", this.#v(s, n));
10079
- else return i && this.#D(n), s && (s.has = "hit", this.#v(s, n)), !0;
10520
+ else return i && this.#R(n), s && (s.has = "hit", this.#v(s, n)), !0;
10080
10521
  } else s && (s.has = "miss");
10081
10522
  return !1;
10082
10523
  }
10083
10524
  peek(e, t = {}) {
10084
- let { status: i = D() ? {} : void 0 } = t;
10525
+ let { status: i = R() ? {} : void 0 } = t;
10085
10526
  i && (i.op = "peek", i.key = e, i.cache = this), t.status = i;
10086
10527
  let s = this.#J(e, t);
10087
10528
  return S.hasSubscribers && S.publish(i), s;
@@ -10092,41 +10533,41 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10092
10533
  i && (i.peek = n === void 0 ? "miss" : "stale");
10093
10534
  return;
10094
10535
  }
10095
- let r = this.#t[n], h = this.#e(r) ? r.__staleWhileFetching : r;
10096
- return i && (h !== void 0 ? (i.peek = "hit", i.value = h) : i.peek = "miss"), h;
10536
+ let o = this.#t[n], l = this.#e(o) ? o.__staleWhileFetching : o;
10537
+ return i && (l !== void 0 ? (i.peek = "hit", i.value = l) : i.peek = "miss"), l;
10097
10538
  }
10098
10539
  #P(e, t, i, s) {
10099
10540
  let n = t === void 0 ? void 0 : this.#t[t];
10100
10541
  if (this.#e(n)) return n;
10101
- let r = new AbortController(), { signal: h } = i;
10102
- h?.addEventListener("abort", () => r.abort(h.reason), { signal: r.signal });
10103
- let a = {
10104
- signal: r.signal,
10542
+ let o = new AbortController(), { signal: l } = i;
10543
+ l?.addEventListener("abort", () => o.abort(l.reason), { signal: o.signal });
10544
+ let h = {
10545
+ signal: o.signal,
10105
10546
  options: i,
10106
10547
  context: s
10107
- }, o = (f, b = !1) => {
10108
- let { aborted: l } = r.signal, w = i.ignoreFetchAbort && f !== void 0, F = i.ignoreFetchAbort || !!(i.allowStaleOnFetchAbort && f !== void 0);
10109
- if (i.status && (l && !b ? (i.status.fetchAborted = !0, i.status.fetchError = r.signal.reason, w && (i.status.fetchAbortIgnored = !0)) : i.status.fetchResolved = !0), l && !w && !b) return y(r.signal.reason, F);
10110
- let m = c, p = this.#t[t];
10111
- return (p === c || p === void 0 && w && b) && (f === void 0 ? m.__staleWhileFetching !== void 0 ? this.#t[t] = m.__staleWhileFetching : this.#E(e, "fetch") : (i.status && (i.status.fetchUpdated = !0), this.#W(e, f, a.options, m))), f;
10112
- }, d = (f) => (i.status && (i.status.fetchRejected = !0, i.status.fetchError = f), y(f, !1)), y = (f, b) => {
10113
- let { aborted: l } = r.signal, w = l && i.allowStaleOnFetchAbort, F = w || i.allowStaleOnFetchRejection, m = F || i.noDeleteOnFetchRejection, p = c;
10114
- if (this.#t[t] === c && (!m || !b && p.__staleWhileFetching === void 0 ? this.#E(e, "fetch") : w || (this.#t[t] = p.__staleWhileFetching)), F) return i.status && p.__staleWhileFetching !== void 0 && (i.status.returnedStale = !0), p.__staleWhileFetching;
10548
+ }, r = (f, y = !1) => {
10549
+ let { aborted: a } = o.signal, w = i.ignoreFetchAbort && f !== void 0, F = i.ignoreFetchAbort || !!(i.allowStaleOnFetchAbort && f !== void 0);
10550
+ if (i.status && (a && !y ? (i.status.fetchAborted = !0, i.status.fetchError = o.signal.reason, w && (i.status.fetchAbortIgnored = !0)) : i.status.fetchResolved = !0), a && !w && !y) return m(o.signal.reason, F);
10551
+ let b = u, p = this.#t[t];
10552
+ return (p === u || p === void 0 && w && y) && (f === void 0 ? b.__staleWhileFetching !== void 0 ? this.#t[t] = b.__staleWhileFetching : this.#E(e, "fetch") : (i.status && (i.status.fetchUpdated = !0), this.#W(e, f, h.options, b))), f;
10553
+ }, c = (f) => (i.status && (i.status.fetchRejected = !0, i.status.fetchError = f), m(f, !1)), m = (f, y) => {
10554
+ let { aborted: a } = o.signal, w = a && i.allowStaleOnFetchAbort, F = w || i.allowStaleOnFetchRejection, b = F || i.noDeleteOnFetchRejection, p = u;
10555
+ if (this.#t[t] === u && (!b || !y && p.__staleWhileFetching === void 0 ? this.#E(e, "fetch") : w || (this.#t[t] = p.__staleWhileFetching)), F) return i.status && p.__staleWhileFetching !== void 0 && (i.status.returnedStale = !0), p.__staleWhileFetching;
10115
10556
  if (p.__returned === p) throw f;
10116
- }, _ = (f, b) => {
10117
- let l = this.#M?.(e, n, a);
10118
- r.signal.addEventListener("abort", () => {
10119
- (!i.ignoreFetchAbort || i.allowStaleOnFetchAbort) && (f(void 0), i.allowStaleOnFetchAbort && (f = (w) => o(w, !0)));
10120
- }), l && l instanceof Promise ? l.then((w) => f(w === void 0 ? void 0 : w), b) : l !== void 0 && f(l);
10557
+ }, _ = (f, y) => {
10558
+ let a = this.#M?.(e, n, h);
10559
+ o.signal.addEventListener("abort", () => {
10560
+ (!i.ignoreFetchAbort || i.allowStaleOnFetchAbort) && (f(void 0), i.allowStaleOnFetchAbort && (f = (w) => r(w, !0)));
10561
+ }), a && a instanceof Promise ? a.then((w) => f(w === void 0 ? void 0 : w), y) : a !== void 0 && f(a);
10121
10562
  };
10122
10563
  i.status && (i.status.fetchDispatched = !0);
10123
- let c = new Promise(_).then(o, d), g = Object.assign(c, {
10124
- __abortController: r,
10564
+ let u = new Promise(_).then(r, c), g = Object.assign(u, {
10565
+ __abortController: o,
10125
10566
  __staleWhileFetching: n,
10126
10567
  __returned: void 0
10127
10568
  });
10128
10569
  return t === void 0 ? (this.#W(e, g, {
10129
- ...a.options,
10570
+ ...h.options,
10130
10571
  status: void 0
10131
10572
  }), t = this.#s.get(e)) : this.#t[t] = g, g;
10132
10573
  }
@@ -10136,53 +10577,53 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10136
10577
  return !!t && t instanceof Promise && t.hasOwnProperty("__staleWhileFetching") && t.__abortController instanceof AbortController;
10137
10578
  }
10138
10579
  fetch(e, t = {}) {
10139
- let i = W.hasSubscribers, { status: s = D() ? {} : void 0 } = t;
10580
+ let i = W.hasSubscribers, { status: s = R() ? {} : void 0 } = t;
10140
10581
  t.status = s, s && t.context && (s.context = t.context);
10141
10582
  let n = this.#B(e, t);
10142
10583
  return s && i && (s.trace = !0, W.tracePromise(() => n, s).catch(() => {})), n;
10143
10584
  }
10144
10585
  async #B(e, t = {}) {
10145
- let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, ttl: r = this.ttl, noDisposeOnSet: h = this.noDisposeOnSet, size: a = 0, sizeCalculation: o = this.sizeCalculation, noUpdateTTL: d = this.noUpdateTTL, noDeleteOnFetchRejection: y = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection: _ = this.allowStaleOnFetchRejection, ignoreFetchAbort: c = this.ignoreFetchAbort, allowStaleOnFetchAbort: g = this.allowStaleOnFetchAbort, context: f, forceRefresh: b = !1, status: l, signal: w } = t;
10146
- if (l && (l.op = "fetch", l.key = e, b && (l.forceRefresh = !0), l.cache = this), !this.#U) return l && (l.fetch = "get"), this.#C(e, {
10586
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, ttl: o = this.ttl, noDisposeOnSet: l = this.noDisposeOnSet, size: h = 0, sizeCalculation: r = this.sizeCalculation, noUpdateTTL: c = this.noUpdateTTL, noDeleteOnFetchRejection: m = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection: _ = this.allowStaleOnFetchRejection, ignoreFetchAbort: u = this.ignoreFetchAbort, allowStaleOnFetchAbort: g = this.allowStaleOnFetchAbort, context: f, forceRefresh: y = !1, status: a, signal: w } = t;
10587
+ if (a && (a.op = "fetch", a.key = e, y && (a.forceRefresh = !0), a.cache = this), !this.#U) return a && (a.fetch = "get"), this.#C(e, {
10147
10588
  allowStale: i,
10148
10589
  updateAgeOnGet: s,
10149
10590
  noDeleteOnStaleGet: n,
10150
- status: l
10591
+ status: a
10151
10592
  });
10152
10593
  let F = {
10153
10594
  allowStale: i,
10154
10595
  updateAgeOnGet: s,
10155
10596
  noDeleteOnStaleGet: n,
10156
- ttl: r,
10157
- noDisposeOnSet: h,
10158
- size: a,
10159
- sizeCalculation: o,
10160
- noUpdateTTL: d,
10161
- noDeleteOnFetchRejection: y,
10597
+ ttl: o,
10598
+ noDisposeOnSet: l,
10599
+ size: h,
10600
+ sizeCalculation: r,
10601
+ noUpdateTTL: c,
10602
+ noDeleteOnFetchRejection: m,
10162
10603
  allowStaleOnFetchRejection: _,
10163
10604
  allowStaleOnFetchAbort: g,
10164
- ignoreFetchAbort: c,
10165
- status: l,
10605
+ ignoreFetchAbort: u,
10606
+ status: a,
10166
10607
  signal: w
10167
- }, m = this.#s.get(e);
10168
- if (m === void 0) {
10169
- l && (l.fetch = "miss");
10170
- let p = this.#P(e, m, F, f);
10608
+ }, b = this.#s.get(e);
10609
+ if (b === void 0) {
10610
+ a && (a.fetch = "miss");
10611
+ let p = this.#P(e, b, F, f);
10171
10612
  return p.__returned = p;
10172
10613
  } else {
10173
- let p = this.#t[m];
10614
+ let p = this.#t[b];
10174
10615
  if (this.#e(p)) {
10175
10616
  let v = i && p.__staleWhileFetching !== void 0;
10176
- return l && (l.fetch = "inflight", v && (l.returnedStale = !0)), v ? p.__staleWhileFetching : p.__returned = p;
10617
+ return a && (a.fetch = "inflight", v && (a.returnedStale = !0)), v ? p.__staleWhileFetching : p.__returned = p;
10177
10618
  }
10178
- let A = this.#p(m);
10179
- if (!b && !A) return l && (l.fetch = "hit"), this.#L(m), s && this.#D(m), l && this.#v(l, m), p;
10180
- let z = this.#P(e, m, F, f), E = z.__staleWhileFetching !== void 0 && i;
10181
- return l && (l.fetch = A ? "stale" : "refresh", E && A && (l.returnedStale = !0)), E ? z.__staleWhileFetching : z.__returned = z;
10619
+ let A = this.#p(b);
10620
+ if (!y && !A) return a && (a.fetch = "hit"), this.#L(b), s && this.#R(b), a && this.#v(a, b), p;
10621
+ let z = this.#P(e, b, F, f), E = z.__staleWhileFetching !== void 0 && i;
10622
+ return a && (a.fetch = A ? "stale" : "refresh", E && A && (a.returnedStale = !0)), E ? z.__staleWhileFetching : z.__returned = z;
10182
10623
  }
10183
10624
  }
10184
10625
  forceFetch(e, t = {}) {
10185
- let i = W.hasSubscribers, { status: s = D() ? {} : void 0 } = t;
10626
+ let i = W.hasSubscribers, { status: s = R() ? {} : void 0 } = t;
10186
10627
  t.status = s, s && t.context && (s.context = t.context);
10187
10628
  let n = this.#K(e, t);
10188
10629
  return s && i && (s.trace = !0, W.tracePromise(() => n, s).catch(() => {})), n;
@@ -10201,15 +10642,15 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10201
10642
  #Q(e, t = {}) {
10202
10643
  let i = this.#I;
10203
10644
  if (!i) throw new Error("no memoMethod provided to constructor");
10204
- let { context: s, status: n, forceRefresh: r, ...h } = t;
10205
- n && r && (n.forceRefresh = !0);
10206
- let a = this.#C(e, h), o = r || a === void 0;
10207
- if (n && (n.memo = o ? "miss" : "hit", o || (n.value = a)), !o) return a;
10208
- let d = i(e, a, {
10209
- options: h,
10645
+ let { context: s, status: n, forceRefresh: o, ...l } = t;
10646
+ n && o && (n.forceRefresh = !0);
10647
+ let h = this.#C(e, l), r = o || h === void 0;
10648
+ if (n && (n.memo = r ? "miss" : "hit", r || (n.value = h)), !r) return h;
10649
+ let c = i(e, h, {
10650
+ options: l,
10210
10651
  context: s
10211
10652
  });
10212
- return n && (n.value = d), this.#W(e, d, h), d;
10653
+ return n && (n.value = c), this.#W(e, c, l), c;
10213
10654
  }
10214
10655
  get(e, t = {}) {
10215
10656
  let { status: i = S.hasSubscribers ? {} : void 0 } = t;
@@ -10218,13 +10659,13 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10218
10659
  return i && (s !== void 0 && (i.value = s), S.hasSubscribers && S.publish(i)), s;
10219
10660
  }
10220
10661
  #C(e, t = {}) {
10221
- let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, status: r } = t, h = this.#s.get(e);
10222
- if (h === void 0) {
10223
- r && (r.get = "miss");
10662
+ let { allowStale: i = this.allowStale, updateAgeOnGet: s = this.updateAgeOnGet, noDeleteOnStaleGet: n = this.noDeleteOnStaleGet, status: o } = t, l = this.#s.get(e);
10663
+ if (l === void 0) {
10664
+ o && (o.get = "miss");
10224
10665
  return;
10225
10666
  }
10226
- let a = this.#t[h], o = this.#e(a);
10227
- return r && this.#v(r, h), this.#p(h) ? o ? (r && (r.get = "stale-fetching"), i && a.__staleWhileFetching !== void 0 ? (r && (r.returnedStale = !0), a.__staleWhileFetching) : void 0) : (n || this.#E(e, "expire"), r && (r.get = "stale"), i ? (r && (r.returnedStale = !0), a) : void 0) : (r && (r.get = o ? "fetching" : "hit"), this.#L(h), s && this.#D(h), o ? a.__staleWhileFetching : a);
10667
+ let h = this.#t[l], r = this.#e(h);
10668
+ return o && this.#v(o, l), this.#p(l) ? r ? (o && (o.get = "stale-fetching"), i && h.__staleWhileFetching !== void 0 ? (o && (o.returnedStale = !0), h.__staleWhileFetching) : void 0) : (n || this.#E(e, "expire"), o && (o.get = "stale"), i ? (o && (o.returnedStale = !0), h) : void 0) : (o && (o.get = r ? "fetching" : "hit"), this.#L(l), s && this.#R(l), r ? h.__staleWhileFetching : h);
10228
10669
  }
10229
10670
  #$(e, t) {
10230
10671
  this.#u[t] = e, this.#l[e] = t;
@@ -10245,9 +10686,9 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10245
10686
  let i = !1;
10246
10687
  if (this.#n !== 0) {
10247
10688
  let s = this.#s.get(e);
10248
- if (s !== void 0) if (this.#g?.[s] && (clearTimeout(this.#g?.[s]), this.#g[s] = void 0), i = !0, this.#n === 1) this.#q(t);
10689
+ if (s !== void 0) if (this.#g?.[s] && (clearTimeout(this.#g[s]), this.#g[s] = void 0), i = !0, this.#n === 1) this.#q(t);
10249
10690
  else {
10250
- this.#R(s);
10691
+ this.#x(s);
10251
10692
  let n = this.#t[s];
10252
10693
  if (this.#e(n) ? n.__abortController.abort(/* @__PURE__ */ new Error("deleted")) : (this.#T || this.#f) && (this.#T && this.#S?.(n, e, t), this.#f && this.#r?.push([
10253
10694
  n,
@@ -10256,10 +10697,10 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10256
10697
  ])), this.#s.delete(e), this.#i[s] = void 0, this.#t[s] = void 0, s === this.#h) this.#h = this.#u[s];
10257
10698
  else if (s === this.#a) this.#a = this.#l[s];
10258
10699
  else {
10259
- let r = this.#u[s];
10260
- this.#l[r] = this.#l[s];
10261
- let h = this.#l[s];
10262
- this.#u[h] = this.#u[s];
10700
+ let o = this.#u[s];
10701
+ this.#l[o] = this.#l[s];
10702
+ let l = this.#l[s];
10703
+ this.#u[l] = this.#u[s];
10263
10704
  }
10264
10705
  this.#n--, this.#y.push(s);
10265
10706
  }
@@ -10298,7 +10739,7 @@ var T = (u) => !!u && u === Math.floor(u) && u > 0 && isFinite(u), G = (u) => T(
10298
10739
  }
10299
10740
  };
10300
10741
  //#endregion
10301
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
10742
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
10302
10743
  /**
10303
10744
  * Unified memoised factory dispatching to the right provider flavour by the
10304
10745
  * source shape:
@@ -10387,7 +10828,7 @@ function hashRawPool(rawPool) {
10387
10828
  return rawPool.map((b) => `${b.blockId}\x1f${b.prodCtx ?? ""}\x1f${b.stagingCtx ?? ""}\x1f${b.prodIncomplete ? 1 : 0}\x1f${b.stagingIncomplete ? 1 : 0}`).join("");
10388
10829
  }
10389
10830
  //#endregion
10390
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
10831
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
10391
10832
  /**
10392
10833
  * Build the default set of ColumnsProviders for the ambient render ctx:
10393
10834
  * - `AccessorColumnsProvider` over `outputs` (if present)
@@ -10422,7 +10863,7 @@ function isColumnProvider(source) {
10422
10863
  return typeof p.getColumns === "function" && typeof p.isFinal === "function";
10423
10864
  }
10424
10865
  //#endregion
10425
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/data_column.js
10866
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/data_column.js
10426
10867
  /**
10427
10868
  * Thrown by leaf-recipe factories when the requested column is provably
10428
10869
  * absent in the active render ctx — i.e. every relevant accessor reports
@@ -10662,7 +11103,7 @@ function memoizeByEntry(fn) {
10662
11103
  };
10663
11104
  }
10664
11105
  //#endregion
10665
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
11106
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
10666
11107
  /**
10667
11108
  * Recipe wrapper that overlays {@link SpecOverrides} on top of any other
10668
11109
  * recipe. The id is `ColumnOverriddenKey { source: inner.id, specOverrides }`.
@@ -10800,7 +11241,7 @@ var DataColumnOverriddenRecipe = class extends ColumnOverriddenRecipe {
10800
11241
  }
10801
11242
  };
10802
11243
  //#endregion
10803
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
11244
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
10804
11245
  /**
10805
11246
  * Recipe wrapper that fixes the values of selected axes of an inner recipe
10806
11247
  * (axis slicing). The id is `FilteredPColumnId { source: inner.id,
@@ -10926,7 +11367,7 @@ function toAxisSelector(axis) {
10926
11367
  return selector;
10927
11368
  }
10928
11369
  //#endregion
10929
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
11370
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
10930
11371
  /**
10931
11372
  * Build a `ColumnRecipe` from a stringified id. Dispatches to the matching
10932
11373
  * concrete recipe variant based on the id's encoding and recurses on
@@ -10977,7 +11418,7 @@ function ColumnRecipeGetStatus(id, opts = {}) {
10977
11418
  }
10978
11419
  const ColumnRecipe = Object.assign(ColumnRecipeBuild, { getStatus: ColumnRecipeGetStatus });
10979
11420
  //#endregion
10980
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
11421
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
10981
11422
  /**
10982
11423
  * Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
10983
11424
  * column + a `path` of linkers + qualifications.
@@ -11148,7 +11589,7 @@ function referencedUniIdsOf(key) {
11148
11589
  return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
11149
11590
  }
11150
11591
  //#endregion
11151
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/column.js
11592
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column.js
11152
11593
  /**
11153
11594
  * Unified entry point — routes between the two top-level dispatchers:
11154
11595
  * - string id (`PObjectId` / `ColumnUniversalId`) → {@link ColumnRecipe}
@@ -11162,7 +11603,7 @@ function Column(source, opts) {
11162
11603
  return DataColumn(source, opts);
11163
11604
  }
11164
11605
  //#endregion
11165
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
11606
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
11166
11607
  /**
11167
11608
  * Build a {@link ColumnsCollection} from sandbox-side source descriptors.
11168
11609
  * Resolves the `columnsCollection` driver (either from `deps.driver` or via
@@ -11271,7 +11712,138 @@ function defaultCtxSources(ctx) {
11271
11712
  return [...currentBlockSources(ctx), { kind: "result_pool" }];
11272
11713
  }
11273
11714
  //#endregion
11274
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
11715
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/utils.js
11716
+ /**
11717
+ * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,
11718
+ * deduped in traversal order. The hit column is
11719
+ * `extractPObjectId(recipe.id)`; anything else in the query is a linker or
11720
+ * other engine-consumed column.
11721
+ *
11722
+ * Pure query walk — no registry access. Use {@link collectLinkerColumns} for
11723
+ * the resolved {@link DataColumnRecipe} variant.
11724
+ */
11725
+ function collectLinkerIds(recipe) {
11726
+ const hit = extractPObjectId(recipe.id);
11727
+ const seen = /* @__PURE__ */ new Set();
11728
+ const out = [];
11729
+ for (const id of collectSpecQueryColumns(recipe.getQuery())) {
11730
+ const bare = extractPObjectId(id);
11731
+ if (bare === hit) continue;
11732
+ if (seen.has(bare)) continue;
11733
+ seen.add(bare);
11734
+ out.push(bare);
11735
+ }
11736
+ return out;
11737
+ }
11738
+ /**
11739
+ * {@link collectLinkerIds} resolved against the ambient context as
11740
+ * {@link DataColumnRecipe} leaves. Throws if any id fails to resolve —
11741
+ * matches the contract of the legacy `resolveLinkers` it replaces.
11742
+ */
11743
+ function collectLinkerColumns(recipe, opts = {}) {
11744
+ return collectLinkerIds(recipe).map((id) => DataColumnImpl.fromId(id, opts) ?? throwError(`materializeLinkers: linker ${id} not resolvable`));
11745
+ }
11746
+ /**
11747
+ * Hit-side axis qualifications for the recipe — the ones that should land on
11748
+ * the outer-join entry wrapping this column at the consumer boundary.
11749
+ *
11750
+ * Descends {@link ColumnOverriddenRecipe} / {@link ColumnFilteredRecipe} via
11751
+ * `getInner()` until it finds a {@link ColumnDiscoveredRecipe}; otherwise
11752
+ * returns `[]`. Pure recipe walk — no query-tree introspection.
11753
+ */
11754
+ function hitQualifications(recipe) {
11755
+ return findDiscovered(recipe)?.getColumnQualifications() ?? [];
11756
+ }
11757
+ /**
11758
+ * Per-primary-column axis qualifications for the recipe — applied to the
11759
+ * outer primary anchors on this recipe's group side. Keyed by the external
11760
+ * primary column id (NOT by columns inside this recipe's own query).
11761
+ *
11762
+ * Same walk strategy as {@link hitQualifications}.
11763
+ */
11764
+ function queriesQualifications(recipe) {
11765
+ return findDiscovered(recipe)?.getQueriesQualifications() ?? {};
11766
+ }
11767
+ /**
11768
+ * Whether the recipe's underlying data resources actually carry bytes —
11769
+ * strictly stronger than `getDataStatus() === "present"`, which only tells
11770
+ * that the `.data` field is wired onto the accessor.
11771
+ *
11772
+ * Walks every physical leaf the recipe depends on via
11773
+ * {@link ColumnRecipe.getReferencedIds} (resolves each id back to a
11774
+ * {@link DataColumnRecipe} through the ambient ctx) and ANDs `hasData()` across
11775
+ * all of them. Inline {@link PColumnValues} payloads count as present.
11776
+ *
11777
+ * Returns `false` if any leaf cannot be re-resolved in `opts.ctx` (treat as
11778
+ * "not yet ready") rather than throwing — this is a UI-facing predicate, not
11779
+ * a contract assertion.
11780
+ */
11781
+ function hasColumnData(recipe, opts = {}) {
11782
+ for (const id of recipe.getReferencedIds()) {
11783
+ const leaf = DataColumnImpl.fromId(id, opts);
11784
+ if (leaf === void 0) return false;
11785
+ if (leaf.getDataStatus() !== "present") return false;
11786
+ if (!isLeafDataPresent(leaf.getData())) return false;
11787
+ }
11788
+ return true;
11789
+ }
11790
+ function isLeafDataPresent(data) {
11791
+ if (data === void 0) return false;
11792
+ if (Array.isArray(data)) return true;
11793
+ if (data instanceof TreeNodeAccessor) return data.hasData();
11794
+ if (isDataInfo(data)) {
11795
+ let ok = true;
11796
+ visitDataInfo(data, (blob) => {
11797
+ ok &&= blob.hasData();
11798
+ });
11799
+ return ok;
11800
+ }
11801
+ return false;
11802
+ }
11803
+ /**
11804
+ * Walk wrapper layers (Overridden, Filtered) until a {@link
11805
+ * ColumnDiscoveredRecipe} is found. Returns `undefined` if the recipe chain
11806
+ * has no Discovered layer (bare leaves and Overridden-over-leaf cases).
11807
+ *
11808
+ * Invariant from the wrapper classes themselves: there is at most one
11809
+ * Discovered layer in any recipe chain — Discovered is constructed only via
11810
+ * its own factory and is never re-wrapped by Discovered.
11811
+ */
11812
+ function findDiscovered(recipe) {
11813
+ let current = recipe;
11814
+ while (true) {
11815
+ if (current instanceof ColumnDiscoveredRecipe) return current;
11816
+ if (current instanceof ColumnOverriddenRecipe || current instanceof ColumnFilteredRecipe) {
11817
+ current = current.getInner();
11818
+ continue;
11819
+ }
11820
+ return;
11821
+ }
11822
+ }
11823
+ /**
11824
+ * Whether the recipe reads exactly one data column — its own — rather than
11825
+ * reaching through others.
11826
+ *
11827
+ * True for a bare leaf and for projections over one (spec overrides, axis
11828
+ * slicing): those add layers but no new columns. False when the recipe gets at
11829
+ * its data through further columns, which happens when discovery reached it via
11830
+ * a linker chain.
11831
+ *
11832
+ * **Why callers care.** A recipe over a single data column is co-indexed by its
11833
+ * own axes, so its spec is the whole truth about them. One that needs other
11834
+ * columns only lines up after they are joined in, and therefore drags axes into
11835
+ * the join that its own spec never mentions — which is why it cannot serve as a
11836
+ * primary column, and why `createPlDataTableV3` splits on this.
11837
+ *
11838
+ * The count comes from {@link ColumnRecipe.getReferencedIds}, which resolves
11839
+ * through the whole wrapper chain, so no class walk is involved and foreign
11840
+ * `ColumnRecipe` implementations are handled too.
11841
+ */
11842
+ function hasSingleDataColumn(recipe) {
11843
+ return recipe.getReferencedIds().length === 1;
11844
+ }
11845
+ //#endregion
11846
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
11275
11847
  function getAllRelatedColumns(ctx, predicate) {
11276
11848
  const columns = new PColumnCollection();
11277
11849
  columns.addColumnProvider(ctx.resultPool);
@@ -11347,7 +11919,7 @@ function discoverIntegrableColumnIds(ctx, rootColumns) {
11347
11919
  }
11348
11920
  }
11349
11921
  //#endregion
11350
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.82.0/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
11922
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
11351
11923
  function isHiddenFromGraphColumn(column) {
11352
11924
  return !!readAnnotationJson(column, Annotation.HideDataFromGraphs);
11353
11925
  }
@@ -11375,47 +11947,1478 @@ function createPFrameForGraphs(ctx, blockColumns) {
11375
11947
  predicate: suitableSpec
11376
11948
  }));
11377
11949
  }
11378
- (/* @__PURE__ */ __commonJSMin(((exports, module) => {
11379
- exports = module.exports = stringify;
11380
- exports.getSerialize = serializer;
11381
- function stringify(obj, replacer, spaces, cycleReplacer) {
11382
- return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
11383
- }
11384
- function serializer(replacer, cycleReplacer) {
11385
- var stack = [], keys = [];
11386
- if (cycleReplacer == null) cycleReplacer = function(key, value) {
11387
- if (stack[0] === value) return "[Circular ~]";
11388
- return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]";
11950
+ //#endregion
11951
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/filters/traverse.js
11952
+ /**
11953
+ * Recursively traverses a FilterSpec tree bottom-up, applying visitor callbacks.
11954
+ *
11955
+ * Entries with `{ type: undefined }` inside `and`/`or` arrays are skipped
11956
+ * (these represent unfilled filter slots in the UI).
11957
+ *
11958
+ * Traversal order:
11959
+ * 1. Recurse into child filters (`and`/`or`/`not`)
11960
+ * 2. Apply the corresponding visitor callback with already-traversed children
11961
+ * 3. For leaf nodes, call `leaf` directly
11962
+ */
11963
+ function traverseFilterSpec(filter, visitor) {
11964
+ return traverseFilterSpecImpl(filter, visitor);
11965
+ }
11966
+ /** Internal implementation with simple generics for clean recursion. */
11967
+ function traverseFilterSpecImpl(filter, visitor) {
11968
+ switch (filter.type) {
11969
+ case "and": return visitor.and(filter.filters.filter((f) => f.type !== void 0).map((f) => traverseFilterSpecImpl(f, visitor)));
11970
+ case "or": return visitor.or(filter.filters.filter((f) => f.type !== void 0).map((f) => traverseFilterSpecImpl(f, visitor)));
11971
+ case "not": return visitor.not(traverseFilterSpecImpl(filter.filter, visitor));
11972
+ default: return visitor.leaf(filter);
11973
+ }
11974
+ }
11975
+ /** Collects all column references (`column` and `rhs` fields) from filter leaves. */
11976
+ function collectFilterSpecColumns(filter) {
11977
+ return traverseFilterSpec(filter, {
11978
+ leaf: (leaf) => {
11979
+ const cols = [];
11980
+ if ("column" in leaf && leaf.column !== void 0) cols.push(leaf.column);
11981
+ if ("rhs" in leaf && leaf.rhs !== void 0) cols.push(leaf.rhs);
11982
+ return cols;
11983
+ },
11984
+ and: (results) => results.flat(),
11985
+ or: (results) => results.flat(),
11986
+ not: (result) => result
11987
+ });
11988
+ }
11989
+ //#endregion
11990
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
11991
+ /** Converts a QueryColumnId object into a SpecQueryExpression reference. */
11992
+ function resolveColumnRef(col) {
11993
+ return col.type === "axis" ? {
11994
+ type: "axisRef",
11995
+ value: col.id
11996
+ } : {
11997
+ type: "columnRef",
11998
+ value: col.id
11999
+ };
12000
+ }
12001
+ /** Converts a FilterSpec tree into a SpecQueryExpression. */
12002
+ function filterSpecToSpecQueryExpr(filter) {
12003
+ return traverseFilterSpec(filter, {
12004
+ leaf: leafToSpecQueryExpr,
12005
+ and: (inputs) => {
12006
+ if (inputs.length === 0) throw new Error("AND filter requires at least one operand");
12007
+ return {
12008
+ type: "and",
12009
+ input: inputs
12010
+ };
12011
+ },
12012
+ or: (inputs) => {
12013
+ if (inputs.length === 0) throw new Error("OR filter requires at least one operand");
12014
+ return {
12015
+ type: "or",
12016
+ input: inputs
12017
+ };
12018
+ },
12019
+ not: (input) => ({
12020
+ type: "not",
12021
+ input
12022
+ })
12023
+ });
12024
+ }
12025
+ function leafToSpecQueryExpr(filter) {
12026
+ switch (filter.type) {
12027
+ case "patternEquals": return {
12028
+ type: "stringEquals",
12029
+ input: resolveColumnRef(filter.column),
12030
+ value: filter.value,
12031
+ caseInsensitive: false
11389
12032
  };
11390
- return function(key, value) {
11391
- if (stack.length > 0) {
11392
- var thisPos = stack.indexOf(this);
11393
- ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
11394
- ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
11395
- if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value);
11396
- } else stack.push(value);
11397
- return replacer == null ? value : replacer.call(this, key, value);
12033
+ case "patternNotEquals": return {
12034
+ type: "not",
12035
+ input: {
12036
+ type: "stringEquals",
12037
+ input: resolveColumnRef(filter.column),
12038
+ value: filter.value,
12039
+ caseInsensitive: false
12040
+ }
11398
12041
  };
11399
- }
11400
- })))();
11401
- const PlErrorLike = objectType({
11402
- type: literalType("PlError"),
11403
- name: stringType(),
11404
- message: stringType(),
11405
- fullMessage: stringType().optional(),
11406
- stack: stringType().optional()
11407
- }).extend({
11408
- cause: lazyType(() => ErrorLike).optional(),
11409
- errors: lazyType(() => ErrorLike.array()).optional()
11410
- });
11411
- const ErrorLike = unionType([objectType({
11412
- type: literalType("StandardError"),
11413
- name: stringType(),
11414
- message: stringType(),
11415
- stack: stringType().optional()
11416
- }).extend({
11417
- cause: lazyType(() => ErrorLike).optional(),
11418
- errors: lazyType(() => ErrorLike.array()).optional()
12042
+ case "patternContainSubsequence": return {
12043
+ type: "stringContains",
12044
+ input: resolveColumnRef(filter.column),
12045
+ value: filter.value,
12046
+ caseInsensitive: false
12047
+ };
12048
+ case "patternNotContainSubsequence": return {
12049
+ type: "not",
12050
+ input: {
12051
+ type: "stringContains",
12052
+ input: resolveColumnRef(filter.column),
12053
+ value: filter.value,
12054
+ caseInsensitive: false
12055
+ }
12056
+ };
12057
+ case "patternMatchesRegularExpression": return {
12058
+ type: "stringRegex",
12059
+ input: resolveColumnRef(filter.column),
12060
+ value: filter.value
12061
+ };
12062
+ case "patternFuzzyContainSubsequence": return {
12063
+ type: "stringContainsFuzzy",
12064
+ input: resolveColumnRef(filter.column),
12065
+ value: filter.value,
12066
+ maxEdits: filter.maxEdits ?? 1,
12067
+ caseInsensitive: false,
12068
+ substitutionsOnly: filter.substitutionsOnly ?? false,
12069
+ wildcard: filter.wildcard ?? null
12070
+ };
12071
+ case "equal": return {
12072
+ type: "numericComparison",
12073
+ operand: "eq",
12074
+ left: resolveColumnRef(filter.column),
12075
+ right: {
12076
+ type: "constant",
12077
+ value: filter.x
12078
+ }
12079
+ };
12080
+ case "notEqual": return {
12081
+ type: "numericComparison",
12082
+ operand: "ne",
12083
+ left: resolveColumnRef(filter.column),
12084
+ right: {
12085
+ type: "constant",
12086
+ value: filter.x
12087
+ }
12088
+ };
12089
+ case "lessThan": return {
12090
+ type: "numericComparison",
12091
+ operand: "lt",
12092
+ left: resolveColumnRef(filter.column),
12093
+ right: {
12094
+ type: "constant",
12095
+ value: filter.x
12096
+ }
12097
+ };
12098
+ case "greaterThan": return {
12099
+ type: "numericComparison",
12100
+ operand: "gt",
12101
+ left: resolveColumnRef(filter.column),
12102
+ right: {
12103
+ type: "constant",
12104
+ value: filter.x
12105
+ }
12106
+ };
12107
+ case "lessThanOrEqual": return {
12108
+ type: "numericComparison",
12109
+ operand: "le",
12110
+ left: resolveColumnRef(filter.column),
12111
+ right: {
12112
+ type: "constant",
12113
+ value: filter.x
12114
+ }
12115
+ };
12116
+ case "greaterThanOrEqual": return {
12117
+ type: "numericComparison",
12118
+ operand: "ge",
12119
+ left: resolveColumnRef(filter.column),
12120
+ right: {
12121
+ type: "constant",
12122
+ value: filter.x
12123
+ }
12124
+ };
12125
+ case "equalToColumn": return {
12126
+ type: "numericComparison",
12127
+ operand: "eq",
12128
+ left: resolveColumnRef(filter.column),
12129
+ right: resolveColumnRef(filter.rhs)
12130
+ };
12131
+ case "lessThanColumn": {
12132
+ const left = resolveColumnRef(filter.column);
12133
+ const right = resolveColumnRef(filter.rhs);
12134
+ if (filter.minDiff !== void 0 && filter.minDiff !== 0) return {
12135
+ type: "numericComparison",
12136
+ operand: "lt",
12137
+ left: {
12138
+ type: "numericBinary",
12139
+ operand: "add",
12140
+ left,
12141
+ right: {
12142
+ type: "constant",
12143
+ value: filter.minDiff
12144
+ }
12145
+ },
12146
+ right
12147
+ };
12148
+ return {
12149
+ type: "numericComparison",
12150
+ operand: "lt",
12151
+ left,
12152
+ right
12153
+ };
12154
+ }
12155
+ case "greaterThanColumn": {
12156
+ const left = resolveColumnRef(filter.column);
12157
+ const right = resolveColumnRef(filter.rhs);
12158
+ if (filter.minDiff !== void 0 && filter.minDiff !== 0) return {
12159
+ type: "numericComparison",
12160
+ operand: "gt",
12161
+ left: {
12162
+ type: "numericBinary",
12163
+ operand: "add",
12164
+ left,
12165
+ right: {
12166
+ type: "constant",
12167
+ value: filter.minDiff
12168
+ }
12169
+ },
12170
+ right
12171
+ };
12172
+ return {
12173
+ type: "numericComparison",
12174
+ operand: "gt",
12175
+ left,
12176
+ right
12177
+ };
12178
+ }
12179
+ case "lessThanColumnOrEqual": {
12180
+ const left = resolveColumnRef(filter.column);
12181
+ const right = resolveColumnRef(filter.rhs);
12182
+ if (filter.minDiff !== void 0 && filter.minDiff !== 0) return {
12183
+ type: "numericComparison",
12184
+ operand: "le",
12185
+ left: {
12186
+ type: "numericBinary",
12187
+ operand: "add",
12188
+ left,
12189
+ right: {
12190
+ type: "constant",
12191
+ value: filter.minDiff
12192
+ }
12193
+ },
12194
+ right
12195
+ };
12196
+ return {
12197
+ type: "numericComparison",
12198
+ operand: "le",
12199
+ left,
12200
+ right
12201
+ };
12202
+ }
12203
+ case "greaterThanColumnOrEqual": {
12204
+ const left = resolveColumnRef(filter.column);
12205
+ const right = resolveColumnRef(filter.rhs);
12206
+ if (filter.minDiff !== void 0 && filter.minDiff !== 0) return {
12207
+ type: "numericComparison",
12208
+ operand: "ge",
12209
+ left: {
12210
+ type: "numericBinary",
12211
+ operand: "add",
12212
+ left,
12213
+ right: {
12214
+ type: "constant",
12215
+ value: filter.minDiff
12216
+ }
12217
+ },
12218
+ right
12219
+ };
12220
+ return {
12221
+ type: "numericComparison",
12222
+ operand: "ge",
12223
+ left,
12224
+ right
12225
+ };
12226
+ }
12227
+ case "inSet": return {
12228
+ type: "isIn",
12229
+ input: resolveColumnRef(filter.column),
12230
+ set: filter.value,
12231
+ negate: false
12232
+ };
12233
+ case "notInSet": return {
12234
+ type: "isIn",
12235
+ input: resolveColumnRef(filter.column),
12236
+ set: filter.value,
12237
+ negate: true
12238
+ };
12239
+ case "isNA": return {
12240
+ type: "isNull",
12241
+ input: resolveColumnRef(filter.column)
12242
+ };
12243
+ case "isNotNA": return {
12244
+ type: "not",
12245
+ input: {
12246
+ type: "isNull",
12247
+ input: resolveColumnRef(filter.column)
12248
+ }
12249
+ };
12250
+ case "ifNa": return {
12251
+ type: "fillNull",
12252
+ input: resolveColumnRef(filter.column),
12253
+ replacement: {
12254
+ type: "constant",
12255
+ value: filter.replacement
12256
+ }
12257
+ };
12258
+ case "topN":
12259
+ case "bottomN": throw new Error(`Filter type "${filter.type}" is not supported in query expressions`);
12260
+ case void 0: throw new Error("Filter type is undefined");
12261
+ default: assertNever(filter);
12262
+ }
12263
+ }
12264
+ //#endregion
12265
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/predicate/isArrayLike.mjs
12266
+ /**
12267
+ * Checks if `value` is array-like.
12268
+ *
12269
+ * @param value The value to check.
12270
+ * @returns Returns `true` if `value` is array-like, else `false`.
12271
+ *
12272
+ * @example
12273
+ * isArrayLike([1, 2, 3]); // true
12274
+ * isArrayLike('abc'); // true
12275
+ * isArrayLike({ 0: 'a', length: 1 }); // true
12276
+ * isArrayLike({}); // false
12277
+ * isArrayLike(null); // false
12278
+ * isArrayLike(undefined); // false
12279
+ */
12280
+ function isArrayLike(value) {
12281
+ return value != null && typeof value !== "function" && isLength(value.length);
12282
+ }
12283
+ //#endregion
12284
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/predicate/isArguments.mjs
12285
+ /**
12286
+ * Checks if the given value is an arguments object.
12287
+ *
12288
+ * This function tests whether the provided value is an arguments object or not.
12289
+ * It returns `true` if the value is an arguments object, and `false` otherwise.
12290
+ *
12291
+ * This function can also serve as a type predicate in TypeScript, narrowing the type of the argument to an arguments object.
12292
+ *
12293
+ * @param value - The value to test if it is an arguments object.
12294
+ * @returns `true` if the value is an arguments, `false` otherwise.
12295
+ *
12296
+ * @example
12297
+ * const args = (function() { return arguments; })();
12298
+ * const strictArgs = (function() { 'use strict'; return arguments; })();
12299
+ * const value = [1, 2, 3];
12300
+ *
12301
+ * console.log(isArguments(args)); // true
12302
+ * console.log(isArguments(strictArgs)); // true
12303
+ * console.log(isArguments(value)); // false
12304
+ */
12305
+ function isArguments(value) {
12306
+ return value !== null && typeof value === "object" && getTag(value) === "[object Arguments]";
12307
+ }
12308
+ //#endregion
12309
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/predicate/isTypedArray.mjs
12310
+ /**
12311
+ * Checks if a value is a TypedArray.
12312
+ * @param x The value to check.
12313
+ * @returns Returns true if `x` is a TypedArray, false otherwise.
12314
+ *
12315
+ * @example
12316
+ * const arr = new Uint8Array([1, 2, 3]);
12317
+ * isTypedArray(arr); // true
12318
+ *
12319
+ * const regularArray = [1, 2, 3];
12320
+ * isTypedArray(regularArray); // false
12321
+ *
12322
+ * const buffer = new ArrayBuffer(16);
12323
+ * isTypedArray(buffer); // false
12324
+ */
12325
+ function isTypedArray(x) {
12326
+ return isTypedArray$1(x);
12327
+ }
12328
+ //#endregion
12329
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/_internal/isPrototype.mjs
12330
+ function isPrototype(value) {
12331
+ const constructor = value?.constructor;
12332
+ return value === (typeof constructor === "function" ? constructor.prototype : Object.prototype);
12333
+ }
12334
+ //#endregion
12335
+ //#region ../node_modules/.pnpm/es-toolkit@1.52.0/node_modules/es-toolkit/dist/compat/predicate/isEmpty.mjs
12336
+ /**
12337
+ * Checks if a given value is empty.
12338
+ *
12339
+ * - If the given value is a string, checks if it is an empty string.
12340
+ * - If the given value is an array, `Map`, or `Set`, checks if its size is 0.
12341
+ * - If the given value is an [array-like object](../predicate/isArrayLike.md), checks if its length is 0.
12342
+ * - If the given value is an object, checks if it is an empty object with no properties.
12343
+ * - Primitive values (booleans, numbers, or bigints) are considered empty.
12344
+ *
12345
+ * @param [value] - The value to check.
12346
+ * @returns `true` if the value is empty, `false` otherwise.
12347
+ *
12348
+ * @example
12349
+ * isEmpty(); // true
12350
+ * isEmpty(null); // true
12351
+ * isEmpty(""); // true
12352
+ * isEmpty([]); // true
12353
+ * isEmpty({}); // true
12354
+ * isEmpty(new Map()); // true
12355
+ * isEmpty(new Set()); // true
12356
+ * isEmpty("hello"); // false
12357
+ * isEmpty([1, 2, 3]); // false
12358
+ * isEmpty({ a: 1 }); // false
12359
+ * isEmpty(new Map([["key", "value"]])); // false
12360
+ * isEmpty(new Set([1, 2, 3])); // false
12361
+ */
12362
+ function isEmpty(value) {
12363
+ if (value == null) return true;
12364
+ if (isArrayLike(value)) {
12365
+ if (typeof value.splice !== "function" && typeof value !== "string" && !isBuffer(value) && !isTypedArray(value) && !isArguments(value)) return false;
12366
+ return value.length === 0;
12367
+ }
12368
+ if (typeof value === "object" || typeof value === "function") {
12369
+ if (value instanceof Map || value instanceof Set) return value.size === 0;
12370
+ const keys = Object.keys(value);
12371
+ if (isPrototype(value)) return keys.filter((x) => x !== "constructor").length === 0;
12372
+ return keys.length === 0;
12373
+ }
12374
+ return true;
12375
+ }
12376
+ //#endregion
12377
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/filters/distill.js
12378
+ /**
12379
+ * Strips non-FilterSpec metadata (whitelist approach) and removes
12380
+ * unfilled leaves (type is undefined or any required field is undefined).
12381
+ */
12382
+ function distillFilterSpec(filter) {
12383
+ if (filter == null) return null;
12384
+ return traverseFilterSpec(filter, {
12385
+ leaf: (leaf) => {
12386
+ const distilled = distillLeaf(leaf);
12387
+ return isFilledLeaf(distilled) ? distilled : null;
12388
+ },
12389
+ and: (results) => {
12390
+ const filtered = results.filter((f) => f !== null);
12391
+ return filtered.length === 0 ? null : {
12392
+ type: "and",
12393
+ filters: filtered
12394
+ };
12395
+ },
12396
+ or: (results) => {
12397
+ const filtered = results.filter((f) => f !== null);
12398
+ return filtered.length === 0 ? null : {
12399
+ type: "or",
12400
+ filters: filtered
12401
+ };
12402
+ },
12403
+ not: (result) => result === null ? null : {
12404
+ type: "not",
12405
+ filter: result
12406
+ }
12407
+ });
12408
+ }
12409
+ function distillLeaf(node) {
12410
+ const result = {};
12411
+ for (const [key, value] of Object.entries(node)) if (KNOWN_LEAF_KEYS.has(key)) result[key] = value;
12412
+ return result;
12413
+ }
12414
+ /** Returns true if the leaf is filled — type is defined and every required field per-type is filled. */
12415
+ function isFilledLeaf(node) {
12416
+ if (isNil$1(node.type)) return false;
12417
+ const required = REQUIRED_KEYS_BY_TYPE[node.type];
12418
+ const record = node;
12419
+ return required.every((key) => isFilledValue(record[key]));
12420
+ }
12421
+ /**
12422
+ * Returns true if the value is considered "filled":
12423
+ * - primitives (number, boolean): always true
12424
+ * - string: non-empty after trim
12425
+ * - array: non-empty AND every item is filled
12426
+ * - plain object: non-empty AND every field value is filled
12427
+ * - null/undefined: false
12428
+ */
12429
+ function isFilledValue(value) {
12430
+ if (isNil$1(value)) return false;
12431
+ switch (typeof value) {
12432
+ case "number":
12433
+ case "boolean": return true;
12434
+ case "string": return value.trim() !== "";
12435
+ default:
12436
+ if (isEmpty(value)) return false;
12437
+ if (Array.isArray(value)) return value.every(isFilledValue);
12438
+ return Object.values(value).every(isFilledValue);
12439
+ }
12440
+ }
12441
+ const KNOWN_LEAF_KEYS = /* @__PURE__ */ new Set([
12442
+ "n",
12443
+ "x",
12444
+ "rhs",
12445
+ "type",
12446
+ "value",
12447
+ "column",
12448
+ "minDiff",
12449
+ "maxEdits",
12450
+ "wildcard",
12451
+ "replacement",
12452
+ "substitutionsOnly"
12453
+ ]);
12454
+ /** Required fields per leaf type. Optional fields (e.g. minDiff, maxEdits) excluded. */
12455
+ const REQUIRED_KEYS_BY_TYPE = {
12456
+ isNA: ["column"],
12457
+ isNotNA: ["column"],
12458
+ ifNa: ["column", "replacement"],
12459
+ patternEquals: ["column", "value"],
12460
+ patternNotEquals: ["column", "value"],
12461
+ patternContainSubsequence: ["column", "value"],
12462
+ patternNotContainSubsequence: ["column", "value"],
12463
+ patternMatchesRegularExpression: ["column", "value"],
12464
+ patternFuzzyContainSubsequence: ["column", "value"],
12465
+ inSet: ["column", "value"],
12466
+ notInSet: ["column", "value"],
12467
+ topN: ["column", "n"],
12468
+ bottomN: ["column", "n"],
12469
+ equal: ["column", "x"],
12470
+ notEqual: ["column", "x"],
12471
+ lessThan: ["column", "x"],
12472
+ greaterThan: ["column", "x"],
12473
+ lessThanOrEqual: ["column", "x"],
12474
+ greaterThanOrEqual: ["column", "x"],
12475
+ equalToColumn: ["column", "rhs"],
12476
+ lessThanColumn: ["column", "rhs"],
12477
+ greaterThanColumn: ["column", "rhs"],
12478
+ lessThanColumnOrEqual: ["column", "rhs"],
12479
+ greaterThanColumnOrEqual: ["column", "rhs"]
12480
+ };
12481
+ //#endregion
12482
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
12483
+ /** Upgrade PlDataTableStateV2 to the latest version */
12484
+ function upgradePlDataTableStateV2(state) {
12485
+ if (!state) return createPlDataTableStateV2();
12486
+ if (!("version" in state)) state = createPlDataTableStateV2();
12487
+ if (state.version === 2) state = {
12488
+ version: 3,
12489
+ stateCache: state.stateCache.map((entry) => ({
12490
+ ...entry,
12491
+ filtersState: []
12492
+ })),
12493
+ pTableParams: createDefaultPTableParamsV7()
12494
+ };
12495
+ if (state.version === 3) state = createPlDataTableStateV2();
12496
+ if (state.version === 4) state = migrateV4toV6(state);
12497
+ if (state.version === 5) state = migrateV5toV6(state);
12498
+ if (state.version === 6) state = migrateV6toV7(state);
12499
+ if (state.version === 7) state = migrateV7toV8(state);
12500
+ return state;
12501
+ }
12502
+ /** Migrate v5 to v6: unwrap `{source, labeled}` colIds in gridState. */
12503
+ function migrateV5toV6(state) {
12504
+ return {
12505
+ version: 6,
12506
+ stateCache: state.stateCache.map((entry) => ({
12507
+ ...entry,
12508
+ gridState: unwrapV5GridState(entry.gridState)
12509
+ })),
12510
+ pTableParams: createDefaultPTableParamsV7()
12511
+ };
12512
+ }
12513
+ /** Convert v5 wrapped colId JSON to bare PTableColumnSpec JSON, taking `.source`.
12514
+ * gridState colIds may include the row-number sentinel (a JSON-stringified
12515
+ * literal, not a wrapped spec) — those pass through unchanged. */
12516
+ function unwrapV5ColId(json) {
12517
+ const parsed = parseJsonSafely(json);
12518
+ return !isNil(parsed) && typeof parsed === "object" && "source" in parsed ? canonicalizeJson(parsed.source) : json;
12519
+ }
12520
+ function unwrapV5GridState(gridState) {
12521
+ const unwrapAs = (json) => unwrapV5ColId(json);
12522
+ return {
12523
+ columnOrder: gridState.columnOrder ? { orderedColIds: gridState.columnOrder.orderedColIds.map(unwrapAs) } : void 0,
12524
+ sort: gridState.sort ? { sortModel: gridState.sort.sortModel.map((s) => ({
12525
+ colId: unwrapAs(s.colId),
12526
+ sort: s.sort
12527
+ })) } : void 0,
12528
+ columnVisibility: gridState.columnVisibility ? { hiddenColIds: gridState.columnVisibility.hiddenColIds.map(unwrapAs) } : void 0
12529
+ };
12530
+ }
12531
+ /** Migrate v6 to v7: rewrite each colId from a full PTableColumnSpec to its
12532
+ * compact PTableColumnId (drops annotations/spec body, ~16× smaller per column). */
12533
+ function migrateV6toV7(state) {
12534
+ return {
12535
+ version: 7,
12536
+ stateCache: state.stateCache.map((entry) => ({
12537
+ ...entry,
12538
+ gridState: shrinkV6GridState(entry.gridState)
12539
+ })),
12540
+ pTableParams: state.pTableParams
12541
+ };
12542
+ }
12543
+ /** Convert a v6 fat colId (canonicalized PTableColumnSpec) to a v7 compact colId
12544
+ * (canonicalized PTableColumnId). The row-number sentinel is a string literal,
12545
+ * not a spec — pass it through unchanged. */
12546
+ function shrinkV6ColId(json) {
12547
+ const parsed = parseJsonSafely(json);
12548
+ if (!isNil(parsed) && typeof parsed === "object" && "type" in parsed && "id" in parsed) return canonicalizeJson(getPTableColumnId(parsed));
12549
+ return json;
12550
+ }
12551
+ function shrinkV6GridState(gridState) {
12552
+ return {
12553
+ columnOrder: gridState.columnOrder ? { orderedColIds: gridState.columnOrder.orderedColIds.map(shrinkV6ColId) } : void 0,
12554
+ sort: gridState.sort ? { sortModel: gridState.sort.sortModel.map((s) => ({
12555
+ colId: shrinkV6ColId(s.colId),
12556
+ sort: s.sort
12557
+ })) } : void 0,
12558
+ columnVisibility: gridState.columnVisibility ? { hiddenColIds: gridState.columnVisibility.hiddenColIds.map(shrinkV6ColId) } : void 0
12559
+ };
12560
+ }
12561
+ /** Migrate v4 state to v6: convert per-column filters to tree-based format (skips v5). */
12562
+ function migrateV4toV6(state) {
12563
+ let idCounter = 0;
12564
+ const nextId = () => ++idCounter;
12565
+ const migratedCache = state.stateCache.map((entry) => {
12566
+ const leaves = [];
12567
+ for (const f of entry.filtersState) if (f.filter !== null && !f.filter.disabled) leaves.push(migrateTableFilter(canonicalizeJson(f.id), f.filter.value, nextId));
12568
+ const filtersState = leaves.length > 0 ? {
12569
+ id: nextId(),
12570
+ type: "and",
12571
+ filters: leaves
12572
+ } : null;
12573
+ return {
12574
+ sourceId: entry.sourceId,
12575
+ gridState: entry.gridState,
12576
+ sheetsState: entry.sheetsState,
12577
+ filtersState,
12578
+ defaultFiltersState: null
12579
+ };
12580
+ });
12581
+ const oldSourceId = state.pTableParams.sourceId;
12582
+ const currentCache = oldSourceId ? migratedCache.find((e) => e.sourceId === oldSourceId) : void 0;
12583
+ return {
12584
+ version: 6,
12585
+ stateCache: migratedCache,
12586
+ pTableParams: currentCache && oldSourceId ? {
12587
+ sourceId: oldSourceId,
12588
+ hiddenColIds: state.pTableParams.hiddenColIds?.map((id) => ({
12589
+ type: "column",
12590
+ id
12591
+ })) ?? null,
12592
+ filters: distillFilterSpec(currentCache.filtersState),
12593
+ defaultFilters: null,
12594
+ sorting: state.pTableParams.sorting
12595
+ } : createDefaultPTableParamsV7()
12596
+ };
12597
+ }
12598
+ /** Migrate a single per-column PlTableFilter to a v7-form tree node (legacy
12599
+ * string column ids). v7 → v8 later converts these to object form. */
12600
+ function migrateTableFilter(column, filter, nextId) {
12601
+ const id = nextId();
12602
+ switch (filter.type) {
12603
+ case "isNA": return {
12604
+ id,
12605
+ type: "isNA",
12606
+ column
12607
+ };
12608
+ case "isNotNA": return {
12609
+ id,
12610
+ type: "isNotNA",
12611
+ column
12612
+ };
12613
+ case "number_equals": return {
12614
+ id,
12615
+ type: "equal",
12616
+ column,
12617
+ x: filter.reference
12618
+ };
12619
+ case "number_notEquals": return {
12620
+ id,
12621
+ type: "notEqual",
12622
+ column,
12623
+ x: filter.reference
12624
+ };
12625
+ case "number_greaterThan": return {
12626
+ id,
12627
+ type: "greaterThan",
12628
+ column,
12629
+ x: filter.reference
12630
+ };
12631
+ case "number_greaterThanOrEqualTo": return {
12632
+ id,
12633
+ type: "greaterThanOrEqual",
12634
+ column,
12635
+ x: filter.reference
12636
+ };
12637
+ case "number_lessThan": return {
12638
+ id,
12639
+ type: "lessThan",
12640
+ column,
12641
+ x: filter.reference
12642
+ };
12643
+ case "number_lessThanOrEqualTo": return {
12644
+ id,
12645
+ type: "lessThanOrEqual",
12646
+ column,
12647
+ x: filter.reference
12648
+ };
12649
+ case "number_between": return {
12650
+ id,
12651
+ type: "and",
12652
+ filters: [filter.includeLowerBound ? {
12653
+ id: nextId(),
12654
+ type: "greaterThanOrEqual",
12655
+ column,
12656
+ x: filter.lowerBound
12657
+ } : {
12658
+ id: nextId(),
12659
+ type: "greaterThan",
12660
+ column,
12661
+ x: filter.lowerBound
12662
+ }, filter.includeUpperBound ? {
12663
+ id: nextId(),
12664
+ type: "lessThanOrEqual",
12665
+ column,
12666
+ x: filter.upperBound
12667
+ } : {
12668
+ id: nextId(),
12669
+ type: "lessThan",
12670
+ column,
12671
+ x: filter.upperBound
12672
+ }]
12673
+ };
12674
+ case "string_equals": return {
12675
+ id,
12676
+ type: "patternEquals",
12677
+ column,
12678
+ value: filter.reference
12679
+ };
12680
+ case "string_notEquals": return {
12681
+ id,
12682
+ type: "patternNotEquals",
12683
+ column,
12684
+ value: filter.reference
12685
+ };
12686
+ case "string_contains": return {
12687
+ id,
12688
+ type: "patternContainSubsequence",
12689
+ column,
12690
+ value: filter.reference
12691
+ };
12692
+ case "string_doesNotContain": return {
12693
+ id,
12694
+ type: "patternNotContainSubsequence",
12695
+ column,
12696
+ value: filter.reference
12697
+ };
12698
+ case "string_matches": return {
12699
+ id,
12700
+ type: "patternMatchesRegularExpression",
12701
+ column,
12702
+ value: filter.reference
12703
+ };
12704
+ case "string_doesNotMatch": return {
12705
+ id,
12706
+ type: "not",
12707
+ filter: {
12708
+ id: nextId(),
12709
+ type: "patternMatchesRegularExpression",
12710
+ column,
12711
+ value: filter.reference
12712
+ }
12713
+ };
12714
+ case "string_containsFuzzyMatch": return {
12715
+ id,
12716
+ type: "patternFuzzyContainSubsequence",
12717
+ column,
12718
+ value: filter.reference,
12719
+ maxEdits: filter.maxEdits,
12720
+ substitutionsOnly: filter.substitutionsOnly,
12721
+ ...filter.wildcard !== void 0 ? { wildcard: filter.wildcard } : {}
12722
+ };
12723
+ }
12724
+ }
12725
+ /** Default pTableParams in the v7 shape (sorting: []). Used by intermediate
12726
+ * migration steps that produce v6/v7 state before the v7 → v8 conversion. */
12727
+ function createDefaultPTableParamsV7() {
12728
+ return {
12729
+ sourceId: null,
12730
+ hiddenColIds: null,
12731
+ filters: null,
12732
+ defaultFilters: null,
12733
+ sorting: []
12734
+ };
12735
+ }
12736
+ function createDefaultPTableParams() {
12737
+ return {
12738
+ sourceId: null,
12739
+ hiddenColIds: null,
12740
+ filters: null,
12741
+ defaultFilters: null,
12742
+ sorting: null
12743
+ };
12744
+ }
12745
+ function createPlDataTableStateV2() {
12746
+ return {
12747
+ version: 8,
12748
+ stateCache: [],
12749
+ pTableParams: createDefaultPTableParams()
12750
+ };
12751
+ }
12752
+ function migrateV7toV8(state) {
12753
+ const newCache = state.stateCache.map((entry) => ({
12754
+ sourceId: entry.sourceId,
12755
+ gridState: entry.gridState,
12756
+ sheetsState: entry.sheetsState,
12757
+ filtersState: convertFiltersWithMeta(entry.filtersState),
12758
+ defaultFiltersState: convertFiltersWithMeta(entry.defaultFiltersState),
12759
+ searchString: entry.searchString
12760
+ }));
12761
+ const params = state.pTableParams;
12762
+ let pTableParams;
12763
+ if (params.sourceId === null) pTableParams = createDefaultPTableParams();
12764
+ else pTableParams = {
12765
+ sourceId: params.sourceId,
12766
+ hiddenColIds: params.hiddenColIds,
12767
+ sorting: params.sorting.length === 0 ? null : params.sorting,
12768
+ filters: convertFiltersPlain(params.filters),
12769
+ defaultFilters: convertFiltersPlain(params.defaultFilters)
12770
+ };
12771
+ return {
12772
+ version: 8,
12773
+ stateCache: newCache,
12774
+ pTableParams
12775
+ };
12776
+ }
12777
+ function convertFiltersWithMeta(node) {
12778
+ if (node === null) return null;
12779
+ const result = pruneFilterNode(node);
12780
+ if (result === void 0) return null;
12781
+ return result;
12782
+ }
12783
+ function convertFiltersPlain(node) {
12784
+ if (node === null) return null;
12785
+ const result = pruneFilterNode(node);
12786
+ if (result === void 0) return null;
12787
+ return result;
12788
+ }
12789
+ /** Recursively converts and prunes a legacy v7 filter tree. Preserves meta
12790
+ * fields (id/isExpanded/source/isSuppressed) on non-leaf nodes. Returns
12791
+ * `undefined` when the subtree is empty after pruning. */
12792
+ function pruneFilterNode(node) {
12793
+ if (!node || typeof node !== "object") return void 0;
12794
+ const n = node;
12795
+ if (n.type === "and" || n.type === "or") {
12796
+ const kept = (n.filters ?? []).map((f) => pruneFilterNode(f)).filter((f) => f !== void 0);
12797
+ if (kept.length === 0) return void 0;
12798
+ return {
12799
+ ...n,
12800
+ type: n.type,
12801
+ filters: kept
12802
+ };
12803
+ }
12804
+ if (n.type === "not") {
12805
+ const inner = pruneFilterNode(n.filter);
12806
+ if (inner === void 0) return void 0;
12807
+ return {
12808
+ ...n,
12809
+ type: "not",
12810
+ filter: inner
12811
+ };
12812
+ }
12813
+ return convertLegacyLeaf(n);
12814
+ }
12815
+ function convertLegacyLeaf(leaf) {
12816
+ if (leaf.type === void 0) return leaf;
12817
+ const result = { ...leaf };
12818
+ if ("column" in result) {
12819
+ const c = parseLegacyLeafColumn(result.column);
12820
+ if (c === void 0) return void 0;
12821
+ result.column = c;
12822
+ }
12823
+ if ("rhs" in result) {
12824
+ const c = parseLegacyLeafColumn(result.rhs);
12825
+ if (c === void 0) return void 0;
12826
+ result.rhs = c;
12827
+ }
12828
+ return result;
12829
+ }
12830
+ function parseLegacyLeafColumn(s) {
12831
+ if (typeof s !== "string") return void 0;
12832
+ const parsed = parseJsonSafely(s);
12833
+ if (!parsed || typeof parsed !== "object") return void 0;
12834
+ if (!("type" in parsed) || !("id" in parsed)) return void 0;
12835
+ const t = parsed.type;
12836
+ if (t !== "axis" && t !== "column") return void 0;
12837
+ return parsed;
12838
+ }
12839
+ //#endregion
12840
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
12841
+ /** Adapt a {@link ColumnRecipe} to the plain {@link RuleColumn} shape. */
12842
+ function toRuleColumn(col) {
12843
+ return {
12844
+ id: extractPObjectId(col.id),
12845
+ spec: col.getSpec()
12846
+ };
12847
+ }
12848
+ /** Check if column should be omitted from the table */
12849
+ function isColumnHidden(spec) {
12850
+ return readAnnotation(spec, Annotation.Table.Visibility) === "hidden";
12851
+ }
12852
+ /** Check if column is hidden by default */
12853
+ function isColumnOptional(spec) {
12854
+ return readAnnotation(spec, Annotation.Table.Visibility) === "optional";
12855
+ }
12856
+ /** Get effective visibility for a column. Rule map lookup first, then annotation fallback. */
12857
+ function getEffectiveVisibility(col, visibilityByColId) {
12858
+ const rule = visibilityByColId?.get(col.id);
12859
+ if (rule !== void 0) return rule.visibility;
12860
+ if (isColumnHidden(col.spec)) return "hidden";
12861
+ if (isColumnOptional(col.spec)) return "optional";
12862
+ }
12863
+ /** Get ordering priority for a column. Rule map lookup first, then annotation fallback. */
12864
+ function getOrderPriority(col, orderByColId) {
12865
+ const rule = orderByColId?.get(col.id);
12866
+ if (rule !== void 0) return rule.priority;
12867
+ const annotation = Number(readAnnotation(col.spec, Annotation.Table.OrderPriority));
12868
+ return isNaN(annotation) ? void 0 : annotation;
12869
+ }
12870
+ /**
12871
+ * Evaluate display rules against a set of columns and return a map of `colId → winning rule`
12872
+ * (first-match-wins, preserving original rule order).
12873
+ *
12874
+ * Predicate-based rules (`ColumnMatcher`) are evaluated directly on the spec.
12875
+ * Selector-based rules (`ColumnSelector`) are matched via the
12876
+ * `columnsCollection` service — the inline column ids must be resolvable in
12877
+ * the active render ctx for the host to read their specs.
12878
+ */
12879
+ function evaluateRules(rules, columns) {
12880
+ const result = /* @__PURE__ */ new Map();
12881
+ if (rules.length === 0 || columns.length === 0) return result;
12882
+ const selectorRules = rules.filter((rule) => typeof rule.match !== "function");
12883
+ const selectorHitsByRule = /* @__PURE__ */ new Map();
12884
+ if (selectorRules.length > 0) {
12885
+ const baseCollection = ColumnsCollection([{
12886
+ columns: uniqBy(columns, (col) => col.id),
12887
+ isFinal: true
12888
+ }]);
12889
+ for (const rule of selectorRules) {
12890
+ const hitIds = baseCollection.filter({ include: rule.match }).getColumnIds();
12891
+ if (hitIds.length === 0) continue;
12892
+ selectorHitsByRule.set(rule, new Set(hitIds.map((id) => extractPObjectId(id))));
12893
+ }
12894
+ }
12895
+ for (const col of columns) {
12896
+ const colKey = extractPObjectId(col.id);
12897
+ for (const rule of rules) if (selectorHitsByRule.get(rule)?.has(colKey) ?? false) {
12898
+ result.set(colKey, rule);
12899
+ break;
12900
+ }
12901
+ }
12902
+ return result;
12903
+ }
12904
+ /**
12905
+ * Build a sidecar map `columnId → AnnotationDataStatus` derived from each
12906
+ * recipe's own status. This is *rendering* metadata — kept out of the spec
12907
+ * so it cannot perturb column identity (id-bearing spec overrides would
12908
+ * diverge the visible PTable's column ids from the full table / pframe).
12909
+ *
12910
+ * Mapping `ColumnFieldStatus` × actual byte-presence → `AnnotationDataStatus`:
12911
+ * - `absent` → `"absent"`
12912
+ * - `resolving` → `"computing"`
12913
+ * - `present` + `hasColumnData()` → `"ready"`
12914
+ * - `present` + no bytes yet → `"computing"`
12915
+ *
12916
+ * Intentionally scoped to visible columns — the probe is meaningful only for
12917
+ * what the user will actually see.
12918
+ */
12919
+ function buildDataStatusMap(columns, opts = {}) {
12920
+ return columns.reduce((acc, c) => (acc[c.id] = deriveDataStatus(c, opts), acc), {});
12921
+ }
12922
+ function deriveDataStatus(column, opts) {
12923
+ const field = column.getDataStatus();
12924
+ if (field === "absent") return "absent";
12925
+ if (field === "resolving") return "computing";
12926
+ return hasColumnData(column, opts) ? "ready" : "computing";
12927
+ }
12928
+ /** Derive labels for all table elements: columns via deriveDistinctLabels, axes from label columns. */
12929
+ function deriveAllLabels(options) {
12930
+ const { columns, deriveLabelsOptions } = options;
12931
+ return deriveDistinctLabels(columns.map((c) => ({
12932
+ spec: c.spec,
12933
+ linkerPath: c.linkerPath?.map((step) => ({ spec: step.linker.spec })),
12934
+ qualifications: c.qualifications
12935
+ })), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
12936
+ }
12937
+ //#endregion
12938
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
12939
+ /**
12940
+ * Assemble a ptable def directly from recipes. Each secondary recipe is its own
12941
+ * outer-joined subtree: `getQuery()` encodes its linker chain, and its
12942
+ * hit-/queries-qualifications are derived on the spot via {@link hitQualifications}
12943
+ * / {@link queriesQualifications} — no pre-extracted DTO. Bare leaves yield empty
12944
+ * qualifications, so plain {@link ColumnRecipe} arrays (e.g. label columns) work
12945
+ * unchanged.
12946
+ */
12947
+ function createPTableDefV3(params) {
12948
+ let query = {
12949
+ type: params.primaryJoinType === "inner" ? "innerJoin" : "fullJoin",
12950
+ entries: params.primary.map((c) => columnToJoinEntry(c, []))
12951
+ };
12952
+ if (params.secondary.length > 0) query = {
12953
+ type: "outerJoin",
12954
+ primary: {
12955
+ entry: query,
12956
+ qualifications: params.secondary.flatMap((s) => {
12957
+ const quals = queriesQualifications(s);
12958
+ return params.primary.flatMap((p) => quals[p.id] ?? []);
12959
+ })
12960
+ },
12961
+ secondary: params.secondary.map((c) => columnToJoinEntry(c, hitQualifications(c)))
12962
+ };
12963
+ if (!isNil(params.filters)) {
12964
+ const nonEmpty = distillFilterSpec(params.filters);
12965
+ if (!isNil(nonEmpty)) {
12966
+ const pridicate = filterSpecToSpecQueryExpr(nonEmpty);
12967
+ if (!isBooleanExpression(pridicate)) throw new Error(`Filter conversion produced a non-boolean expression (got type "${pridicate.type}"), expected a boolean predicate for query filtering`);
12968
+ query = {
12969
+ type: "filter",
12970
+ input: query,
12971
+ predicate: pridicate
12972
+ };
12973
+ }
12974
+ }
12975
+ if (!isNil(params.sorting) && params.sorting.length > 0) query = {
12976
+ type: "sort",
12977
+ input: query,
12978
+ sortBy: params.sorting.map((s) => ({
12979
+ expression: columnIdToExpr(s.column),
12980
+ ascending: s.ascending,
12981
+ nullsFirst: s.naAndAbsentAreLeastValues
12982
+ }))
12983
+ };
12984
+ return { query };
12985
+ }
12986
+ function columnIdToExpr(col) {
12987
+ return col.type === "axis" ? {
12988
+ type: "axisRef",
12989
+ value: col.id
12990
+ } : {
12991
+ type: "columnRef",
12992
+ value: col.id
12993
+ };
12994
+ }
12995
+ function columnToJoinEntry(col, qualifications) {
12996
+ return {
12997
+ entry: col.getQuery(),
12998
+ qualifications
12999
+ };
13000
+ }
13001
+ //#endregion
13002
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
13003
+ function createColumnResolver(columns) {
13004
+ const axisIds = [];
13005
+ for (const c of columns) for (const ax of c.getSpec().axesSpec) axisIds.push(getAxisId(ax));
13006
+ const byFullId = /* @__PURE__ */ new Map();
13007
+ const byPObjectId = /* @__PURE__ */ new Map();
13008
+ for (const c of columns) {
13009
+ byFullId.set(c.id, c);
13010
+ const pid = extractPObjectId(c.id);
13011
+ if (!byPObjectId.has(pid)) byPObjectId.set(pid, c);
13012
+ }
13013
+ return (ref) => {
13014
+ if (ref.type === "axis") return axisIds.some((a) => matchAxisId(ref.id, a)) ? ref : void 0;
13015
+ const hit = byFullId.get(ref.id) ?? byPObjectId.get(extractPObjectId(ref.id));
13016
+ if (hit === void 0) return void 0;
13017
+ return {
13018
+ type: "column",
13019
+ id: hit.id
13020
+ };
13021
+ };
13022
+ }
13023
+ //#endregion
13024
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
13025
+ /**
13026
+ * Discover columns from sources/anchors and split them into primary
13027
+ * (direct anchor hits — zero-hop, query is a bare column) and secondary
13028
+ * (reached via a linker chain, query carries a join).
13029
+ */
13030
+ function discoverTableColumns(ctx, options) {
13031
+ const discoveredColumns = ColumnsCollection(options.sources, { ctx: ctx.ctx }).discover({
13032
+ ...options.selector,
13033
+ anchors: options.anchors
13034
+ }).getColumns();
13035
+ const primary = [];
13036
+ const secondary = [];
13037
+ for (const col of discoveredColumns) if (hasSingleDataColumn(col)) primary.push(col);
13038
+ else secondary.push(col);
13039
+ return {
13040
+ primary,
13041
+ secondary
13042
+ };
13043
+ }
13044
+ /**
13045
+ * Discover label columns matching the axes of the given value columns from
13046
+ * ctx providers. Returns a list of label {@link ColumnRecipe}s.
13047
+ *
13048
+ * Primary columns are used as anchors for axis-aware label discovery.
13049
+ * `maxHops` is taken from the longest linker chain present in `columns`.
13050
+ */
13051
+ function discoverLabelColumns(ctx, primary) {
13052
+ if (primary.length === 0) return [];
13053
+ const axes = primary.flatMap((col) => col.getSpec().axesSpec);
13054
+ return ColumnsCollection(void 0, { ctx: ctx.ctx }).discover({
13055
+ include: axes.map((a) => ({
13056
+ name: {
13057
+ type: "exact",
13058
+ value: PColumnName.Label
13059
+ },
13060
+ axes: [{ name: {
13061
+ type: "exact",
13062
+ value: a.name
13063
+ } }]
13064
+ })),
13065
+ anchors: Object.fromEntries(primary.map((col, i) => [`anchor_${i}`, col.getSpec()])),
13066
+ maxHops: 0
13067
+ }).getColumns();
13068
+ }
13069
+ //#endregion
13070
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
13071
+ function createPlDataTableV3(ctx, options) {
13072
+ const state = upgradePlDataTableStateV2(options.tableState);
13073
+ const primaryJoinType = options.primaryJoinType ?? "full";
13074
+ const resolved = resolveInputColumns(ctx, options);
13075
+ if (resolved === void 0) return void 0;
13076
+ const { primary, secondary } = resolved;
13077
+ if (primary.length === 0) return void 0;
13078
+ const { direct, linked } = splitByTopology(secondary);
13079
+ const derivedLabels = deriveAllLabels({
13080
+ columns: [...primary, ...secondary].filter((c) => !isColumnHidden(c.getSpec())).map(toLabelableColumn),
13081
+ deriveLabelsOptions: {
13082
+ includeNativeLabel: true,
13083
+ ...options.labelsOptions
13084
+ }
13085
+ });
13086
+ const allColumnsForRules = [
13087
+ ...primary,
13088
+ ...direct,
13089
+ ...linked,
13090
+ ...collectLinkerSnapshots(linked)
13091
+ ];
13092
+ const visibilityByColId = evaluateRules(options.displayOptions?.visibility ?? [], allColumnsForRules);
13093
+ const orderByColId = evaluateRules(options.displayOptions?.ordering ?? [], allColumnsForRules);
13094
+ const resolver = createColumnResolver([
13095
+ ...primary,
13096
+ ...direct,
13097
+ ...linked.flatMap((lc) => [...collectLinkerColumns(lc), lc])
13098
+ ]);
13099
+ const remapedDefaultFilters = remapFilterColumnIds(options.filters, resolver);
13100
+ const filters = filterFilters(concatFilters(state.pTableParams.filters, state.pTableParams.defaultFilters ?? remapedDefaultFilters), resolver);
13101
+ const sorting = filterSorting(resolveSorting(state.pTableParams.sorting, remapSortingColumnIds(options.sorting, resolver)), resolver);
13102
+ const fullDef = createPTableDefV3({
13103
+ primaryJoinType,
13104
+ primary,
13105
+ secondary: [...direct, ...linked],
13106
+ filters,
13107
+ sorting
13108
+ });
13109
+ const fullHandle = ctx.createPTableV2(fullDef);
13110
+ const pframeHandle = ctx.createPFrame(uniq([
13111
+ ...primary.map((v) => extractPObjectId(v.id)),
13112
+ ...direct.map((v) => extractPObjectId(v.id)),
13113
+ ...linked.map((v) => extractPObjectId(v.id))
13114
+ ]));
13115
+ const hiddenSpecs = state.pTableParams.hiddenColIds;
13116
+ const hiddenColumnIds = computeHiddenColumns({
13117
+ columns: [
13118
+ ...primary,
13119
+ ...direct,
13120
+ ...linked
13121
+ ],
13122
+ visibilityByColId,
13123
+ sorting,
13124
+ filters,
13125
+ hiddenSpecs
13126
+ });
13127
+ const visible = {
13128
+ primary,
13129
+ direct: direct.filter((c) => !hiddenColumnIds.has(c.id)),
13130
+ linked: linked.filter((c) => !hiddenColumnIds.has(c.id))
13131
+ };
13132
+ const visibleDef = createPTableDefV3({
13133
+ primaryJoinType,
13134
+ primary,
13135
+ secondary: [...visible.direct, ...visible.linked],
13136
+ filters,
13137
+ sorting
13138
+ });
13139
+ const visibleHandle = ctx.createPTableV2(visibleDef);
13140
+ const columnsMeta = buildColumnsMeta({
13141
+ fullColumns: [
13142
+ ...primary,
13143
+ ...direct,
13144
+ ...linked
13145
+ ],
13146
+ visibleColumns: [
13147
+ ...visible.primary,
13148
+ ...visible.direct,
13149
+ ...visible.linked
13150
+ ],
13151
+ primaryColumns: primary,
13152
+ derivedLabels,
13153
+ visibilityByColId,
13154
+ orderByColId
13155
+ });
13156
+ return {
13157
+ sourceId: state.pTableParams.sourceId,
13158
+ fullTableHandle: fullHandle,
13159
+ fullPframeHandle: pframeHandle,
13160
+ visibleTableHandle: visibleHandle,
13161
+ defaultFilters: remapedDefaultFilters,
13162
+ columnsMeta
13163
+ };
13164
+ }
13165
+ /** Normalize either option branch into a {primary, secondary} pair of recipes. */
13166
+ function resolveInputColumns(ctx, options) {
13167
+ if ("primaryColumns" in options) {
13168
+ const primary = options.primaryColumns;
13169
+ const secondary = options.columns ?? [];
13170
+ const labels = discoverLabelColumns(ctx, primary);
13171
+ const primaryIds = new Set(primary.map((c) => c.id));
13172
+ return {
13173
+ primary,
13174
+ secondary: dedupColumns([...secondary, ...labels].filter((c) => !primaryIds.has(c.id)), (c) => c.id, (c) => c.getSpec())
13175
+ };
13176
+ }
13177
+ if (isPlainObject$1(options.columns)) return discoverTableColumns(ctx, options.columns);
13178
+ }
13179
+ /** Split secondary recipes by query topology: leaves (no linker chain) vs joined. */
13180
+ function splitByTopology(columns) {
13181
+ const direct = [];
13182
+ const linked = [];
13183
+ for (const c of columns) if (hasSingleDataColumn(c)) direct.push(c);
13184
+ else linked.push(c);
13185
+ return {
13186
+ direct,
13187
+ linked
13188
+ };
13189
+ }
13190
+ /** All linker recipes across the given linked columns, deduped by id. */
13191
+ function collectLinkerSnapshots(linked) {
13192
+ return uniqueBy(linked.flatMap((c) => collectLinkerColumns(c)), (c) => c.id);
13193
+ }
13194
+ function toLabelableColumn(col) {
13195
+ return {
13196
+ id: col.id,
13197
+ spec: col.getSpec(),
13198
+ linkerPath: collectLinkerColumns(col).map((linker) => ({ linker: { spec: linker.getSpec() } })),
13199
+ qualifications: {
13200
+ forHit: [...hitQualifications(col)],
13201
+ forQueries: queriesQualifications(col)
13202
+ }
13203
+ };
13204
+ }
13205
+ /**
13206
+ * Compute display metadata as a sidecar keyed by each emitted column's
13207
+ * `ColumnUniversalId` (and axis `AxisId`), instead of baking it into the specs
13208
+ * via `withSpecs`. Spec overrides change a recipe's id, so the same physical
13209
+ * column reached two ways would diverge into two ids and render twice; keeping
13210
+ * meta out of the spec preserves identity and lets dedup collapse such cases.
13211
+ * The UI overlays this onto the engine-emitted specs at render time.
13212
+ */
13213
+ function buildColumnsMeta(params) {
13214
+ const { fullColumns, visibleColumns, primaryColumns, derivedLabels } = params;
13215
+ const { visibilityByColId, orderByColId } = params;
13216
+ const visibleStatus = buildDataStatusMap(visibleColumns);
13217
+ const columns = fullColumns.reduce((acc, c) => {
13218
+ const rc = toRuleColumn(c);
13219
+ acc[c.id] = {
13220
+ label: derivedLabels[c.id],
13221
+ visibility: getEffectiveVisibility(rc, visibilityByColId),
13222
+ order: getOrderPriority(rc, orderByColId),
13223
+ status: visibleStatus[c.id]
13224
+ };
13225
+ return acc;
13226
+ }, {});
13227
+ const primaryAxisKeys = new Set(primaryColumns.flatMap((c) => c.getSpec().axesSpec.map((a) => canonicalizeAxisId(a))));
13228
+ return {
13229
+ columns,
13230
+ axes: fullColumns.reduce((acc, c) => c.getSpec().axesSpec.reduce((inner, ax) => {
13231
+ const key = canonicalizeAxisId(ax);
13232
+ if (inner[key] === void 0) inner[key] = { hidden: !primaryAxisKeys.has(key) };
13233
+ return inner;
13234
+ }, acc), {})
13235
+ };
13236
+ }
13237
+ /** Drop filter leaves whose column references cannot be resolved; rewrite the
13238
+ * resolvable ones through the resolver. Prune empty and/or/not groups. */
13239
+ function filterFilters(filters, resolver) {
13240
+ if (isNil$1(filters)) return filters;
13241
+ const rewriteLeaf = (leaf) => {
13242
+ if (leaf.type === void 0) return leaf;
13243
+ const result = { ...leaf };
13244
+ if ("column" in result) {
13245
+ const c = resolver(result.column);
13246
+ if (isNil$1(c)) return void 0;
13247
+ result.column = c;
13248
+ }
13249
+ if ("rhs" in result) {
13250
+ const c = resolver(result.rhs);
13251
+ if (isNil$1(c)) return void 0;
13252
+ result.rhs = c;
13253
+ }
13254
+ return result;
13255
+ };
13256
+ const prune = (node) => {
13257
+ if (node.type === "and" || node.type === "or") {
13258
+ const kept = node.filters.map((f) => prune(f)).filter((f) => !isNil$1(f));
13259
+ if (kept.length === 0) return void 0;
13260
+ return {
13261
+ type: node.type,
13262
+ filters: kept
13263
+ };
13264
+ }
13265
+ if (node.type === "not") {
13266
+ const inner = prune(node.filter);
13267
+ return isNil$1(inner) ? void 0 : {
13268
+ type: "not",
13269
+ filter: inner
13270
+ };
13271
+ }
13272
+ return rewriteLeaf(node);
13273
+ };
13274
+ return prune(filters);
13275
+ }
13276
+ /** Merge two filter trees into one AND-combined tree. Returns the non-nil one if the other is nil.
13277
+ * Exported for unit testing. */
13278
+ function concatFilters(a, b) {
13279
+ if (isNil$1(a)) return b;
13280
+ if (isNil$1(b)) return a;
13281
+ const operands = (f) => f.type === "and" ? f.filters : [f];
13282
+ return {
13283
+ type: "and",
13284
+ filters: [...operands(a), ...operands(b)]
13285
+ };
13286
+ }
13287
+ /** Pick user sorting from state if set, otherwise fall back to options default.
13288
+ * null = user has not touched sorting → use default;
13289
+ * [] = user has explicitly cleared sorting → no sorting (default ignored). */
13290
+ function resolveSorting(userSorting, defaultSorting) {
13291
+ return (isNil$1(userSorting) ? defaultSorting : userSorting) ?? [];
13292
+ }
13293
+ /** Rewrite sorting entries through the resolver; drop those that fail to resolve. */
13294
+ function filterSorting(sorting, resolver) {
13295
+ return sorting.flatMap((s) => {
13296
+ const col = resolver(s.column);
13297
+ return isNil$1(col) ? [] : [{
13298
+ ...s,
13299
+ column: col
13300
+ }];
13301
+ });
13302
+ }
13303
+ /** Determine which columns should be hidden based on state or optional-column defaults.
13304
+ * Keyed by the recipe's logical {@link ColumnUniversalId} (rich) — variants of
13305
+ * the same physical column are independently visible/hidden. */
13306
+ function computeHiddenColumns(params) {
13307
+ const { columns, visibilityByColId, sorting, filters, hiddenSpecs } = params;
13308
+ const visibilityOf = (c) => getEffectiveVisibility(toRuleColumn(c), visibilityByColId);
13309
+ const alwaysHidden = columns.filter((c) => visibilityOf(c) === "hidden").map((c) => c.id);
13310
+ const optionalHidden = !isNil$1(hiddenSpecs) ? hiddenSpecs.filter((s) => s.type === "column").map((s) => s.id) : columns.filter((c) => visibilityOf(c) === "optional").map((c) => c.id);
13311
+ const initial = [...alwaysHidden, ...optionalHidden];
13312
+ const preserved = collectPreservedColumnIds(sorting, filters);
13313
+ return new Set(initial.filter((id) => !preserved.has(id)));
13314
+ }
13315
+ /** Collect IDs of columns that must remain visible (sorted, filtered). */
13316
+ function collectPreservedColumnIds(sorting, filters) {
13317
+ const sortedIds = (sorting ?? []).map((s) => s.column).filter((c) => c.type === "column").map((c) => c.id);
13318
+ const filterIds = !isNil$1(filters) ? collectFilterSpecColumns(filters).flatMap((c) => c.type === "column" ? [c.id] : []) : [];
13319
+ return /* @__PURE__ */ new Set([...sortedIds, ...filterIds]);
13320
+ }
13321
+ /** Remap column references in sorting entries through the resolver.
13322
+ * Unresolved entries are dropped with a warning (best-effort contract). */
13323
+ function remapSortingColumnIds(sorting, resolver) {
13324
+ return sorting?.flatMap((s) => {
13325
+ const col = resolver(s.column);
13326
+ if (isNil$1(col)) {
13327
+ console.warn(`Sorting column ${JSON.stringify(s.column)} does not match any discovered column — dropped.`);
13328
+ return [];
13329
+ }
13330
+ return [{
13331
+ ...s,
13332
+ column: col
13333
+ }];
13334
+ });
13335
+ }
13336
+ /** Remap column references in a filter tree through the resolver.
13337
+ * Unresolved leaves are dropped with a warning; empty groups are pruned. */
13338
+ function remapFilterColumnIds(filters, resolver) {
13339
+ if (isNil$1(filters)) return filters;
13340
+ const mapLeaf = (leaf) => {
13341
+ if (leaf.type === void 0) return leaf;
13342
+ const result = { ...leaf };
13343
+ if ("column" in result) {
13344
+ const c = resolver(result.column);
13345
+ if (isNil$1(c)) {
13346
+ console.warn(`Filter column ${JSON.stringify(result.column)} does not match any discovered column — dropped.`);
13347
+ return;
13348
+ }
13349
+ result.column = c;
13350
+ }
13351
+ if ("rhs" in result) {
13352
+ const c = resolver(result.rhs);
13353
+ if (isNil$1(c)) {
13354
+ console.warn(`Filter rhs ${JSON.stringify(result.rhs)} does not match any discovered column — dropped.`);
13355
+ return;
13356
+ }
13357
+ result.rhs = c;
13358
+ }
13359
+ return result;
13360
+ };
13361
+ const prune = (node) => {
13362
+ if (node.type === "and" || node.type === "or") {
13363
+ const kept = node.filters.map((f) => prune(f)).filter((f) => !isNil$1(f));
13364
+ if (kept.length === 0) return void 0;
13365
+ return {
13366
+ type: node.type,
13367
+ filters: kept
13368
+ };
13369
+ }
13370
+ if (node.type === "not") {
13371
+ const inner = prune(node.filter);
13372
+ return isNil$1(inner) ? void 0 : {
13373
+ type: "not",
13374
+ filter: inner
13375
+ };
13376
+ }
13377
+ return mapLeaf(node);
13378
+ };
13379
+ return prune(filters);
13380
+ }
13381
+ (/* @__PURE__ */ __commonJSMin(((exports, module) => {
13382
+ exports = module.exports = stringify;
13383
+ exports.getSerialize = serializer;
13384
+ function stringify(obj, replacer, spaces, cycleReplacer) {
13385
+ return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
13386
+ }
13387
+ function serializer(replacer, cycleReplacer) {
13388
+ var stack = [], keys = [];
13389
+ if (cycleReplacer == null) cycleReplacer = function(key, value) {
13390
+ if (stack[0] === value) return "[Circular ~]";
13391
+ return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]";
13392
+ };
13393
+ return function(key, value) {
13394
+ if (stack.length > 0) {
13395
+ var thisPos = stack.indexOf(this);
13396
+ ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
13397
+ ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
13398
+ if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value);
13399
+ } else stack.push(value);
13400
+ return replacer == null ? value : replacer.call(this, key, value);
13401
+ };
13402
+ }
13403
+ })))();
13404
+ const PlErrorLike = objectType({
13405
+ type: literalType("PlError"),
13406
+ name: stringType(),
13407
+ message: stringType(),
13408
+ fullMessage: stringType().optional(),
13409
+ stack: stringType().optional()
13410
+ }).extend({
13411
+ cause: lazyType(() => ErrorLike).optional(),
13412
+ errors: lazyType(() => ErrorLike.array()).optional()
13413
+ });
13414
+ const ErrorLike = unionType([objectType({
13415
+ type: literalType("StandardError"),
13416
+ name: stringType(),
13417
+ message: stringType(),
13418
+ stack: stringType().optional()
13419
+ }).extend({
13420
+ cause: lazyType(() => ErrorLike).optional(),
13421
+ errors: lazyType(() => ErrorLike.array()).optional()
11419
13422
  }), PlErrorLike]);
11420
13423
  const ErrorShape = objectType({
11421
13424
  name: stringType(),
@@ -11427,7 +13430,7 @@ const ErrorShape = objectType({
11427
13430
  errors: lazyType(() => ErrorShape.array()).optional()
11428
13431
  });
11429
13432
  //#endregion
11430
- //#region ../model/dist/index.js
13433
+ //#region ../model/dist/render-utils.js
11431
13434
  /** A selector `name`/`domain` given as a bare string normalizes to a REGEX matcher, so an
11432
13435
  * exact name must be spelled out. `"pl7.app/frequency"` as a regex is unanchored and `.`
11433
13436
  * matches any character, which would also admit `pl7.app/frequencyRatio`. */
@@ -11450,39 +13453,343 @@ function dedupByLeafId(recipes) {
11450
13453
  return true;
11451
13454
  });
11452
13455
  }
13456
+ /**
13457
+ * The p-columns of one workflow output, or undefined while the block is still computing.
13458
+ *
13459
+ * `getPColumns()` throws two different ways and they must not be treated alike. Mid-run the
13460
+ * resource tree is incomplete and traversal can throw — that is transient and means "not yet".
13461
+ * Once the block is ready-or-error, a throw means the workflow FAILED, and swallowing it makes a
13462
+ * crashed run indistinguishable from a healthy empty one: the output reports ok with no value,
13463
+ * the block shows Done, and the map is simply blank. That cost a day of debugging once already,
13464
+ * so past readiness the error is rethrown and surfaces on the output.
13465
+ */
13466
+ function outputPColumns(ctx, name) {
13467
+ try {
13468
+ const node = ctx.outputs?.resolve(name);
13469
+ if (node === void 0) return void 0;
13470
+ return node.getPColumns();
13471
+ } catch (e) {
13472
+ if (String(e).includes("field not found")) return void 0;
13473
+ if (ctx.outputs?.getIsReadyOrError() === false) return void 0;
13474
+ throw e;
13475
+ }
13476
+ }
13477
+ /**
13478
+ * Spec for a ref from the result pool, reported absent only once that absence has settled.
13479
+ *
13480
+ * `getPColumnSpecByRef` answers from the pool as it stands and registers nothing, so a column
13481
+ * that has not reached the pool yet is indistinguishable from one that never will. The output
13482
+ * settles at `undefined`, and a table fed by it then renders its not-ready text ("Select score
13483
+ * columns in Settings, then Run") for the seconds the pool takes to fill, although nothing is
13484
+ * wrong and the data is on its way. `getSpecs` does register — the middle layer marks the render
13485
+ * unstable while the pool is incomplete (`specs_from_pool_incomplete`) — so consulting it on a
13486
+ * miss keeps the output unsettled until the pool is complete and the absence is real.
13487
+ */
13488
+ function poolSpecByRef(ctx, ref) {
13489
+ const spec = ctx.resultPool.getPColumnSpecByRef(ref);
13490
+ if (spec !== void 0) return spec;
13491
+ ctx.resultPool.getSpecs();
13492
+ }
13493
+ //#endregion
13494
+ //#region ../model/dist/specs.js
13495
+ /**
13496
+ * Column and axis names this block shares with its workflow and with the profiler upstream.
13497
+ *
13498
+ * Every string here is a contract: change one and the matching literal in
13499
+ * `workflow/src/main.tpl.tengo` — or in the profiler that emits it — has to change with it, or
13500
+ * the column simply stops being found and an output goes quietly empty. They live in one file so
13501
+ * that obligation is visible rather than buried among the render helpers.
13502
+ */
11453
13503
  const STATE_MATRIX = "pl7.app/repertoire/stateMatrix";
11454
- const LANDSCAPE_VALUE = "pl7.app/repertoire/singleMutantValue";
11455
13504
  const LANDSCAPE_SCORE_REF = "pl7.app/repertoire/landscapeScoreRef";
11456
- const LANDSCAPE_SCORE_INDEX = "pl7.app/repertoire/landscapeScoreIndex";
11457
- const NO_DATASET_LABEL = "No dataset selected";
13505
+ const MUTATION_ID_AXIS = "pl7.app/repertoire/mutationId";
13506
+ const MUTATION_VARIANT_LINK = "pl7.app/repertoire/mutationVariantLink";
13507
+ const BROWSABLE_MUTATION = "pl7.app/repertoire/browsableMutation";
13508
+ //#endregion
13509
+ //#region ../model/dist/drill-down-table.js
11458
13510
  /**
11459
- * Default state for a mutation-landscape chart. Used by `init` for the placeholder and by the UI
11460
- * for each score a run produces, so the two look alike.
13511
+ * The Table tab: every variant carrying the active drill-down's substitution, at any mutation
13512
+ * count.
11461
13513
  *
11462
- * @param currentTab `"settings"` opens the Settings drawer, `null` leaves it closed
13514
+ * The block exports only the `[variantKey, mutationId]` linker as the primary column; sequence,
13515
+ * mutations, mutation count, abundance and the scores are joined in from the result pool on the
13516
+ * shared variantKey axis, so none of them is copied into this block's own exports and the user
13517
+ * can surface any other variant-keyed column later.
11463
13518
  */
11464
- function makeLandscapeChartState(title, currentTab) {
11465
- return {
11466
- title,
11467
- template: "heatmap",
11468
- currentTab,
11469
- layersSettings: { heatmap: {
11470
- normalizationDirection: null,
11471
- transform: null
11472
- } },
11473
- axesSettings: {
11474
- axisX: { cellSize: 20 },
11475
- axisY: {
11476
- hideAxisLabels: false,
11477
- cellSize: 20
11478
- }
13519
+ function drillDownTableModel(ctx) {
13520
+ const mutationId = ctx.data.activeDrillDown;
13521
+ const linker = outputPColumns(ctx, "mutationVariantLinkPf")?.find((c) => c.spec.name === MUTATION_VARIANT_LINK);
13522
+ if (linker === void 0) return void 0;
13523
+ const mutationAxis = linker.spec.axesSpec.find((a) => a.name === MUTATION_ID_AXIS);
13524
+ if (mutationAxis === void 0) return void 0;
13525
+ const stateMatrixRef = ctx.data.stateMatrixRef;
13526
+ if (stateMatrixRef === void 0) return void 0;
13527
+ const stateSpec = poolSpecByRef(ctx, stateMatrixRef);
13528
+ if (!stateSpec) return void 0;
13529
+ const discovered = ColumnsCollection(["result_pool"]).discover({
13530
+ anchors: { main: stateSpec },
13531
+ mode: "enrichment",
13532
+ maxHops: 0,
13533
+ exclude: [{ annotations: { "pl7.app/isLinkerColumn": exactMatch("true") } }]
13534
+ }).getColumns();
13535
+ const secondary = dedupByLeafId(discovered).filter((recipe) => {
13536
+ const axes = recipe.getSpec().axesSpec;
13537
+ return axes.length === 1 && axes[0].name === "pl7.app/variantKey";
13538
+ });
13539
+ const scoreKey = ctx.data.drillDowns.find((d) => d.mutationId === mutationId)?.scoreKey;
13540
+ const activeScoreSpec = scoreKey === void 0 ? void 0 : discovered.find((recipe) => recipe.id === scoreKey)?.getSpec();
13541
+ const visibility = [
13542
+ {
13543
+ match: { name: exactMatch("pl7.app/label") },
13544
+ visibility: "default"
13545
+ },
13546
+ {
13547
+ match: { name: exactMatch("pl7.app/repertoire/mutations") },
13548
+ visibility: "default"
13549
+ },
13550
+ {
13551
+ match: { name: exactMatch("pl7.app/repertoire/mutationCount") },
13552
+ visibility: "default"
13553
+ },
13554
+ {
13555
+ match: {
13556
+ name: exactMatch("pl7.app/sequence"),
13557
+ annotations: { "pl7.app/isMainSequence": exactMatch("true") }
13558
+ },
13559
+ visibility: "default"
11479
13560
  }
11480
- };
13561
+ ];
13562
+ if (activeScoreSpec !== void 0) visibility.push({
13563
+ match: {
13564
+ name: exactMatch(activeScoreSpec.name),
13565
+ domain: Object.fromEntries(Object.entries(activeScoreSpec.domain ?? {}).map(([k, v]) => [k, exactMatch(v)]))
13566
+ },
13567
+ visibility: "default"
13568
+ });
13569
+ visibility.push({
13570
+ match: { name: ".*" },
13571
+ visibility: "optional"
13572
+ });
13573
+ return createPlDataTableV3(ctx, {
13574
+ primaryColumns: [DataColumn.fromColumn(linker)],
13575
+ columns: secondary,
13576
+ displayOptions: { visibility },
13577
+ filters: mutationId === void 0 ? void 0 : {
13578
+ type: "and",
13579
+ filters: [{
13580
+ type: "patternEquals",
13581
+ column: {
13582
+ type: "axis",
13583
+ id: {
13584
+ name: mutationAxis.name,
13585
+ type: mutationAxis.type,
13586
+ domain: mutationAxis.domain
13587
+ }
13588
+ },
13589
+ value: mutationId
13590
+ }]
13591
+ },
13592
+ tableState: ctx.data.drillDownTableState
13593
+ });
13594
+ }
13595
+ //#endregion
13596
+ //#region ../kind/dist/package.js
13597
+ var name = "@platforma-open/milaboratories.repertoire-mutation-heatmap.kind";
13598
+ var version = "1.0.0";
13599
+ //#endregion
13600
+ //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/params.js
13601
+ /**
13602
+ * Establish that a value is an object whose fields a kind can read — the half of a params
13603
+ * check every kind needs and no two kinds differ on.
13604
+ *
13605
+ * Params that arrived from a template file are `unknown`, and before a single field can be
13606
+ * read the value has to be an object. Worth a shared function because the check is easy to
13607
+ * get wrong by hand: `typeof null` is `"object"`, `Object.keys(5)` is `[]` and
13608
+ * `Object.keys(["a"])` is `["0"]`, so a naive test lets `null`, a number and an array through
13609
+ * as if they were empty params.
13610
+ *
13611
+ * What each field must *be* is the kind's own business and stays in the kind, as plain
13612
+ * TypeScript: this package deliberately carries no validation library, so a kind author owes
13613
+ * it no schema.
13614
+ *
13615
+ * A key the kind does not declare is NOT refused. A parser returns the params to use, so a
13616
+ * field it never read is dropped and never reaches the block — the only question was whether
13617
+ * to also complain, and complaining costs more than it catches. It would mean each kind
13618
+ * restating its own field list as strings, with nothing checking that the list stayed in step
13619
+ * with the type: a field added to the contract and read by the parser, but missed in the list,
13620
+ * would turn into a kind that refuses files that are correct. What an unexpected key can
13621
+ * actually mean is a params contract from a different version of the kind, and that is
13622
+ * guarded where it belongs — by the version in the entry's `{name}@{selector}` reference.
13623
+ *
13624
+ * An assertion rather than a parser that returns a copy, so a kind reads its fields off the
13625
+ * value it was handed:
13626
+ *
13627
+ * ```ts
13628
+ * function parseInitializationParams(value: unknown): BlockParams {
13629
+ * assertParamsObject(value);
13630
+ *
13631
+ * const { numbers } = value;
13632
+ * if (numbers !== undefined && !isNumberArray(numbers)) {
13633
+ * throw new Error("'numbers' must be an array of numbers.");
13634
+ * }
13635
+ * return { numbers };
13636
+ * }
13637
+ * ```
13638
+ *
13639
+ * Messages are finished sentences addressed to whoever wrote the file, because that is who
13640
+ * reads them: a kind's rejection is reported against the entry that carried the params.
13641
+ *
13642
+ * @param value The params as they arrived
13643
+ * @throws if `value` is not an object
13644
+ */
13645
+ function assertParamsObject(value) {
13646
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`Params must be an object, not ${describe(value)}.`);
13647
+ }
13648
+ /** What a value is, for a message that has to say why it is not an object. */
13649
+ function describe(value) {
13650
+ if (value === null) return "null";
13651
+ if (value === void 0) return "nothing";
13652
+ if (Array.isArray(value)) return "an array";
13653
+ return `a ${typeof value} (${JSON.stringify(value) ?? String(value)})`;
13654
+ }
13655
+ //#endregion
13656
+ //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/index.js
13657
+ /**
13658
+ * Define a block kind.
13659
+ *
13660
+ * `meta` is the kind's identity — its own `{ name, version }`. Source it from
13661
+ * the package's `package.json` rather than hand-typing literals, so the on-wire
13662
+ * `{name}@{version}` cannot drift from what npm publishes and what the S3
13663
+ * manifest records (all read the same `package.json`):
13664
+ *
13665
+ * ```ts
13666
+ * // a kind package's src/index.ts
13667
+ * import { name, version } from "../package.json" with { type: "json" };
13668
+ * export const kind = defineBlockKind<Params>({ name, version });
13669
+ * ```
13670
+ *
13671
+ * rolldown inlines the JSON import (tree-shaken to the two strings) into the
13672
+ * bundled `kind.js`, so no build-time injection is needed.
13673
+ *
13674
+ * A kind must also declare `parseInitializationParams` — the runtime check applied to params
13675
+ * that came from a template file rather than from typed code. See
13676
+ * {@link CompiledBlockKind} for what it must do.
13677
+ *
13678
+ * @typeParam BlockParams - shape of the params a block of this kind reads. Pinned both
13679
+ * as a type and by `parseInitializationParams`, whose return type is checked against it.
13680
+ */
13681
+ function defineBlockKind(meta) {
13682
+ return Object.freeze({
13683
+ kindSchema: "v1",
13684
+ name: meta.name,
13685
+ version: meta.version,
13686
+ parseInitializationParams: meta.parseInitializationParams
13687
+ });
13688
+ }
13689
+ //#endregion
13690
+ //#region ../kind/dist/index.js
13691
+ /**
13692
+ * The same contract at runtime, for params that arrive from a template file
13693
+ * rather than from typed code.
13694
+ *
13695
+ * The contract names no fields, so there is nothing to read and nothing to
13696
+ * validate beyond the value being an object at all. Keys a template supplies
13697
+ * anyway are dropped by not being read. The return type holds this in step: the
13698
+ * moment `BlockParams` declares a required field, `return {}` stops compiling.
13699
+ */
13700
+ function parseInitializationParams(value) {
13701
+ assertParamsObject(value);
13702
+ return {};
13703
+ }
13704
+ const kind = defineBlockKind({
13705
+ name,
13706
+ version,
13707
+ parseInitializationParams
13708
+ });
13709
+ //#endregion
13710
+ //#region ../model/dist/index.js
13711
+ /**
13712
+ * The section href of one drill-down. The model builds the section list with it and the UI
13713
+ * navigates with it, so the two cannot drift apart on the encoding — which they would, silently,
13714
+ * the first time a designator needed escaping.
13715
+ */
13716
+ /**
13717
+ * `A5C · Bin score (5.5)` — the substitution and the score it is measured on.
13718
+ *
13719
+ * Derived from the produced columns rather than stored on the drill-down: a stored label goes
13720
+ * stale when a score is renamed upstream, and would be missing entirely on any drill-down opened
13721
+ * before it was introduced. Falls back to the bare designator before a run has produced columns.
13722
+ */
13723
+ function drillDownLabel(mutationId, scoreLabel) {
13724
+ return scoreLabel ? `${mutationId} · ${scoreLabel}` : mutationId;
13725
+ }
13726
+ /**
13727
+ * The landscape charts the last run produced, in the user's score order.
13728
+ *
13729
+ * Shared by the `landscapePanels` output and by `.sections()`, which needs the same list to name
13730
+ * one page per score — two derivations of "which charts exist" would drift the moment one of
13731
+ * them changed.
13732
+ */
13733
+ function landscapePanelsFrom(pCols) {
13734
+ if (pCols === void 0) return void 0;
13735
+ const panels = [];
13736
+ for (const col of pCols) {
13737
+ if (col.spec.name !== "pl7.app/repertoire/singleMutantValue") continue;
13738
+ const key = col.spec.annotations?.[LANDSCAPE_SCORE_REF];
13739
+ if (key === void 0) continue;
13740
+ panels.push({
13741
+ key,
13742
+ label: col.spec.annotations?.["pl7.app/label"] ?? "Score",
13743
+ index: Number(col.spec.annotations?.["pl7.app/repertoire/landscapeScoreIndex"] ?? "0"),
13744
+ spec: col.spec
13745
+ });
13746
+ }
13747
+ panels.sort((a, b) => a.index - b.index);
13748
+ return panels;
11481
13749
  }
13750
+ /** The section href of one landscape page. */
13751
+ function landscapeHref(scoreKey) {
13752
+ return `/?score=${encodeURIComponent(scoreKey)}`;
13753
+ }
13754
+ /** `Landscape · Bin score (5.5)` — what the sidebar shows for one landscape page. */
13755
+ function landscapeLabel(scoreLabel) {
13756
+ return `Landscape · ${scoreLabel}`;
13757
+ }
13758
+ /** score id -> display label, from the columns the last run produced. */
13759
+ function scoreLabelsByKey(pCols) {
13760
+ const labels = {};
13761
+ for (const col of pCols ?? []) {
13762
+ if (col.spec.name !== "pl7.app/repertoire/singleMutantValue") continue;
13763
+ const key = col.spec.annotations?.[LANDSCAPE_SCORE_REF];
13764
+ const label = col.spec.annotations?.["pl7.app/label"];
13765
+ if (key !== void 0 && label !== void 0) labels[key] = label;
13766
+ }
13767
+ return labels;
13768
+ }
13769
+ function drillDownHref(mutationId) {
13770
+ return `/drilldown?m=${encodeURIComponent(mutationId)}`;
13771
+ }
13772
+ const NO_DATASET_LABEL = "No dataset selected";
11482
13773
  const dataModel = new DataModelBuilder({ kind }).from("v1").migrate("v2", (v1) => ({
11483
13774
  ...v1,
11484
13775
  singleMutantHeatmapStates: {}
13776
+ })).migrate("v3", (v2) => ({
13777
+ ...v2,
13778
+ singleMutantHeatmapState: withEmptyNAValue(v2.singleMutantHeatmapState),
13779
+ singleMutantHeatmapStates: Object.fromEntries(Object.entries(v2.singleMutantHeatmapStates).map(([key, state]) => [key, withEmptyNAValue(state)]))
13780
+ })).migrate("v4", (v3) => ({
13781
+ ...v3,
13782
+ ...mapChartStates(v3, withParentOnXAxis)
13783
+ })).migrate("v5", (v4) => ({
13784
+ ...v4,
13785
+ drillDowns: [],
13786
+ drillDownChartState: makeDrillDownChartState(),
13787
+ drillDownTableState: createPlDataTableStateV2(),
13788
+ ...mapChartStates(v4, withRegionColoursReseeded)
11485
13789
  })).init(() => ({
13790
+ drillDowns: [],
13791
+ drillDownChartState: makeDrillDownChartState(),
13792
+ drillDownTableState: createPlDataTableStateV2(),
11486
13793
  roundFrequencyRefs: [],
11487
13794
  compositionEpsilon: 1e-6,
11488
13795
  scoreRefs: [],
@@ -11498,7 +13805,10 @@ const dataModel = new DataModelBuilder({ kind }).from("v1").migrate("v2", (v1) =
11498
13805
  } },
11499
13806
  axesSettings: {
11500
13807
  other: { facetColumns: 1 },
11501
- axisX: { cellSize: 20 },
13808
+ axisX: {
13809
+ cellSize: 20,
13810
+ axisLabelsAngle: 45
13811
+ },
11502
13812
  axisY: {
11503
13813
  hideAxisLabels: false,
11504
13814
  cellSize: 20
@@ -11535,7 +13845,7 @@ const platforma$1 = BlockModelV3.create({
11535
13845
  }).output("scoreOptions", (ctx) => {
11536
13846
  const stateMatrixRef = ctx.data.stateMatrixRef;
11537
13847
  if (stateMatrixRef === void 0) return void 0;
11538
- const stateSpec = ctx.resultPool.getPColumnSpecByRef(stateMatrixRef);
13848
+ const stateSpec = poolSpecByRef(ctx, stateMatrixRef);
11539
13849
  if (!stateSpec) return void 0;
11540
13850
  const anchors = { main: stateSpec };
11541
13851
  const columns = ColumnsCollection(["result_pool"]).discover({
@@ -11567,7 +13877,7 @@ const platforma$1 = BlockModelV3.create({
11567
13877
  }).output("roundFrequencyOptions", (ctx) => {
11568
13878
  const stateMatrixRef = ctx.data.stateMatrixRef;
11569
13879
  if (stateMatrixRef === void 0) return void 0;
11570
- const stateSpec = ctx.resultPool.getPColumnSpecByRef(stateMatrixRef);
13880
+ const stateSpec = poolSpecByRef(ctx, stateMatrixRef);
11571
13881
  if (!stateSpec) return void 0;
11572
13882
  return dedupByLeafId(ColumnsCollection(["result_pool"]).discover({
11573
13883
  include: { name: exactMatch("pl7.app/frequency") },
@@ -11591,66 +13901,61 @@ const platforma$1 = BlockModelV3.create({
11591
13901
  if (stateMatrixRef === void 0) return void 0;
11592
13902
  return ctx.resultPool.getPColumnByRef(stateMatrixRef)?.id;
11593
13903
  }).outputWithStatus("singleMutantHeatmapPf", (ctx) => {
11594
- try {
11595
- const pCols = ctx.outputs?.resolve("singleMutantHeatmapPf")?.getPColumns();
11596
- if (pCols === void 0) return void 0;
11597
- return createPFrameForGraphs(ctx, pCols);
11598
- } catch {
11599
- return;
11600
- }
13904
+ const pCols = outputPColumns(ctx, "singleMutantHeatmapPf");
13905
+ if (pCols === void 0) return void 0;
13906
+ return createPFrameForGraphs(ctx, pCols);
11601
13907
  }).output("singleMutantHeatmapPCols", (ctx) => {
11602
- try {
11603
- return ctx.outputs?.resolve("singleMutantHeatmapPf")?.getPColumns();
11604
- } catch {
11605
- return;
11606
- }
11607
- }).output("landscapePanels", (ctx) => {
11608
- let pCols;
11609
- try {
11610
- pCols = ctx.outputs?.resolve("singleMutantHeatmapPf")?.getPColumns();
11611
- } catch {
11612
- return;
11613
- }
13908
+ return outputPColumns(ctx, "singleMutantHeatmapPf");
13909
+ }).output("landscapePanels", (ctx) => landscapePanelsFrom(outputPColumns(ctx, "singleMutantHeatmapPf"))).outputWithStatus("drillDownHeatmapPf", (ctx) => {
13910
+ const pCols = outputPColumns(ctx, "drillDownHeatmapPf");
11614
13911
  if (pCols === void 0) return void 0;
11615
- const panels = [];
11616
- for (const col of pCols) {
11617
- if (col.spec.name !== LANDSCAPE_VALUE) continue;
11618
- const key = col.spec.annotations?.[LANDSCAPE_SCORE_REF];
11619
- if (key === void 0) continue;
11620
- panels.push({
11621
- key,
11622
- label: col.spec.annotations?.["pl7.app/label"] ?? "Score",
11623
- index: Number(col.spec.annotations?.[LANDSCAPE_SCORE_INDEX] ?? "0"),
11624
- spec: col.spec
11625
- });
11626
- }
11627
- panels.sort((a, b) => a.index - b.index);
11628
- return panels;
11629
- }).outputWithStatus("compositionHeatmapPf", (ctx) => {
11630
- try {
11631
- const pCols = ctx.outputs?.resolve("compositionHeatmapPf")?.getPColumns();
11632
- if (pCols === void 0) return void 0;
11633
- return createPFrameForGraphs(ctx, pCols);
11634
- } catch {
11635
- return;
11636
- }
13912
+ return createPFrameForGraphs(ctx, pCols);
13913
+ }).output("drillDownHeatmapPCols", (ctx) => {
13914
+ return outputPColumns(ctx, "drillDownHeatmapPf");
13915
+ }).output("browsableMutationsPf", (ctx) => {
13916
+ const pCols = outputPColumns(ctx, "browsableMutationsPf");
13917
+ if (pCols === void 0 || pCols.length === 0) return void 0;
13918
+ return ctx.createPFrame(pCols);
13919
+ }).output("browsableMutationsColId", (ctx) => {
13920
+ return outputPColumns(ctx, "browsableMutationsPf")?.find((c) => c.spec.name === BROWSABLE_MUTATION)?.id;
13921
+ }).outputWithStatus("drillDownTable", (ctx) => drillDownTableModel(ctx)).outputWithStatus("compositionHeatmapPf", (ctx) => {
13922
+ const pCols = outputPColumns(ctx, "compositionHeatmapPf");
13923
+ if (pCols === void 0) return void 0;
13924
+ return createPFrameForGraphs(ctx, pCols);
11637
13925
  }).output("compositionHeatmapPCols", (ctx) => {
11638
- try {
11639
- return ctx.outputs?.resolve("compositionHeatmapPf")?.getPColumns();
11640
- } catch {
11641
- return;
11642
- }
13926
+ return outputPColumns(ctx, "compositionHeatmapPf");
11643
13927
  }).output("isRunning", (ctx) => ctx.outputs?.getIsReadyOrError() === false).title(() => "Mutation Explorer").subtitle((ctx) => ctx.data.customBlockLabel || ctx.data.defaultBlockLabel || NO_DATASET_LABEL).sections((ctx) => {
11644
- const sections = [{
13928
+ const pCols = outputPColumns(ctx, "singleMutantHeatmapPf");
13929
+ const panels = landscapePanelsFrom(pCols) ?? [];
13930
+ const sections = [];
13931
+ if (panels.length === 0) sections.push({
11645
13932
  type: "link",
11646
13933
  href: "/",
11647
13934
  label: "Single Mutation Landscape"
11648
- }];
11649
- if (ctx.data.roundFrequencyRefs.length >= 2) sections.push({
13935
+ });
13936
+ else for (const p of panels) sections.push({
11650
13937
  type: "link",
11651
- href: "/composition",
11652
- label: "Enrichment Analysis"
13938
+ href: landscapeHref(p.key),
13939
+ label: landscapeLabel(p.label)
11653
13940
  });
13941
+ const drillDowns = ctx.data.drillDowns ?? [];
13942
+ if (drillDowns.length > 0) {
13943
+ const scoreLabels = scoreLabelsByKey(pCols);
13944
+ sections.push({ type: "delimiter" });
13945
+ for (const d of drillDowns) sections.push({
13946
+ type: "link",
13947
+ href: drillDownHref(d.mutationId),
13948
+ label: drillDownLabel(d.mutationId, scoreLabels[d.scoreKey])
13949
+ });
13950
+ }
13951
+ if (ctx.data.roundFrequencyRefs.length >= 2) {
13952
+ sections.push({ type: "delimiter" });
13953
+ sections.push({
13954
+ type: "link",
13955
+ href: "/composition",
13956
+ label: "Enrichment Analysis"
13957
+ });
13958
+ }
11654
13959
  return sections;
11655
13960
  }).done();
11656
13961
  //#endregion