@platforma-open/milaboratories.top-antibodies 4.6.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { r as __toESM, t as __commonJSMin } from "./rolldown-runtime-B-1-B7_t.js";
2
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/plugin_handle.js
2
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/plugin_handle.js
3
3
  const PLUGIN_OUTPUT_PREFIX = "plugin-output#";
4
4
  /** Construct the output key for a plugin output in the block outputs map. */
5
5
  function pluginOutputKey(handle, outputKey) {
6
6
  return `${PLUGIN_OUTPUT_PREFIX}${handle}#${outputKey}`;
7
7
  }
8
8
  //#endregion
9
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_storage.js
9
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/block_storage.js
10
10
  /**
11
11
  * Discriminator key for BlockStorage format detection.
12
12
  * This unique hash-based key identifies data as BlockStorage vs legacy formats.
@@ -3815,7 +3815,7 @@ objectType({
3815
3815
  content: stringType()
3816
3816
  });
3817
3817
  //#endregion
3818
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3818
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/bmodel/block_kind_ref.js
3819
3819
  /**
3820
3820
  * Compose a {@link BlockKindReference} from a kind's `name`/`version`.
3821
3821
  *
@@ -3831,7 +3831,7 @@ objectType({
3831
3831
  to: numberType().min(1)
3832
3832
  });
3833
3833
  //#endregion
3834
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/util.js
3834
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/util.js
3835
3835
  function assertNever(x) {
3836
3836
  throw new Error("Unexpected object: " + x);
3837
3837
  }
@@ -3843,7 +3843,7 @@ function uniqueBy(array, makeId) {
3843
3843
  return [...new Map(array.map((e) => [makeId(e), e])).values()];
3844
3844
  }
3845
3845
  //#endregion
3846
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
3846
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/data_info.js
3847
3847
  /**
3848
3848
  * Type guard function that checks if the given value is a valid DataInfo.
3849
3849
  *
@@ -4034,7 +4034,7 @@ function entriesToDataInfo(dataInfoEntries) {
4034
4034
  }
4035
4035
  }
4036
4036
  //#endregion
4037
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/errors.js
4037
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/errors.js
4038
4038
  var ServiceError = class extends Error {
4039
4039
  name = "ServiceError";
4040
4040
  };
@@ -4058,7 +4058,7 @@ function ensureError(value) {
4058
4058
  return new Error(stringifyValue(value));
4059
4059
  }
4060
4060
  //#endregion
4061
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/json.js
4061
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/json.js
4062
4062
  var import_canonicalize = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
4063
4063
  module.exports = function serialize(object) {
4064
4064
  if (typeof object === "number" && isNaN(object)) throw new Error("NaN is not allowed");
@@ -4091,7 +4091,7 @@ function parseJsonSafely(value, fallback) {
4091
4091
  }
4092
4092
  }
4093
4093
  //#endregion
4094
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4094
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/spec.js
4095
4095
  function readMetadata(metadata, key) {
4096
4096
  return metadata?.[key];
4097
4097
  }
@@ -4419,7 +4419,7 @@ function matchAxisId(query, target) {
4419
4419
  return query.name === target.name && matchDomain$1(query.domain, target.domain) && matchDomain$1(query.contextDomain, target.contextDomain);
4420
4420
  }
4421
4421
  //#endregion
4422
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4422
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/query/utils.js
4423
4423
  const BOOLEAN_TYPES = /* @__PURE__ */ new Set([
4424
4424
  "numericComparison",
4425
4425
  "stringEquals",
@@ -4524,7 +4524,7 @@ function collectSpecQueryColumns(query) {
4524
4524
  return result;
4525
4525
  }
4526
4526
  //#endregion
4527
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4527
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_calculate.js
4528
4528
  function mapPTableDef(def, cb) {
4529
4529
  return {
4530
4530
  ...def,
@@ -4567,7 +4567,7 @@ function mapJoinEntry(entry, cb) {
4567
4567
  }
4568
4568
  }
4569
4569
  //#endregion
4570
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
4570
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/table_common.js
4571
4571
  function getPTableColumnId(spec) {
4572
4572
  switch (spec.type) {
4573
4573
  case "axis": return {
@@ -4581,7 +4581,7 @@ function getPTableColumnId(spec) {
4581
4581
  }
4582
4582
  }
4583
4583
  //#endregion
4584
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4584
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/filtered_column.js
4585
4585
  function stringifyColumnFilteredId(key) {
4586
4586
  return canonicalizeJson(createColumnFilteredKey(key));
4587
4587
  }
@@ -4614,7 +4614,7 @@ function applyAxisFilters(spec, axisFilters) {
4614
4614
  };
4615
4615
  }
4616
4616
  //#endregion
4617
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4617
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/pool/spec.js
4618
4618
  function isPObjectId(value) {
4619
4619
  if (typeof value !== "string") return false;
4620
4620
  return isPObjectKey(parseJsonSafely(value));
@@ -4740,7 +4740,7 @@ function throwError(v) {
4740
4740
  else throw v;
4741
4741
  }
4742
4742
  //#endregion
4743
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4743
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/discovered_column.js
4744
4744
  function isColumnDiscoveredKey(obj) {
4745
4745
  return typeof obj === "object" && obj !== null && "__isDiscovered" in obj;
4746
4746
  }
@@ -4804,7 +4804,7 @@ function isString(value) {
4804
4804
  return typeof value === "string";
4805
4805
  }
4806
4806
  //#endregion
4807
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
4807
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/ids.js
4808
4808
  /**
4809
4809
  * Canonically serializes a column key to a branded string id. Accepts both
4810
4810
  * the new {@link ColumnUniversalKey} and the deprecated {@link UniversalPColumnId}
@@ -4978,7 +4978,7 @@ function extractPObjectId(id) {
4978
4978
  throw new Error(`extractPObjectId: unrecognized column id structure: ${JSON.stringify(id)}`);
4979
4979
  }
4980
4980
  //#endregion
4981
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
4981
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/overridden.js
4982
4982
  function isColumnOverriddenKey(obj) {
4983
4983
  return typeof obj === "object" && obj !== null && "__isOverridden" in obj;
4984
4984
  }
@@ -5100,7 +5100,7 @@ function mergeRecord(a, b) {
5100
5100
  };
5101
5101
  }
5102
5102
  //#endregion
5103
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5103
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/anchored.js
5104
5104
  function axisKey(axis) {
5105
5105
  return (0, import_canonicalize.default)(getAxisId(axis));
5106
5106
  }
@@ -5346,7 +5346,7 @@ function isAnchorAxisRef(value) {
5346
5346
  return typeof value === "object" && "anchor" in value;
5347
5347
  }
5348
5348
  //#endregion
5349
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5349
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/selectors.js
5350
5350
  /**
5351
5351
  * Determines if an axis ID matches an axis selector.
5352
5352
  *
@@ -5472,7 +5472,7 @@ function multiColumnSelectorsToPredicate(selectors) {
5472
5472
  return (spec) => isPColumnSpec(spec) && arr.some((sel) => matchMultiColumnSelector(spec, sel));
5473
5473
  }
5474
5474
  //#endregion
5475
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5475
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/spec/native_id.js
5476
5476
  function deriveNativeId(spec) {
5477
5477
  const result = {
5478
5478
  kind: spec.kind,
@@ -5484,7 +5484,7 @@ function deriveNativeId(spec) {
5484
5484
  return (0, import_canonicalize.default)(result);
5485
5485
  }
5486
5486
  //#endregion
5487
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5487
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/drivers/pframe/linker_columns.js
5488
5488
  var LinkerMap = class LinkerMap {
5489
5489
  /** Graph of linkers connected by axes (single or grouped by parents) */
5490
5490
  data;
@@ -5662,7 +5662,7 @@ var LinkerMap = class LinkerMap {
5662
5662
  }
5663
5663
  };
5664
5664
  //#endregion
5665
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5665
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/flags/block_flags.js
5666
5666
  /**
5667
5667
  * Required PFrames version. Bump this in lockstep with the `@milaboratories/pframes-rs-*`
5668
5668
  * version in `pnpm-workspace.yaml` so blocks built against the new SDK refuse to load on
@@ -5725,7 +5725,7 @@ function createEnrichmentRef(hit, options = {}) {
5725
5725
  };
5726
5726
  }
5727
5727
  //#endregion
5728
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5728
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/value_or_error.js
5729
5729
  function mapValueInVOE(voe, cb) {
5730
5730
  return voe.ok ? {
5731
5731
  ok: true,
@@ -5733,7 +5733,7 @@ function mapValueInVOE(voe, cb) {
5733
5733
  } : voe;
5734
5734
  }
5735
5735
  //#endregion
5736
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
5736
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/resource_types.js
5737
5737
  /** Well-known resource type names used across the platform. */
5738
5738
  const ResourceTypeName = {
5739
5739
  StreamManager: "StreamManager",
@@ -5749,6 +5749,7 @@ const ResourceTypeName = {
5749
5749
  BlobMap: "BlobMap",
5750
5750
  BResolveSingle: "BResolveSingle",
5751
5751
  BResolveSingleNoResult: "BResolveSingleNoResult",
5752
+ BResolveChoice: "BResolveChoice",
5752
5753
  BQueryResult: "BQueryResult",
5753
5754
  TengoTemplate: "TengoTemplate",
5754
5755
  TengoLib: "TengoLib",
@@ -5760,9 +5761,13 @@ const ResourceTypeName = {
5760
5761
  JsonString: "json/string",
5761
5762
  JsonArray: "json/array",
5762
5763
  JsonNumber: "json/number",
5764
+ JsonBool: "json/bool",
5765
+ JsonNull: "json/null",
5766
+ JsonErrorTrace: "json/errorTrace",
5763
5767
  BContextEnd: "BContextEnd",
5764
5768
  FrontendFromUrl: "Frontend/FromUrl",
5765
5769
  FrontendFromFolder: "Frontend/FromFolder",
5770
+ FrontendFromLocalTgz: "Frontend/FromLocalTgz",
5766
5771
  BObjectSpec: "BObjectSpec",
5767
5772
  Blob: "Blob",
5768
5773
  Null: "Null",
@@ -5777,7 +5782,7 @@ const ResourceTypeName = {
5777
5782
  SharedEnvelope: "SharedEnvelope"
5778
5783
  };
5779
5784
  //#endregion
5780
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5785
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/services/service_types.js
5781
5786
  const SERVICE_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9]*$/;
5782
5787
  const { service, isNodeService, isWasmService, isMainService, getServiceKind, getServiceModelMethods, getServiceUiMethods } = (() => {
5783
5788
  const typeMap = /* @__PURE__ */ new Map();
@@ -5816,7 +5821,7 @@ const { service, isNodeService, isWasmService, isMainService, getServiceKind, ge
5816
5821
  };
5817
5822
  })();
5818
5823
  //#endregion
5819
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5824
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/services/service_declarations.js
5820
5825
  const Services = {
5821
5826
  PFrameSpec: service()({
5822
5827
  type: "wasm",
@@ -5910,7 +5915,7 @@ function resolveRequiredServices(flags) {
5910
5915
  }
5911
5916
  Object.fromEntries(Object.keys(Services).map((key) => [`requires${key}`, true]));
5912
5917
  //#endregion
5913
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
5918
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/services/service_injectors.js
5914
5919
  function buildMethodMap(pick) {
5915
5920
  const result = {};
5916
5921
  for (const id of Object.values(Services)) result[id] = [...pick(id)];
@@ -5919,7 +5924,7 @@ function buildMethodMap(pick) {
5919
5924
  buildMethodMap(getServiceUiMethods);
5920
5925
  buildMethodMap(getServiceModelMethods);
5921
5926
  //#endregion
5922
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
5927
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/accessor_traversal.js
5923
5928
  /** Resource types that hold column collections — DFS stops here and collects. */
5924
5929
  const COLLECT_TYPES = [ResourceTypeName.PFrame];
5925
5930
  /** Resource types DFS descends through when looking for PFrames. */
@@ -6027,7 +6032,7 @@ function indexPoolBlock(block) {
6027
6032
  return result;
6028
6033
  }
6029
6034
  //#endregion
6030
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6035
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/column_registry.js
6031
6036
  /**
6032
6037
  * Id-index over a set of {@link ColumnEntriesProvider}s. Sole job:
6033
6038
  * {@link PObjectId} → {@link LeafEntry}. Generic over the accessor flavour, so
@@ -6064,7 +6069,7 @@ var ColumnRegistry = class {
6064
6069
  }
6065
6070
  };
6066
6071
  //#endregion
6067
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
6072
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/dedup.js
6068
6073
  /**
6069
6074
  * Two-track dedup over an item stream keyed by `ColumnUniversalId`:
6070
6075
  *
@@ -6105,7 +6110,7 @@ function dedupColumns(items, getId, getSpec) {
6105
6110
  return out;
6106
6111
  }
6107
6112
  //#endregion
6108
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6113
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/columns/providers.js
6109
6114
  /**
6110
6115
  * Generic entries provider over a single accessor root. Walks `<root>` once
6111
6116
  * from the supplied `rootPath`, builds an id → {@link LeafEntry} map and
@@ -6162,7 +6167,7 @@ var ResultPoolEntriesProvider = class {
6162
6167
  }
6163
6168
  };
6164
6169
  //#endregion
6165
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6170
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/template/template_ref_form.js
6166
6171
  /**
6167
6172
  * Whether `value` is a reference in the readable spelling.
6168
6173
  *
@@ -6231,7 +6236,7 @@ function expandTemplatePlRef(ref) {
6231
6236
  };
6232
6237
  }
6233
6238
  //#endregion
6234
- //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.51.0/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6239
+ //#region ../node_modules/.pnpm/@milaboratories+pl-model-common@1.53.0/node_modules/@milaboratories/pl-model-common/dist/template/template_relocate.js
6235
6240
  /**
6236
6241
  * Point every column identifier in a block's params at the blocks of the project being built.
6237
6242
  *
@@ -6291,7 +6296,7 @@ function relocateBlockIds(params, blockIds) {
6291
6296
  return walk(params);
6292
6297
  }
6293
6298
  //#endregion
6294
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_migrations.js
6299
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/block_migrations.js
6295
6300
  /** Create a DataVersioned wrapper with correct shape */
6296
6301
  function makeVersionedData(version, data) {
6297
6302
  return {
@@ -6869,7 +6874,7 @@ var DataModel = class DataModel {
6869
6874
  }
6870
6875
  };
6871
6876
  //#endregion
6872
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/internal.js
6877
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/internal.js
6873
6878
  /** Utility code helping to identify whether the code is running in actual UI environment */
6874
6879
  function isInUI() {
6875
6880
  return typeof globalThis.getPlatforma !== "undefined" || typeof globalThis.platforma !== "undefined";
@@ -6939,7 +6944,7 @@ function registerFutureAwait(handle, onResolve) {
6939
6944
  futureResolves.get(handle).push(onResolve);
6940
6945
  }
6941
6946
  //#endregion
6942
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
6947
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/block_storage_facade.js
6943
6948
  /**
6944
6949
  * All facade callback names as constants.
6945
6950
  * These are the source of truth - the interface is derived from these.
@@ -6977,7 +6982,7 @@ function registerFacadeCallbacks(callbacks) {
6977
6982
  for (const key of Object.values(BlockStorageFacadeCallbacks)) tryRegisterCallback(key, callbacks[key]);
6978
6983
  }
6979
6984
  //#endregion
6980
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/services/block_services.js
6985
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/services/block_services.js
6981
6986
  /**
6982
6987
  * Services required by all V3 blocks by default.
6983
6988
  * Edit this when a new service should be available to all blocks.
@@ -6993,7 +6998,7 @@ const BLOCK_SERVICE_FLAGS = {
6993
6998
  };
6994
6999
  resolveRequiredServices(BLOCK_SERVICE_FLAGS);
6995
7000
  //#endregion
6996
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/future.js
7001
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/future.js
6997
7002
  var FutureRef = class FutureRef {
6998
7003
  handle;
6999
7004
  postProcess;
@@ -7021,7 +7026,7 @@ var FutureRef = class FutureRef {
7021
7026
  }
7022
7027
  };
7023
7028
  //#endregion
7024
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/accessor.js
7029
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/accessor.js
7025
7030
  function ifDef(value, cb) {
7026
7031
  return value === void 0 ? void 0 : cb(value);
7027
7032
  }
@@ -7271,11 +7276,11 @@ var TreeNodeAccessor = class TreeNodeAccessor {
7271
7276
  }
7272
7277
  };
7273
7278
  //#endregion
7274
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/internal.js
7279
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/internal.js
7275
7280
  const MainAccessorName = "main";
7276
7281
  const StagingAccessorName = "staging";
7277
7282
  //#endregion
7278
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7283
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/util/axis_filtering.js
7279
7284
  function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7280
7285
  const sortedFilters = [...axisFilters].sort((a, b) => b[0] - a[0]);
7281
7286
  const { type } = dataInfoEntries;
@@ -7339,7 +7344,7 @@ function filterDataInfoEntries(dataInfoEntries, axisFilters) {
7339
7344
  }
7340
7345
  }
7341
7346
  //#endregion
7342
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7347
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/labels/linked_column_postfix.js
7343
7348
  /**
7344
7349
  * Structural postfix derivation for linked columns (phase 2 of `deriveDistinctLabels`).
7345
7350
  *
@@ -7522,7 +7527,7 @@ function derivePostfixes(entries, format = defaultLinkerFormatter) {
7522
7527
  });
7523
7528
  }
7524
7529
  //#endregion
7525
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7530
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/labels/derive_distinct_labels.js
7526
7531
  const DISTANCE_PENALTY = .001;
7527
7532
  const LABEL_TYPE = "__LABEL__";
7528
7533
  const LABEL_TYPE_FULL = "__LABEL__@1";
@@ -7564,6 +7569,7 @@ function deriveStems(values, options) {
7564
7569
  if (labelForced) forcedSet.add(LABEL_TYPE_FULL);
7565
7570
  const { mainTypes, secondaryTypes } = classifyTypes(stats, values.length);
7566
7571
  const build = (typeSet, force) => buildLabels(records, typeSet, forceTraceElements, separator, force);
7572
+ const finalize = (minimized, rendered) => repairBareLabels(rendered, minimized, records, stats, forceTraceElements, separator);
7567
7573
  if (mainTypes.length === 0) {
7568
7574
  if (secondaryTypes.length !== 0) throw new Error("Non-empty secondary types list while main types list is empty.");
7569
7575
  return build(/* @__PURE__ */ new Set([LABEL_TYPE_FULL]), true) ?? throwError("Failed to derive labels using native column labels");
@@ -7577,7 +7583,7 @@ function deriveStems(values, options) {
7577
7583
  const candidateResult = build(currentSet, false);
7578
7584
  if (candidateResult !== void 0 && countUniqueLabels(candidateResult) === values.length) {
7579
7585
  const minimized = minimizeTypeSet(currentSet, records, stats, forceTraceElements, forcedSet, separator);
7580
- return repairBareByPresence(build(minimized, false) ?? throwError("Failed to derive unique labels"), minimized, records, stats, forcedSet, forceTraceElements, separator);
7586
+ return finalize(minimized, build(minimized, false) ?? throwError("Failed to derive unique labels"));
7581
7587
  }
7582
7588
  additionalType++;
7583
7589
  if (additionalType >= mainTypes.length) {
@@ -7590,7 +7596,7 @@ function deriveStems(values, options) {
7590
7596
  ...mainTypes,
7591
7597
  ...secondaryTypes
7592
7598
  ]), records, stats, forceTraceElements, forcedSet, separator);
7593
- return repairBareByPresence(build(minimized, true) ?? throwError("Failed to derive unique labels"), minimized, records, stats, forcedSet, forceTraceElements, separator);
7599
+ return finalize(minimized, build(minimized, true) ?? throwError("Failed to derive unique labels"));
7594
7600
  }
7595
7601
  function extractEntryParts(entry) {
7596
7602
  if (!("spec" in entry && typeof entry.spec === "object")) return {
@@ -7755,62 +7761,202 @@ function minimizeTypeSet(typeSet, records, stats, forceTraceElements, forcedSet,
7755
7761
  }
7756
7762
  return result;
7757
7763
  }
7758
- const ABSENT_VALUE = "\0absent";
7759
- /** Whether `fullType`'s rendered value differs across the group (absence counts as a value). */
7760
- function typeDistinguishes(records, group, fullType) {
7761
- const values = /* @__PURE__ */ new Set();
7762
- for (const i of group) {
7763
- const ft = records[i].fullTrace.find((e) => e.fullType === fullType);
7764
- values.add(ft?.label ?? ABSENT_VALUE);
7765
- if (values.size > 1) return true;
7766
- }
7767
- return false;
7768
- }
7769
- /** The highest-importance trace type this row HAS (outside `typeSet`) that sets it apart from its
7770
- * group peers. `undefined` when the row carries nothing distinguishing of its own. */
7771
- function bestDistinguishingType(records, group, row, typeSet, forcedSet, forceTraceElements, stats) {
7772
- return records[row].fullTrace.reduce((best, ft) => {
7773
- if (typeSet.has(ft.fullType) || forcedSet.has(ft.fullType) || forceTraceElements?.has(ft.type)) return best;
7774
- if (!typeDistinguishes(records, group, ft.fullType)) return best;
7775
- const imp = stats.importances.get(ft.fullType) ?? 0;
7776
- return best === void 0 || imp > best.imp ? {
7777
- type: ft.fullType,
7778
- imp
7779
- } : best;
7780
- }, void 0)?.type;
7781
- }
7782
- /**
7783
- * Un-bare columns distinguished only "by absence". After minimization a column can end up with a
7784
- * bare trace zone (only the forced native label) while a peer sharing that same base renders extra
7785
- * tokens — the column reads as unique purely because it LACKS what the peer has. For each such bare
7786
- * column this re-renders JUST that column's label with the highest-importance trace type it actually
7787
- * carries that tells it apart from its peers, so every colliding column is distinguished by a token
7788
- * it HAS rather than by omission.
7789
- *
7790
- * Patches individual labels rather than the shared type set on purpose: the set is global, so adding
7791
- * a type there would also decorate unrelated columns in other groups that happen to carry it. Only
7792
- * bare columns' labels grow (a superset of their previous value), so uniqueness is preserved. Groups
7793
- * are keyed by the base = the label rendered from the forced types alone.
7794
- */
7795
- function repairBareByPresence(labels, minimized, records, stats, forcedSet, forceTraceElements, separator) {
7796
- const base = records.map((r) => renderRecordLabel(r, forcedSet, forceTraceElements, separator));
7797
- const isBare = records.map((r, i) => renderRecordLabel(r, minimized, forceTraceElements, separator) === base[i]);
7798
- const groups = records.reduce((acc, _, i) => acc.set(base[i] ?? "", [...acc.get(base[i] ?? "") ?? [], i]), /* @__PURE__ */ new Map());
7764
+ /**
7765
+ * Repairs labels told apart only by what they lack: in a group with the same shown base, a
7766
+ * member is bare when its shown parts are a strict subset of a peer's. The group is re-labelled
7767
+ * from parts all members carry, or bare members add a hidden part (group-wide when labels stay
7768
+ * unique), whichever keeps the more important distinction; labels stay unique across the list.
7769
+ */
7770
+ function repairBareLabels(labels, minimized, records, stats, forceTraceElements, separator) {
7771
+ const traces = records.map((r) => new Map(r.fullTrace.map((ft) => [ft.fullType, ft.label])));
7772
+ const isQualification = (t) => isSyntheticType(t.split("@")[0]);
7773
+ const depths = records.map((r) => {
7774
+ const steps = r.fullTrace.filter((ft) => ft.fullType !== LABEL_TYPE_FULL && !isQualification(ft.fullType));
7775
+ return new Map(steps.map((ft, idx) => [ft.fullType, steps.length - idx]));
7776
+ });
7777
+ const isForced = (t) => forceTraceElements?.has(t.split("@")[0]) === true;
7778
+ const isDistinctionType = (t) => t !== LABEL_TYPE_FULL && !isQualification(t);
7779
+ const importance = (t) => stats.importances.get(t) ?? 0;
7780
+ const byImportance = (a, b) => importance(b) - importance(a);
7781
+ const render = (i, types) => renderRecordLabel(records[i], types, forceTraceElements, separator);
7782
+ const partKey = (t, l) => `${t}\u0000${l}`;
7783
+ const labelShown = minimized.has(LABEL_TYPE_FULL);
7784
+ const baseTypes = new Set(labelShown ? [LABEL_TYPE_FULL] : []);
7785
+ const qualTypes = [...minimized].filter(isQualification);
7786
+ const groups = /* @__PURE__ */ new Map();
7787
+ records.forEach((_, i) => {
7788
+ const key = render(i, baseTypes) ?? "";
7789
+ const group = groups.get(key);
7790
+ if (group) group.push(i);
7791
+ else groups.set(key, [i]);
7792
+ });
7799
7793
  const patched = [...labels];
7800
- for (const group of groups.values()) {
7801
- if (!group.some((i) => !isBare[i])) continue;
7802
- for (const i of group) {
7803
- if (!isBare[i]) continue;
7804
- const chosen = bestDistinguishingType(records, group, i, minimized, forcedSet, forceTraceElements, stats);
7805
- if (chosen === void 0) continue;
7806
- const withToken = /* @__PURE__ */ new Set([...minimized, chosen]);
7807
- patched[i] = renderRecordLabel(records[i], withToken, forceTraceElements, separator) ?? patched[i];
7808
- }
7794
+ const counts = /* @__PURE__ */ new Map();
7795
+ const addCount = (l, d) => counts.set(l, (counts.get(l) ?? 0) + d);
7796
+ for (const l of patched) addCount(l, 1);
7797
+ const tryApply = (members, next) => {
7798
+ if (new Set(next).size !== members.length) return false;
7799
+ for (const i of members) addCount(patched[i], -1);
7800
+ const clashes = next.some((l) => (counts.get(l) ?? 0) > 0);
7801
+ members.forEach((i, k) => {
7802
+ if (!clashes) patched[i] = next[k];
7803
+ addCount(patched[i], 1);
7804
+ });
7805
+ return !clashes;
7806
+ };
7807
+ for (const [key, group] of groups) {
7808
+ if (group.length < 2) continue;
7809
+ const shown = group.map((i) => [...traces[i]].filter(([t]) => t !== LABEL_TYPE_FULL && (minimized.has(t) || isForced(t))));
7810
+ const partKeys = shown.map((parts) => parts.map(([t, l]) => partKey(t, l)));
7811
+ const sigIndex = /* @__PURE__ */ new Map();
7812
+ const setKeys = [];
7813
+ const setMembers = [];
7814
+ const sigOf = partKeys.map((keys, k) => {
7815
+ const sig = [...keys].sort().join("");
7816
+ let s = sigIndex.get(sig);
7817
+ if (s === void 0) {
7818
+ s = setKeys.length;
7819
+ sigIndex.set(sig, s);
7820
+ setKeys.push(keys);
7821
+ setMembers.push([]);
7822
+ }
7823
+ setMembers[s].push(k);
7824
+ return s;
7825
+ });
7826
+ const setSets = setKeys.map((keys) => new Set(keys));
7827
+ const postings = /* @__PURE__ */ new Map();
7828
+ setKeys.forEach((keys, s) => keys.forEach((p) => {
7829
+ const list = postings.get(p);
7830
+ if (list) list.push(s);
7831
+ else postings.set(p, [s]);
7832
+ }));
7833
+ const withParts = setKeys.map((_, s) => s).filter((s) => setKeys[s].length > 0);
7834
+ const supersetSets = setKeys.map((keys, s) => {
7835
+ if (keys.length === 0) return withParts;
7836
+ const rarest = keys.reduce((a, b) => postings.get(a).length <= postings.get(b).length ? a : b);
7837
+ return postings.get(rarest).filter((t) => t !== s && setSets[t].size > keys.length && keys.every((x) => setSets[t].has(x)));
7838
+ });
7839
+ const bare = group.map((_, k) => supersetSets[sigOf[k]].length > 0);
7840
+ if (!bare.some(Boolean)) continue;
7841
+ const typeCount = /* @__PURE__ */ new Map();
7842
+ for (const i of group) for (const t of traces[i].keys()) typeCount.set(t, (typeCount.get(t) ?? 0) + 1);
7843
+ const isUneven = (t) => (typeCount.get(t) ?? 0) > 0 && typeCount.get(t) < group.length;
7844
+ const unevenMax = Math.max(...[...minimized].filter((t) => isDistinctionType(t) && !isForced(t) && isUneven(t)).map(importance));
7845
+ let sharedLabels;
7846
+ let sharedMax = Number.NEGATIVE_INFINITY;
7847
+ if (labelShown && key !== "") {
7848
+ const shared = [...typeCount].filter(([t, n]) => n === group.length && isDistinctionType(t)).map(([t]) => t).sort(byImportance);
7849
+ const chosen = new Set(baseTypes);
7850
+ const distinctCount = (types) => new Set(group.map((i) => render(i, types) ?? "")).size;
7851
+ let count = distinctCount(chosen);
7852
+ for (const t of shared) {
7853
+ if (count === group.length) break;
7854
+ const next = distinctCount(/* @__PURE__ */ new Set([...chosen, t]));
7855
+ if (next > count) {
7856
+ if (chosen.size === baseTypes.size) sharedMax = importance(t);
7857
+ chosen.add(t);
7858
+ count = next;
7859
+ }
7860
+ }
7861
+ const withTags = /* @__PURE__ */ new Set([...chosen, ...qualTypes]);
7862
+ const complete = group.map((i) => render(i, withTags)).filter((l) => l !== void 0);
7863
+ if (count === group.length && complete.length === group.length && new Set(complete).size === group.length) sharedLabels = complete;
7864
+ }
7865
+ const applyBareFix = () => {
7866
+ const bareMembers = group.filter((_, k) => bare[k]);
7867
+ const oldBare = /* @__PURE__ */ new Map();
7868
+ for (const i of bareMembers) oldBare.set(patched[i], (oldBare.get(patched[i]) ?? 0) + 1);
7869
+ const isFree = (l) => (counts.get(l) ?? 0) - (oldBare.get(l) ?? 0) === 0;
7870
+ const shownTypes = (k) => [
7871
+ ...baseTypes,
7872
+ ...shown[k].map(([t]) => t),
7873
+ ...qualTypes
7874
+ ];
7875
+ const setLabels = /* @__PURE__ */ new Map();
7876
+ const labelsIn = (s) => {
7877
+ let byType = setLabels.get(s);
7878
+ if (byType) return byType;
7879
+ byType = /* @__PURE__ */ new Map();
7880
+ for (const m of setMembers[s]) for (const [t, l] of traces[group[m]]) {
7881
+ const entry = byType.get(t) ?? {
7882
+ labels: /* @__PURE__ */ new Set(),
7883
+ n: 0
7884
+ };
7885
+ entry.labels.add(l);
7886
+ entry.n++;
7887
+ byType.set(t, entry);
7888
+ }
7889
+ setLabels.set(s, byType);
7890
+ return byType;
7891
+ };
7892
+ const someDiffers = (s, u, mine) => {
7893
+ const entry = labelsIn(s).get(u);
7894
+ if (entry === void 0) return mine !== void 0;
7895
+ if (entry.n < setMembers[s].length) return true;
7896
+ return entry.labels.size > 1 || !entry.labels.has(mine ?? "");
7897
+ };
7898
+ const extraDepthsOf = /* @__PURE__ */ new Map();
7899
+ const extraDepths = (s) => {
7900
+ let depthsSet = extraDepthsOf.get(s);
7901
+ if (depthsSet) return depthsSet;
7902
+ depthsSet = new Set(supersetSets[s].flatMap((t) => {
7903
+ const rep = setMembers[t][0];
7904
+ return shown[rep].filter(([u, l]) => !isQualification(u) && !setSets[s].has(partKey(u, l))).map(([u]) => depths[group[rep]].get(u));
7905
+ }));
7906
+ extraDepthsOf.set(s, depthsSet);
7907
+ return depthsSet;
7908
+ };
7909
+ const picks = /* @__PURE__ */ new Map();
7910
+ group.forEach((i, k) => {
7911
+ if (!bare[k]) return;
7912
+ const peers = supersetSets[sigOf[k]];
7913
+ const kindDepths = extraDepths(sigOf[k]);
7914
+ const sameKind = (u) => kindDepths.has(depths[i].get(u)) ? 1 : 0;
7915
+ const candidates = [...traces[i].keys()].filter((u) => !minimized.has(u) && !isForced(u)).filter((u) => peers.some((t) => someDiffers(t, u, traces[i].get(u)))).sort((a, b) => sameKind(b) - sameKind(a) || byImportance(a, b));
7916
+ for (const u of candidates) {
7917
+ const label = render(i, /* @__PURE__ */ new Set([...shownTypes(k), u]));
7918
+ if (label !== void 0 && isFree(label)) {
7919
+ picks.set(i, {
7920
+ type: u,
7921
+ label
7922
+ });
7923
+ break;
7924
+ }
7925
+ }
7926
+ });
7927
+ if (picks.size === 0) return false;
7928
+ if (labelShown && key !== "") {
7929
+ const picked = [...new Set([...picks.values()].map((p) => p.type))];
7930
+ const full = group.map((i, k) => render(i, /* @__PURE__ */ new Set([...shownTypes(k), ...picked]))).filter((l) => l !== void 0);
7931
+ if (full.length === group.length && tryApply(group, full)) return true;
7932
+ }
7933
+ const proposed = new Map([...picks].map(([i, p]) => [i, p.label]));
7934
+ for (let changed = true; changed;) {
7935
+ changed = false;
7936
+ const firstOld = /* @__PURE__ */ new Map();
7937
+ for (const [i, l] of proposed) {
7938
+ const old = firstOld.get(l);
7939
+ if (old === void 0) firstOld.set(l, patched[i]);
7940
+ else if (old !== patched[i]) changed = proposed.delete(i);
7941
+ }
7942
+ const kept = new Set(bareMembers.filter((i) => !proposed.has(i)).map((i) => patched[i]));
7943
+ for (const [i, l] of proposed) if (kept.has(l)) changed = proposed.delete(i);
7944
+ }
7945
+ for (const i of bareMembers) addCount(patched[i], -1);
7946
+ for (const i of bareMembers) {
7947
+ patched[i] = proposed.get(i) ?? patched[i];
7948
+ addCount(patched[i], 1);
7949
+ }
7950
+ return proposed.size > 0;
7951
+ };
7952
+ if (sharedLabels && sharedMax >= unevenMax && tryApply(group, sharedLabels)) continue;
7953
+ if (applyBareFix()) continue;
7954
+ if (sharedLabels && sharedMax < unevenMax) tryApply(group, sharedLabels);
7809
7955
  }
7810
7956
  return patched;
7811
7957
  }
7812
7958
  //#endregion
7813
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/label.js
7959
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/util/label.js
7814
7960
  /** @deprecated Use deriveDistinctLabels */
7815
7961
  function deriveLabels(values, getSpec, options = {}) {
7816
7962
  return deriveDistinctLabels(values.map(getSpec), options).map((label, i) => ({
@@ -7819,7 +7965,7 @@ function deriveLabels(values, getSpec, options = {}) {
7819
7965
  }));
7820
7966
  }
7821
7967
  //#endregion
7822
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
7968
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/util/pcolumn_data.js
7823
7969
  const RT_RESOURCE_MAP = "PColumnData/ResourceMap";
7824
7970
  const RT_RESOURCE_MAP_PARTITIONED = "PColumnData/Partitioned/ResourceMap";
7825
7971
  const RT_JSON_PARTITIONED = "PColumnData/JsonPartitioned";
@@ -8117,7 +8263,7 @@ function allPColumnsReady(columns) {
8117
8263
  return columns.every(isPColumnReady);
8118
8264
  }
8119
8265
  //#endregion
8120
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
8266
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/util/column_collection.js
8121
8267
  function isPColumnValues(value) {
8122
8268
  if (!Array.isArray(value)) return false;
8123
8269
  if (value.length === 0) return true;
@@ -8395,7 +8541,7 @@ var PColumnCollection = class {
8395
8541
  }
8396
8542
  };
8397
8543
  //#endregion
8398
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8544
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/services/service_bridge.js
8399
8545
  /**
8400
8546
  * Builds a ServiceProxy from a ServiceDispatch.
8401
8547
  * Each service method call is forwarded to dispatch.callServiceMethod.
@@ -8404,7 +8550,7 @@ function createServiceProxy(dispatch) {
8404
8550
  return ((serviceId) => Object.freeze(Object.fromEntries(dispatch.getServiceMethods(serviceId).map((method) => [method, (...args) => dispatch.callServiceMethod(serviceId, method, ...args)]))));
8405
8551
  }
8406
8552
  //#endregion
8407
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/services/get_services.js
8553
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/services/get_services.js
8408
8554
  const cachedServices = /* @__PURE__ */ new WeakMap();
8409
8555
  function getService(name, deps) {
8410
8556
  const ctx = deps?.ctx ?? getCfgRenderCtx();
@@ -8418,7 +8564,7 @@ function getService(name, deps) {
8418
8564
  })();
8419
8565
  }
8420
8566
  //#endregion
8421
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8567
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/util/pframe_upgraders.js
8422
8568
  function patchInSetFilters(filters) {
8423
8569
  const inSetToOrEqual = (predicate) => {
8424
8570
  if (predicate.operator !== "InSet") return predicate;
@@ -8456,7 +8602,7 @@ function patchInSetFilters(filters) {
8456
8602
  return filters.map((filter) => mapFilter(filter, inSetToOrEqual));
8457
8603
  }
8458
8604
  //#endregion
8459
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/render/api.js
8605
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/render/api.js
8460
8606
  /**
8461
8607
  * Helper function to match domain objects
8462
8608
  * @param query Optional domain to match against
@@ -8905,27 +9051,27 @@ var PluginRenderCtx = class extends RenderCtxBase {
8905
9051
  }
8906
9052
  };
8907
9053
  //#endregion
8908
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/plugin_model.js
9054
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/plugin_model.js
8909
9055
  /** Internal plugin↔block handshake. `Symbol.for` (not `Symbol`) so it stays
8910
9056
  * identical across multiple `@platforma-sdk/model` copies in one process. */
8911
9057
  const CREATE_PLUGIN_MODEL = Symbol.for("@platforma-sdk/model:createPluginModel");
8912
9058
  //#endregion
8913
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/version.js
8914
- const PlatformaSDKVersion = "1.84.1";
9059
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/version.js
9060
+ const PlatformaSDKVersion = "1.85.2";
8915
9061
  //#endregion
8916
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/bconfig/types.js
9062
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/bconfig/types.js
8917
9063
  function isConfigLambda(cfgOrFh) {
8918
9064
  return cfgOrFh.__renderLambda === true;
8919
9065
  }
8920
9066
  //#endregion
8921
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
9067
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/bconfig/normalization.js
8922
9068
  function downgradeCfgOrLambda(data) {
8923
9069
  if (data === void 0) return void 0;
8924
9070
  if (isConfigLambda(data)) return data.handle;
8925
9071
  return data;
8926
9072
  }
8927
9073
  //#endregion
8928
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
9074
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/block_storage_callbacks.js
8929
9075
  /**
8930
9076
  * BlockStorage Callback Implementations - wired to facade callbacks in BlockModelV3.done().
8931
9077
  *
@@ -9279,7 +9425,7 @@ function deriveTemplateParamsFromStorage(storageJson, deriveTemplateParams) {
9279
9425
  }
9280
9426
  }
9281
9427
  //#endregion
9282
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/block_model.js
9428
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/block_model.js
9283
9429
  /**
9284
9430
  * Merges two feature flag objects with type-aware logic:
9285
9431
  * - `supports*` (boolean): OR — `true` if either side is `true`
@@ -9645,7 +9791,7 @@ var BlockModelV3 = class BlockModelV3 {
9645
9791
  }
9646
9792
  };
9647
9793
  //#endregion
9648
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9794
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/pframe_utils/axes.js
9649
9795
  /** Create id for column copy with added keys in axes domains */
9650
9796
  const colId = (id, domains, contextDomains) => {
9651
9797
  let wid = id.toString();
@@ -9751,7 +9897,7 @@ function getAdditionalColumnsForColumn(blockAxes, column) {
9751
9897
  })];
9752
9898
  }
9753
9899
  //#endregion
9754
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
9900
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/leaf_rebrand.js
9755
9901
  /**
9756
9902
  * Replace every column leaf whose id equals `fromId` with `toId`, leaving
9757
9903
  * other column refs (linkers, sub-anchors) intact. Wrapper recipes
@@ -10949,7 +11095,7 @@ var LRUCache = class LRUCache {
10949
11095
  }
10950
11096
  };
10951
11097
  //#endregion
10952
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
11098
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_providers/providers.js
10953
11099
  /**
10954
11100
  * Unified memoised factory dispatching to the right provider flavour by the
10955
11101
  * source shape:
@@ -11038,7 +11184,7 @@ function hashRawPool(rawPool) {
11038
11184
  return rawPool.map((b) => `${b.blockId}\x1f${b.prodCtx ?? ""}\x1f${b.stagingCtx ?? ""}\x1f${b.prodIncomplete ? 1 : 0}\x1f${b.stagingIncomplete ? 1 : 0}`).join("");
11039
11185
  }
11040
11186
  //#endregion
11041
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
11187
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_providers/index.js
11042
11188
  /**
11043
11189
  * Build the default set of ColumnsProviders for the ambient render ctx:
11044
11190
  * - `AccessorColumnsProvider` over `outputs` (if present)
@@ -11073,7 +11219,7 @@ function isColumnProvider(source) {
11073
11219
  return typeof p.getColumns === "function" && typeof p.isFinal === "function";
11074
11220
  }
11075
11221
  //#endregion
11076
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/data_column.js
11222
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/data_column.js
11077
11223
  /**
11078
11224
  * Thrown by leaf-recipe factories when the requested column is provably
11079
11225
  * absent in the active render ctx — i.e. every relevant accessor reports
@@ -11313,7 +11459,7 @@ function memoizeByEntry(fn) {
11313
11459
  };
11314
11460
  }
11315
11461
  //#endregion
11316
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
11462
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_overrided_recipe.js
11317
11463
  /**
11318
11464
  * Recipe wrapper that overlays {@link SpecOverrides} on top of any other
11319
11465
  * recipe. The id is `ColumnOverriddenKey { source: inner.id, specOverrides }`.
@@ -11451,7 +11597,7 @@ var DataColumnOverriddenRecipe = class extends ColumnOverriddenRecipe {
11451
11597
  }
11452
11598
  };
11453
11599
  //#endregion
11454
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
11600
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_filtered_recipe.js
11455
11601
  /**
11456
11602
  * Recipe wrapper that fixes the values of selected axes of an inner recipe
11457
11603
  * (axis slicing). The id is `FilteredPColumnId { source: inner.id,
@@ -11577,7 +11723,7 @@ function toAxisSelector(axis) {
11577
11723
  return selector;
11578
11724
  }
11579
11725
  //#endregion
11580
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
11726
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/index.js
11581
11727
  /**
11582
11728
  * Build a `ColumnRecipe` from a stringified id. Dispatches to the matching
11583
11729
  * concrete recipe variant based on the id's encoding and recurses on
@@ -11628,7 +11774,7 @@ function ColumnRecipeGetStatus(id, opts = {}) {
11628
11774
  }
11629
11775
  const ColumnRecipe = Object.assign(ColumnRecipeBuild, { getStatus: ColumnRecipeGetStatus });
11630
11776
  //#endregion
11631
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
11777
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column_recipes/column_discovered_recipe.js
11632
11778
  /**
11633
11779
  * Recipe for columns identified by a {@link ColumnDiscoveredKey}: a base
11634
11780
  * column + a `path` of linkers + qualifications.
@@ -11799,7 +11945,7 @@ function referencedUniIdsOf(key) {
11799
11945
  return /* @__PURE__ */ new Set([key.column, ...(key.path ?? []).map((item) => item.column)]);
11800
11946
  }
11801
11947
  //#endregion
11802
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/column.js
11948
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/column.js
11803
11949
  /**
11804
11950
  * Unified entry point — routes between the two top-level dispatchers:
11805
11951
  * - string id (`PObjectId` / `ColumnUniversalId`) → {@link ColumnRecipe}
@@ -11813,7 +11959,7 @@ function Column(source, opts) {
11813
11959
  return DataColumn(source, opts);
11814
11960
  }
11815
11961
  //#endregion
11816
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
11962
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/columns_collection.js
11817
11963
  /**
11818
11964
  * Build a {@link ColumnsCollection} from sandbox-side source descriptors.
11819
11965
  * Resolves the `columnsCollection` driver (either from `deps.driver` or via
@@ -11922,7 +12068,7 @@ function defaultCtxSources(ctx) {
11922
12068
  return [...currentBlockSources(ctx), { kind: "result_pool" }];
11923
12069
  }
11924
12070
  //#endregion
11925
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/columns/utils.js
12071
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/columns/utils.js
11926
12072
  /**
11927
12073
  * PObjectIds of every non-hit column referenced by `recipe.getQuery()`,
11928
12074
  * deduped in traversal order. The hit column is
@@ -12053,7 +12199,7 @@ function hasSingleDataColumn(recipe) {
12053
12199
  return recipe.getReferencedIds().length === 1;
12054
12200
  }
12055
12201
  //#endregion
12056
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
12202
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/pframe_utils/columns.js
12057
12203
  function getAllRelatedColumns(ctx, predicate) {
12058
12204
  const columns = new PColumnCollection();
12059
12205
  columns.addColumnProvider(ctx.resultPool);
@@ -12129,7 +12275,7 @@ function discoverIntegrableColumnIds(ctx, rootColumns) {
12129
12275
  }
12130
12276
  }
12131
12277
  //#endregion
12132
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
12278
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PFrameForGraphs.js
12133
12279
  function isHiddenFromGraphColumn(column) {
12134
12280
  return !!readAnnotationJson(column, Annotation.HideDataFromGraphs);
12135
12281
  }
@@ -12158,7 +12304,7 @@ function createPFrameForGraphs(ctx, blockColumns) {
12158
12304
  }));
12159
12305
  }
12160
12306
  //#endregion
12161
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/dataset_selection.js
12307
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/dataset_selection.js
12162
12308
  function isDatasetSelection(value) {
12163
12309
  return typeof value === "object" && value !== null && value.__isDatasetSelection === "v1" && "primary" in value;
12164
12310
  }
@@ -12174,7 +12320,7 @@ function createDatasetSelection(primary, enrichments) {
12174
12320
  };
12175
12321
  }
12176
12322
  //#endregion
12177
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/filter_discovery.js
12323
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/filter_discovery.js
12178
12324
  /**
12179
12325
  * Matches columns annotated `pl7.app/isSubset: "true"` whose axes ⊆ anchor axes.
12180
12326
  *
@@ -12226,7 +12372,7 @@ function buildRefMap(entries) {
12226
12372
  return new Map(entries.map((e) => [(0, import_canonicalize.default)(e.ref), e.ref]));
12227
12373
  }
12228
12374
  //#endregion
12229
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/enrichment_discovery.js
12375
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/enrichment_discovery.js
12230
12376
  /**
12231
12377
  * Linker-reached hits attached to the anchor primary. Drops zero-hop variants
12232
12378
  * (filters / the primary itself) and structural hits (subset, linker, label
@@ -12286,7 +12432,7 @@ function enrichmentVariantsToRefs(variants, labelOptions) {
12286
12432
  });
12287
12433
  }
12288
12434
  //#endregion
12289
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/build_dataset_options.js
12435
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDatasetSelector/build_dataset_options.js
12290
12436
  function toPredicate(opt) {
12291
12437
  if (opt === void 0) return () => true;
12292
12438
  return typeof opt === "function" ? opt : multiColumnSelectorsToPredicate(opt);
@@ -12300,7 +12446,7 @@ function toPredicate(opt) {
12300
12446
  function buildDatasetOptions(ctx, opts) {
12301
12447
  const primaryPredicate = toPredicate(opts?.primary);
12302
12448
  const filterPredicate = toPredicate(opts?.filter);
12303
- const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: true });
12449
+ const options = ctx.resultPool.getOptions(primaryPredicate, { refsWithEnrichments: opts?.requireEnrichments ?? true });
12304
12450
  if (options.length === 0) return [];
12305
12451
  const refMap = buildRefMap(ctx.resultPool.getSpecs().entries);
12306
12452
  const withEnrichments = opts?.withEnrichments ?? false;
@@ -12336,7 +12482,7 @@ function buildDatasetOptions(ctx, opts) {
12336
12482
  });
12337
12483
  }
12338
12484
  //#endregion
12339
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/filters/traverse.js
12485
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/filters/traverse.js
12340
12486
  /**
12341
12487
  * Recursively traverses a FilterSpec tree bottom-up, applying visitor callbacks.
12342
12488
  *
@@ -12375,7 +12521,7 @@ function collectFilterSpecColumns(filter) {
12375
12521
  });
12376
12522
  }
12377
12523
  //#endregion
12378
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
12524
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/filters/converters/filterToQuery.js
12379
12525
  /** Converts a QueryColumnId object into a SpecQueryExpression reference. */
12380
12526
  function resolveColumnRef(col) {
12381
12527
  return col.type === "axis" ? {
@@ -12713,7 +12859,7 @@ function isNumber(value) {
12713
12859
  return typeof value === "number" || value instanceof Number;
12714
12860
  }
12715
12861
  //#endregion
12716
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/filters/distill.js
12862
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/filters/distill.js
12717
12863
  /**
12718
12864
  * Strips non-FilterSpec metadata (whitelist approach) and removes
12719
12865
  * unfilled leaves (type is undefined or any required field is undefined).
@@ -12818,7 +12964,7 @@ const REQUIRED_KEYS_BY_TYPE = {
12818
12964
  greaterThanColumnOrEqual: ["column", "rhs"]
12819
12965
  };
12820
12966
  //#endregion
12821
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
12967
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/state-migration.js
12822
12968
  /** Upgrade PlDataTableStateV2 to the latest version */
12823
12969
  function upgradePlDataTableStateV2(state) {
12824
12970
  if (!state) return createPlDataTableStateV2();
@@ -13176,7 +13322,7 @@ function parseLegacyLeafColumn(s) {
13176
13322
  return parsed;
13177
13323
  }
13178
13324
  //#endregion
13179
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
13325
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/utils.js
13180
13326
  /** Adapt a {@link ColumnRecipe} to the plain {@link RuleColumn} shape. */
13181
13327
  function toRuleColumn(col) {
13182
13328
  return {
@@ -13274,7 +13420,7 @@ function deriveAllLabels(options) {
13274
13420
  })), deriveLabelsOptions).reduce((acc, label, index) => (acc[columns[index].id] = label, acc), {});
13275
13421
  }
13276
13422
  //#endregion
13277
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
13423
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPTableDefV3.js
13278
13424
  /**
13279
13425
  * Assemble a ptable def directly from recipes. Each secondary recipe is its own
13280
13426
  * outer-joined subtree: `getQuery()` encodes its linker chain, and its
@@ -13338,7 +13484,7 @@ function columnToJoinEntry(col, qualifications) {
13338
13484
  };
13339
13485
  }
13340
13486
  //#endregion
13341
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
13487
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/columnResolver.js
13342
13488
  function createColumnResolver(columns) {
13343
13489
  const axisIds = [];
13344
13490
  for (const c of columns) for (const ax of c.getSpec().axesSpec) axisIds.push(getAxisId(ax));
@@ -13360,7 +13506,7 @@ function createColumnResolver(columns) {
13360
13506
  };
13361
13507
  }
13362
13508
  //#endregion
13363
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
13509
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/discoverColumns.js
13364
13510
  /**
13365
13511
  * Discover columns from sources/anchors and split them into primary
13366
13512
  * (direct anchor hits — zero-hop, query is a bare column) and secondary
@@ -13406,7 +13552,7 @@ function discoverLabelColumns(ctx, primary) {
13406
13552
  }).getColumns();
13407
13553
  }
13408
13554
  //#endregion
13409
- //#region ../node_modules/.pnpm/@platforma-sdk+model@1.84.1/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
13555
+ //#region ../node_modules/.pnpm/@platforma-sdk+model@1.85.2/node_modules/@platforma-sdk/model/dist/components/PlDataTable/createPlDataTable/createPlDataTableV3.js
13410
13556
  function createPlDataTableV3(ctx, options) {
13411
13557
  const state = upgradePlDataTableStateV2(options.tableState);
13412
13558
  const primaryJoinType = options.primaryJoinType ?? "full";
@@ -13965,6 +14111,52 @@ function isOnAnchorAxes(spec, anchorSpec) {
13965
14111
  const anchorAxes = new Set(anchorSpec.axesSpec.map(canonicalizeAxisId));
13966
14112
  return spec.axesSpec.every((axis) => anchorAxes.has(canonicalizeAxisId(axis)));
13967
14113
  }
14114
+ /** Axis names that key a dataset's records. See {@link recordSource} for the producers. */
14115
+ const RECORD_AXIS_NAMES = /* @__PURE__ */ new Set([
14116
+ "pl7.app/vdj/clonotypeKey",
14117
+ "pl7.app/vdj/scClonotypeKey",
14118
+ "pl7.app/variantKey"
14119
+ ]);
14120
+ /** The anchor's record axis, found by name, not by position. */
14121
+ function findRecordAxis(anchorSpec) {
14122
+ return anchorSpec.axesSpec.find((axis) => RECORD_AXIS_NAMES.has(axis.name));
14123
+ }
14124
+ /**
14125
+ * True when the axis keys the records of a dataset other than the anchor's.
14126
+ *
14127
+ * The anchor's record axis domain is its dataset identity (run id, chain, key structure); a
14128
+ * record axis of the same dataset carries all of it, a narrower one (e.g. per chain) adds
14129
+ * keys. A record axis without that identity belongs to another dataset. An undomained
14130
+ * anchor record axis gives no identity to compare, so only that exact axis counts as own.
14131
+ * An anchor with no record axis has no identity at all, and nothing counts as foreign.
14132
+ */
14133
+ function isOtherDatasetRecordAxis(axis, anchorSpec) {
14134
+ if (!RECORD_AXIS_NAMES.has(axis.name)) return false;
14135
+ const anchorRecordAxis = findRecordAxis(anchorSpec);
14136
+ if (anchorRecordAxis === void 0) return false;
14137
+ const identity = Object.entries(anchorRecordAxis.domain ?? {});
14138
+ if (identity.length === 0) return canonicalizeAxisId(axis) !== canonicalizeAxisId(anchorRecordAxis);
14139
+ return !identity.every(([key, value]) => axis.domain?.[key] === value);
14140
+ }
14141
+ /**
14142
+ * True when the column, or a linker it was reached through, is keyed by another dataset's
14143
+ * records — e.g. a single-cell reference joined to the anchor by VDJ Integration.
14144
+ *
14145
+ * Links inside the anchor's own dataset (clusters, lineages) never cross a foreign record
14146
+ * axis and do not count.
14147
+ */
14148
+ function isFromAnotherDataset(spec, linkerSpecs, anchorSpec) {
14149
+ return [spec, ...linkerSpecs].some((s) => s.axesSpec.some((axis) => isOtherDatasetRecordAxis(axis, anchorSpec)));
14150
+ }
14151
+ /**
14152
+ * True when every axis of the column is one of the anchor's axes or an axis a linker on its
14153
+ * path maps the anchor's records to (a cluster, a lineage). Such a column resolves to one
14154
+ * value per anchor record; a column with an unlinked extra axis (e.g. a contrast) does not.
14155
+ */
14156
+ function isKeyedByAnchorRecords(spec, linkerSpecs, anchorSpec) {
14157
+ const reachable = new Set([anchorSpec, ...linkerSpecs].flatMap((s) => s.axesSpec.map(canonicalizeAxisId)));
14158
+ return spec.axesSpec.every((axis) => reachable.has(canonicalizeAxisId(axis)));
14159
+ }
13968
14160
  /** Traversal scope shared by every anchored discovery in the model: filter and ranking
13969
14161
  * options, defaults, the MSA frame and the results table. */
13970
14162
  const ANCHORED_DISCOVERY = {
@@ -13989,6 +14181,66 @@ function isRankableMatch(c, anchorSpec, rankedColumnIds) {
13989
14181
  if (rankedColumnIds.has(extractPObjectId(c.id))) return true;
13990
14182
  return !isPresenceOnlyColumn(c.getSpec(), anchorSpec);
13991
14183
  }
14184
+ const MAX_RANKING_WEIGHT = 1e3;
14185
+ /**
14186
+ * Whether a stored weight is one the score can use.
14187
+ */
14188
+ function rankingWeightError(weight) {
14189
+ if (!Number.isFinite(weight)) return "Not a number";
14190
+ if (weight <= 0) return `Above 0`;
14191
+ if (weight > 1e3) return `Max ${MAX_RANKING_WEIGHT}`;
14192
+ }
14193
+ function isUsableRankingWeight(weight) {
14194
+ return rankingWeightError(weight) === void 0;
14195
+ }
14196
+ /**
14197
+ * Fills in the weight of every ranking row that has none.
14198
+ *
14199
+ * Every row gets the same weight. A list arriving without weights was a priority order and stays
14200
+ * one — the block migrates into `priority` mode, where weights go unused — so they carry no
14201
+ * ordering of their own and start level for the balanced score.
14202
+ */
14203
+ function withRankingWeights(rows) {
14204
+ if (!Array.isArray(rows)) return [];
14205
+ return rows.map((row) => ({
14206
+ ...row,
14207
+ weight: row.weight ?? 1
14208
+ }));
14209
+ }
14210
+ /** Each weight as a fraction of all of them: `w / Σw`. Zero-sum lists read as equal. */
14211
+ function normalizeWeights(weights) {
14212
+ const total = weights.reduce((sum, w) => sum + w, 0);
14213
+ if (!(total > 0)) return weights.map(() => 1 / weights.length);
14214
+ return weights.map((w) => w / total);
14215
+ }
14216
+ /**
14217
+ * Which level a ranking metric acts on: cluster-level when its axes do not include the
14218
+ * anchor's record axis.
14219
+ */
14220
+ function rankingLevelOf(spec, anchorSpec) {
14221
+ const recordAxisName = anchorSpec.axesSpec[1]?.name;
14222
+ if (recordAxisName === void 0) return "clonotype";
14223
+ return spec.axesSpec.some((axis) => axis.name === recordAxisName) ? "clonotype" : "cluster";
14224
+ }
14225
+ /** What one record is called: Clonotype, Peptide, Variant, or Sequence when unplaceable. */
14226
+ function recordLabel(anchorSpec) {
14227
+ switch (recordSource(anchorSpec)) {
14228
+ case "peptide": return "Peptide";
14229
+ case "amplicon": return "Variant";
14230
+ case "vdj": return "Clonotype";
14231
+ default: return "Sequence";
14232
+ }
14233
+ }
14234
+ /**
14235
+ * What each level is called, for this dataset. Model-side because `PlDropdown` reads its
14236
+ * `group` off the option itself.
14237
+ */
14238
+ function rankingLevelLabels(anchorSpec) {
14239
+ return {
14240
+ cluster: "Cluster",
14241
+ clonotype: recordLabel(anchorSpec)
14242
+ };
14243
+ }
13992
14244
  /**
13993
14245
  * Collapses discovery results to one recipe per storage column, first hit wins.
13994
14246
  *
@@ -14032,33 +14284,80 @@ const IN_VIVO_MUTATION_COLUMNS = /* @__PURE__ */ new Set([
14032
14284
  "pl7.app/vdj/sequence/nAAMutationsCDR",
14033
14285
  "pl7.app/vdj/sequence/nAAMutationsFWR"
14034
14286
  ]);
14035
- const IN_VIVO_FILTER_SPEC_NAMES = /* @__PURE__ */ new Set([
14036
- "pl7.app/vdj/isProductive",
14037
- "pl7.app/developabilityRisk",
14038
- "pl7.app/vdj/developabilityRisk"
14039
- ]);
14040
- const IN_VIVO_RANKING_SPEC_NAMES = /* @__PURE__ */ new Set([
14041
- "pl7.app/vdj/repertoireScore",
14042
- "pl7.app/developabilityScore",
14043
- "pl7.app/vdj/developabilityScore"
14044
- ]);
14045
- const IN_VITRO_FILTER_SPEC_NAMES = /* @__PURE__ */ new Set([
14046
- "pl7.app/vdj/isProductive",
14047
- "pl7.app/developabilityRisk",
14048
- "pl7.app/vdj/developabilityRisk",
14049
- "pl7.app/enrichmentQuality",
14050
- "pl7.app/vdj/enrichmentQuality",
14051
- "pl7.app/vdj/bindingSpecificity",
14052
- "pl7.app/enrichment",
14053
- "pl7.app/vdj/enrichment"
14054
- ]);
14055
- const IN_VITRO_RANKING_SPEC_NAMES = /* @__PURE__ */ new Set([
14056
- "pl7.app/developabilityScore",
14057
- "pl7.app/vdj/developabilityScore",
14058
- "pl7.app/enrichment",
14059
- "pl7.app/vdj/enrichment",
14060
- "pl7.app/maxFrequency"
14061
- ]);
14287
+ const IN_VIVO_RANKING_PRIORITY = [{ names: ["pl7.app/vdj/repertoireScore"] }, { names: ["pl7.app/developabilityScore", "pl7.app/vdj/developabilityScore"] }];
14288
+ const IN_VIVO_FILTER_PRIORITY = [
14289
+ {
14290
+ names: ["pl7.app/vdj/sequence/fractionCDRMutations"],
14291
+ default: {
14292
+ type: "number_greaterThan",
14293
+ reference: .5
14294
+ }
14295
+ },
14296
+ {
14297
+ names: ["pl7.app/vdj/sequence/nMutations"],
14298
+ default: {
14299
+ type: "number_greaterThanOrEqualTo",
14300
+ reference: 3
14301
+ }
14302
+ },
14303
+ { names: ["pl7.app/developabilityRisk", "pl7.app/vdj/developabilityRisk"] },
14304
+ { names: ["pl7.app/vdj/isProductive"] }
14305
+ ];
14306
+ /** In Vitro preset rankings, shared with the peptide preset. Max Frequency precedes
14307
+ * Developability cost as the first per-element criterion: enrichment run on clusters gives a
14308
+ * cluster's members one shared Max Log2FC, so only a per-element value orders them. */
14309
+ const IN_VITRO_RANKING_PRIORITY = [
14310
+ {
14311
+ names: ["pl7.app/enrichment"],
14312
+ domain: { "pl7.app/enrichment/type": "max" }
14313
+ },
14314
+ { names: ["pl7.app/vdj/enrichment"] },
14315
+ { names: ["pl7.app/maxFrequency"] },
14316
+ { names: ["pl7.app/developabilityScore", "pl7.app/vdj/developabilityScore"] },
14317
+ {
14318
+ names: ["pl7.app/enrichment"],
14319
+ domain: { "pl7.app/enrichment/type": "comparison" }
14320
+ }
14321
+ ];
14322
+ const IN_VITRO_FILTER_PRIORITY = [
14323
+ { names: ["pl7.app/vdj/bindingSpecificity"] },
14324
+ { names: ["pl7.app/enrichmentQuality", "pl7.app/vdj/enrichmentQuality"] },
14325
+ {
14326
+ names: ["pl7.app/enrichment"],
14327
+ domain: { "pl7.app/enrichment/type": "max" }
14328
+ },
14329
+ { names: ["pl7.app/vdj/enrichment"] },
14330
+ {
14331
+ names: ["pl7.app/enrichment"],
14332
+ domain: { "pl7.app/enrichment/type": "comparison" }
14333
+ },
14334
+ { names: ["pl7.app/developabilityRisk", "pl7.app/vdj/developabilityRisk"] },
14335
+ { names: ["pl7.app/vdj/isProductive"] }
14336
+ ];
14337
+ function priorityIndex(entries) {
14338
+ const index = /* @__PURE__ */ new Map();
14339
+ entries.forEach((entry, rank) => entry.names.forEach((name) => {
14340
+ const claims = index.get(name);
14341
+ if (claims) claims.push({
14342
+ rank,
14343
+ domain: entry.domain
14344
+ });
14345
+ else index.set(name, [{
14346
+ rank,
14347
+ domain: entry.domain
14348
+ }]);
14349
+ }));
14350
+ return index;
14351
+ }
14352
+ const IN_VIVO_RANKING_INDEX = priorityIndex(IN_VIVO_RANKING_PRIORITY);
14353
+ const IN_VIVO_FILTER_INDEX = priorityIndex(IN_VIVO_FILTER_PRIORITY);
14354
+ const IN_VITRO_RANKING_INDEX = priorityIndex(IN_VITRO_RANKING_PRIORITY);
14355
+ const IN_VITRO_FILTER_INDEX = priorityIndex(IN_VITRO_FILTER_PRIORITY);
14356
+ /** The rank `spec` holds, or `undefined` when no entry claims it — so a list is both the
14357
+ * allowlist and the priority. First match wins: narrower entries come first. */
14358
+ function presetPriorityOf(spec, index) {
14359
+ return index.get(spec.name)?.find(({ domain }) => Object.entries(domain ?? {}).every(([key, value]) => spec.domain?.[key] === value))?.rank;
14360
+ }
14062
14361
  /**
14063
14362
  * Builds a host-driven {@link ColumnsCollection} over the upstream result pool
14064
14363
  * and computes column metadata (scores, defaults, presets).
@@ -14082,21 +14381,30 @@ function buildCollection(inputAnchor, inputFilter) {
14082
14381
  ...ANCHORED_DISCOVERY,
14083
14382
  exclude: discoveryExcludeSelectors(sampleAxisName)
14084
14383
  }).getColumns()).filter(isSelectableMatch);
14384
+ let scoresPending = false;
14085
14385
  const scores = allMatches.filter((c) => {
14086
14386
  const spec = c.getSpec();
14087
- return spec.annotations?.[Annotation.IsScore] === "true" && isOnAnchorAxes(spec, anchorSpec);
14387
+ if (spec.annotations?.[Annotation.IsScore] !== "true") return false;
14388
+ let linkerSpecs;
14389
+ try {
14390
+ linkerSpecs = collectLinkerColumns(c).map((l) => l.getSpec());
14391
+ } catch (e) {
14392
+ if (!(e instanceof ColumnAbsentError)) scoresPending = true;
14393
+ return false;
14394
+ }
14395
+ return isKeyedByAnchorRecords(spec, linkerSpecs, anchorSpec) && !isFromAnotherDataset(spec, linkerSpecs, anchorSpec);
14088
14396
  });
14089
14397
  const defaultCandidates = defaultsForSubset(scores, inputFilter && anchorInitializedId(inputFilter));
14090
- const defaultFilters = computeDefaultFilters(defaultCandidates, inputAnchor);
14398
+ const presets = computePresets(defaultCandidates, computeDefaultFilters(defaultCandidates, inputAnchor), inputAnchor, anchorSpec);
14091
14399
  return {
14092
14400
  collection,
14093
14401
  anchorSpec,
14094
14402
  sampleAxisName,
14403
+ scoresPending,
14095
14404
  meta: {
14096
14405
  allMatches,
14097
14406
  scores,
14098
- defaultFilters,
14099
- ...computePresets(defaultCandidates, defaultFilters, inputAnchor, anchorSpec)
14407
+ ...presets
14100
14408
  }
14101
14409
  };
14102
14410
  }
@@ -14192,77 +14500,62 @@ function hasGeneCalls(anchorSpec) {
14192
14500
  }
14193
14501
  function computePresets(scores, defaultFilters, anchorRef, anchorSpec) {
14194
14502
  const usesPeptidePreset = isPeptideOrAmplicon(anchorSpec);
14195
- const repertoireScore = scores.find((s) => s.getSpec().name === REPERTOIRE_SCORE_COLUMN_NAME);
14196
- const hasRepertoireScore = repertoireScore !== void 0;
14503
+ const hasRepertoireScore = scores.some((s) => s.getSpec().name === REPERTOIRE_SCORE_COLUMN_NAME);
14197
14504
  const isEnrichmentColumn = (name) => name.startsWith("pl7.app/enrichment") || name.startsWith("pl7.app/vdj/enrichment");
14198
14505
  const hasEnrichmentScores = scores.some((s) => isEnrichmentColumn(s.getSpec().name));
14199
14506
  const detectedPreset = usesPeptidePreset ? "peptide" : hasRepertoireScore ? "in-vivo" : hasEnrichmentScores ? "in-vitro" : void 0;
14200
- const defaultRankingOrder = scores.filter((s) => s.getSpec().valueType !== "String").filter((s) => !hasRepertoireScore || s.getSpec().name !== "pl7.app/vdj/repertoireScore").filter((s) => !hasRepertoireScore || !IN_VIVO_MUTATION_COLUMNS.has(s.getSpec().name)).map((s) => ({
14507
+ const defaultRankingOrder = scores.filter((s) => s.getSpec().valueType !== "String").filter((s) => !hasRepertoireScore || !IN_VIVO_MUTATION_COLUMNS.has(s.getSpec().name)).map((s) => ({
14201
14508
  id: `default-rank-${s.id}`,
14202
14509
  value: matchToColumnId(s, anchorRef),
14203
14510
  rankingOrder: s.getSpec().annotations?.[Annotation.Score.RankingOrder] ?? "decreasing",
14511
+ weight: 1,
14204
14512
  isExpanded: false
14205
14513
  }));
14206
- if (repertoireScore) defaultRankingOrder.unshift({
14207
- value: matchToColumnId(repertoireScore, anchorRef),
14208
- rankingOrder: repertoireScore.getSpec().annotations?.["pl7.app/score/rankingOrder"] ?? "decreasing"
14209
- });
14210
- const specNameByColumnId = new Map(scores.map((s) => [matchToColumnId(s, anchorRef).column, s.getSpec().name]));
14211
- const inVitroFilters = defaultFilters.filter((f) => {
14212
- const specName = specNameByColumnId.get(f.column.column);
14213
- return specName !== void 0 && IN_VITRO_FILTER_SPEC_NAMES.has(specName);
14214
- });
14514
+ const specByColumnId = new Map(scores.map((s) => [matchToColumnId(s, anchorRef).column, s.getSpec()]));
14515
+ /** The rows a preset's list claims, in that list's order. Within one rank, by label —
14516
+ * several per-comparison fold changes read in label order. */
14517
+ const ordered = (rows, columnIdOf, index) => rows.flatMap((row) => {
14518
+ const id = columnIdOf(row);
14519
+ const spec = specByColumnId.get(id);
14520
+ if (spec === void 0) return [];
14521
+ const rank = presetPriorityOf(spec, index);
14522
+ return rank === void 0 ? [] : [{
14523
+ row,
14524
+ rank,
14525
+ label: readAnnotation(spec, Annotation.Label) ?? "",
14526
+ id: id ?? ""
14527
+ }];
14528
+ }).sort((a, b) => a.rank - b.rank || a.label.localeCompare(b.label) || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)).map(({ row }) => row);
14529
+ const rankingOrderFor = (priority) => ordered(defaultRankingOrder, (r) => r.value?.column, priority);
14530
+ /** A preset's default filters. An entry carrying its own `default` overrides the column's
14531
+ * cutoff, and reaches columns that have none and so never entered `defaultFilters`. */
14532
+ const filtersFor = (priority, index) => {
14533
+ const supplied = priority.flatMap((entry, rank) => {
14534
+ const override = entry.default;
14535
+ if (override === void 0) return [];
14536
+ return scores.filter((score) => presetPriorityOf(score.getSpec(), index) === rank).map((score) => ({
14537
+ column: matchToColumnId(score, anchorRef),
14538
+ default: { ...override }
14539
+ }));
14540
+ });
14541
+ const overridden = new Set(supplied.map((f) => f.column.column));
14542
+ const fromCutoffs = defaultFilters.filter((f) => !overridden.has(f.column.column));
14543
+ return ordered([...supplied, ...fromCutoffs], (f) => f.column.column, index);
14544
+ };
14215
14545
  const inVitroDefaults = {
14216
- rankingOrder: defaultRankingOrder.filter((r) => {
14217
- const col = r.value?.column;
14218
- if (col === void 0) return false;
14219
- const specName = specNameByColumnId.get(col);
14220
- return specName !== void 0 && IN_VITRO_RANKING_SPEC_NAMES.has(specName);
14221
- }),
14222
- filters: inVitroFilters
14546
+ rankingOrder: rankingOrderFor(IN_VITRO_RANKING_INDEX),
14547
+ filters: filtersFor(IN_VITRO_FILTER_PRIORITY, IN_VITRO_FILTER_INDEX)
14223
14548
  };
14224
- const inVivoFilters = defaultFilters.filter((f) => {
14225
- const specName = specNameByColumnId.get(f.column.column);
14226
- return specName !== void 0 && IN_VIVO_FILTER_SPEC_NAMES.has(specName);
14227
- });
14228
- const fractionCDRMutationsCol = scores.find((s) => s.getSpec().name === "pl7.app/vdj/sequence/fractionCDRMutations");
14229
- if (fractionCDRMutationsCol) inVivoFilters.push({
14230
- column: matchToColumnId(fractionCDRMutationsCol, anchorRef),
14231
- default: {
14232
- type: "number_greaterThan",
14233
- reference: .5
14234
- }
14235
- });
14236
- const nMutationsCol = scores.find((s) => s.getSpec().name === "pl7.app/vdj/sequence/nMutations");
14237
- if (nMutationsCol) inVivoFilters.push({
14238
- column: matchToColumnId(nMutationsCol, anchorRef),
14239
- default: {
14240
- type: "number_greaterThanOrEqualTo",
14241
- reference: 3
14242
- }
14243
- });
14244
14549
  return {
14245
- defaultRankingOrder,
14246
14550
  hasRepertoireScore,
14247
14551
  hasEnrichmentScores,
14248
14552
  detectedPreset,
14249
14553
  inVivoDefaults: {
14250
- rankingOrder: defaultRankingOrder.filter((r) => {
14251
- const col = r.value?.column;
14252
- if (col === void 0) return false;
14253
- const specName = specNameByColumnId.get(col);
14254
- return specName !== void 0 && IN_VIVO_RANKING_SPEC_NAMES.has(specName);
14255
- }),
14256
- filters: inVivoFilters
14554
+ rankingOrder: rankingOrderFor(IN_VIVO_RANKING_INDEX),
14555
+ filters: filtersFor(IN_VIVO_FILTER_PRIORITY, IN_VIVO_FILTER_INDEX)
14257
14556
  },
14258
14557
  inVitroDefaults,
14259
- inPeptideDefaults: {
14260
- rankingOrder: scores.filter((s) => s.getSpec().valueType !== "String").map((s) => ({
14261
- value: matchToColumnId(s, anchorRef),
14262
- rankingOrder: s.getSpec().annotations?.[Annotation.Score.RankingOrder] ?? "decreasing"
14263
- })),
14264
- filters: defaultFilters
14265
- }
14558
+ inPeptideDefaults: inVitroDefaults
14266
14559
  };
14267
14560
  }
14268
14561
  function getDefaultBlockLabel(data) {
@@ -14291,11 +14584,30 @@ function initializedSlotParts(stored) {
14291
14584
  }
14292
14585
  //#endregion
14293
14586
  //#region ../model/dist/converters.js
14294
- function convertRankingOrderUI(rankingOrder) {
14295
- return rankingOrder.map((item) => ({
14587
+ /**
14588
+ * Narrows ranking rows to what the workflow reads.
14589
+ *
14590
+ * In `balanced` mode each row carries its weight as a fraction of all of them.
14591
+ */
14592
+ function convertRankingOrderUI(rankingOrder, mode) {
14593
+ if (mode !== "balanced") return rankingOrder.map((item) => ({
14296
14594
  value: item.value,
14297
14595
  rankingOrder: item.rankingOrder
14298
14596
  }));
14597
+ const weightNorms = normalizeWeights(rankingOrder.map((item) => item.weight ?? 1));
14598
+ return rankingOrder.map((item, i) => ({
14599
+ value: item.value,
14600
+ rankingOrder: item.rankingOrder,
14601
+ weightNorm: weightNorms[i]
14602
+ }));
14603
+ }
14604
+ /** As {@link convertRankingOrderUI}, keeping `weight` so a template round-trips it. */
14605
+ function convertRankingOrderUIForParams(rankingOrder) {
14606
+ return rankingOrder.map((item) => ({
14607
+ value: item.value,
14608
+ rankingOrder: item.rankingOrder,
14609
+ weight: item.weight
14610
+ }));
14299
14611
  }
14300
14612
  function convertFilterUI(filters) {
14301
14613
  return filters.map((item) => ({
@@ -14306,7 +14618,7 @@ function convertFilterUI(filters) {
14306
14618
  //#endregion
14307
14619
  //#region ../kind/dist/package.js
14308
14620
  var name = "@platforma-open/milaboratories.top-antibodies.kind";
14309
- var version = "1.1.0";
14621
+ var version = "1.2.0";
14310
14622
  //#endregion
14311
14623
  //#region ../node_modules/.pnpm/@platforma-sdk+block-kind@1.1.0/node_modules/@platforma-sdk/block-kind/dist/params.js
14312
14624
  /**
@@ -14450,7 +14762,7 @@ const isScopedColumnId = (v) => isPlainObject(v) && isPlRef(v.anchorRef) && isSt
14450
14762
  * produce the moment a predicate is added.
14451
14763
  */
14452
14764
  const isFilterPredicate = (v) => isPlainObject(v) && isString(v.type);
14453
- const isRankingOrder = (v) => isPlainObject(v) && optional(isScopedColumnId)(v.value) && oneOf("increasing", "decreasing")(v.rankingOrder);
14765
+ const isRankingOrder = (v) => isPlainObject(v) && optional(isScopedColumnId)(v.value) && oneOf("increasing", "decreasing")(v.rankingOrder) && optional(isNumber)(v.weight);
14454
14766
  const isFilter = (v) => isPlainObject(v) && optional(isScopedColumnId)(v.value) && optional(isFilterPredicate)(v.filter);
14455
14767
  /**
14456
14768
  * The defaults-init slot, by its envelope only.
@@ -14488,7 +14800,8 @@ const CONTRACT = {
14488
14800
  preset: check(oneOf("in-vivo", "in-vitro", "peptide"), "one of: in-vivo, in-vitro, peptide"),
14489
14801
  topClonotypes: check(isNumber, "a number"),
14490
14802
  kabatNumbering: check(isBoolean, "a boolean"),
14491
- rankingOrder: check(arrayOf(isRankingOrder), "an array of { value?, rankingOrder: 'increasing' | 'decreasing' } entries"),
14803
+ rankingMode: check(oneOf("priority", "balanced"), "one of: priority, balanced"),
14804
+ rankingOrder: check(arrayOf(isRankingOrder), "an array of { value?, rankingOrder: 'increasing' | 'decreasing', weight? } entries"),
14492
14805
  filters: check(arrayOf(isFilter), "an array of { value?, filter? } entries"),
14493
14806
  diversificationColumn: check(isPlRef, REF),
14494
14807
  filtersInitializedForAnchor: check(isInitializedForAnchor, INITIALIZED_SLOT),
@@ -14556,8 +14869,9 @@ const blockDataModel = new DataModelBuilder({ kind }).from("Ver_2026_02_25").upg
14556
14869
  input: inputAnchor !== void 0 ? createDatasetSelection(createPrimaryRef(inputAnchor)) : void 0
14557
14870
  };
14558
14871
  }).migrate("Ver_2026_07_28", (prev) => {
14559
- const rankingOrder = prev.rankingOrder.filter((rank) => rank.value?.column !== REMOVED_IN_VIVO_SCORE_COLUMN_ID);
14560
- if (rankingOrder.length === prev.rankingOrder.length) return { ...prev };
14872
+ const stored = Array.isArray(prev.rankingOrder) ? prev.rankingOrder : [];
14873
+ const rankingOrder = stored.filter((rank) => rank?.value?.column !== REMOVED_IN_VIVO_SCORE_COLUMN_ID);
14874
+ if (rankingOrder.length === stored.length) return { ...prev };
14561
14875
  return {
14562
14876
  ...prev,
14563
14877
  rankingOrder,
@@ -14571,13 +14885,18 @@ const blockDataModel = new DataModelBuilder({ kind }).from("Ver_2026_02_25").upg
14571
14885
  ...prev,
14572
14886
  filtersInitializedForAnchor: readInitializedForAnchor(prev.filtersInitializedForAnchor),
14573
14887
  rankingsInitializedForAnchor: readInitializedForAnchor(prev.rankingsInitializedForAnchor)
14888
+ })).migrate("Ver_2026_10_08", (prev) => ({
14889
+ ...prev,
14890
+ rankingOrder: withRankingWeights(prev.rankingOrder),
14891
+ rankingMode: "priority"
14574
14892
  })).init(({ params }) => ({
14575
14893
  defaultBlockLabel: params?.defaultBlockLabel ?? getDefaultBlockLabel({}),
14576
14894
  customBlockLabel: params?.customBlockLabel ?? "",
14577
14895
  input: params?.input,
14578
14896
  topClonotypes: params?.topClonotypes ?? 100,
14579
14897
  kabatNumbering: params?.kabatNumbering,
14580
- rankingOrder: params?.rankingOrder ?? [],
14898
+ rankingOrder: withRankingWeights(params?.rankingOrder ?? []),
14899
+ rankingMode: params?.rankingMode ?? "priority",
14581
14900
  filters: params?.filters ?? [],
14582
14901
  diversificationColumn: params?.diversificationColumn,
14583
14902
  tableState: createPlDataTableStateV2(),
@@ -14626,12 +14945,6 @@ var titles = {
14626
14945
  };
14627
14946
  //#endregion
14628
14947
  //#region ../model/dist/index.js
14629
- const CLUSTERING_TRACE_TYPES = [
14630
- "milaboratories.clonotype-clustering.clustering",
14631
- "milaboratories.3d-structure-clustering.clustering",
14632
- "milaboratories.embedding-clustering.clustering",
14633
- "milaboratories.lineage-trees.clustering"
14634
- ];
14635
14948
  /** Label column keyed by exactly one clonotype/variant key axis. Omitting
14636
14949
  * `partialAxesMatch` requires the exact axis set, i.e. `axesSpec.length === 1`. */
14637
14950
  const LABEL_KEY_AXIS_SELECTORS = [
@@ -14723,7 +15036,8 @@ const platforma$1 = BlockModelV3.create({
14723
15036
  preset: data.preset,
14724
15037
  topClonotypes: data.topClonotypes,
14725
15038
  kabatNumbering: data.kabatNumbering,
14726
- rankingOrder: convertRankingOrderUI(data.rankingOrder),
15039
+ rankingMode: data.rankingMode,
15040
+ rankingOrder: convertRankingOrderUIForParams(data.rankingOrder),
14727
15041
  filters: convertFilterUI(data.filters),
14728
15042
  diversificationColumn: data.diversificationColumn,
14729
15043
  filtersInitializedForAnchor: readInitializedForAnchor(data.filtersInitializedForAnchor),
@@ -14734,8 +15048,9 @@ const platforma$1 = BlockModelV3.create({
14734
15048
  const inputAnchor = getInputAnchorRef(data);
14735
15049
  if (inputAnchor === void 0) throw new Error("No input anchor");
14736
15050
  if (data.topClonotypes === void 0) throw new Error("No top clonotypes");
14737
- const rankingOrder = convertRankingOrderUI(data.rankingOrder);
15051
+ const rankingOrder = convertRankingOrderUI(data.rankingOrder, data.rankingMode);
14738
15052
  if (rankingOrder.some((order) => order.value === void 0)) throw new Error("Incomplete ranking order");
15053
+ if (data.rankingMode === "balanced" && !data.rankingOrder.every((row) => isUsableRankingWeight(row.weight))) throw new Error(`Ranking weights must be above 0 and at most ${MAX_RANKING_WEIGHT}`);
14739
15054
  const filters = convertFilterUI(data.filters);
14740
15055
  if (filters.some((filter) => filter.value === void 0)) throw new Error("Incomplete filters");
14741
15056
  return {
@@ -14744,6 +15059,7 @@ const platforma$1 = BlockModelV3.create({
14744
15059
  inputAnchor,
14745
15060
  inputFilter: getInputFilterRef(data),
14746
15061
  topClonotypes: data.topClonotypes,
15062
+ rankingMode: data.rankingMode,
14747
15063
  rankingOrder,
14748
15064
  filters,
14749
15065
  kabatNumbering: data.kabatNumbering,
@@ -14777,7 +15093,15 @@ const platforma$1 = BlockModelV3.create({
14777
15093
  });
14778
15094
  }).output("inputAnchorSpec", (ctx) => {
14779
15095
  return getSpecByRef(getInputAnchorRef(ctx.data));
14780
- }, { retentive: true }).output("isPeptide", (ctx) => {
15096
+ }).output("inputStatus", (ctx) => {
15097
+ const inputAnchor = getInputAnchorRef(ctx.data);
15098
+ const inputKey = inputKeyOf(inputAnchor, getInputFilterRef(ctx.data));
15099
+ if (inputKey === void 0) return void 0;
15100
+ return {
15101
+ inputKey,
15102
+ ready: getSpecByRef(inputAnchor) !== void 0
15103
+ };
15104
+ }).output("isPeptide", (ctx) => {
14781
15105
  const keyAxis = getSpecByRef(getInputAnchorRef(ctx.data))?.axesSpec[1];
14782
15106
  if (keyAxis?.name !== "pl7.app/variantKey") return false;
14783
15107
  const domain = keyAxis.domain ?? {};
@@ -14787,15 +15111,15 @@ const platforma$1 = BlockModelV3.create({
14787
15111
  if (domain["pl7.app/repertoire/extractionRunId"] !== void 0) return false;
14788
15112
  if (domain["pl7.app/vdj/clonotypingRunId"] !== void 0) return false;
14789
15113
  return true;
14790
- }, { retentive: true }).output("modality", (ctx) => {
15114
+ }).output("modality", (ctx) => {
14791
15115
  const spec = getSpecByRef(getInputAnchorRef(ctx.data));
14792
15116
  if (!spec) return void 0;
14793
15117
  return isPeptideOrAmplicon(spec) ? "peptide" : "antibody_tcr";
14794
- }, { retentive: true }).output("filterConfig", (ctx) => {
15118
+ }).output("filterConfig", (ctx) => {
14795
15119
  const inputAnchor = getInputAnchorRef(ctx.data);
14796
15120
  const inputFilter = getInputFilterRef(ctx.data);
14797
15121
  const result = buildCollection(inputAnchor, inputFilter);
14798
- if (!result) return void 0;
15122
+ if (!result || result.scoresPending) return void 0;
14799
15123
  const datasetFilterId = inputFilter && anchorInitializedId(inputFilter);
14800
15124
  const isDatasetFilter = (c) => datasetFilterId !== void 0 && extractPObjectId(c.id) === datasetFilterId;
14801
15125
  const filterableMatches = result.meta.allMatches.filter((c) => !isDatasetFilter(c));
@@ -14814,7 +15138,6 @@ const platforma$1 = BlockModelV3.create({
14814
15138
  };
14815
15139
  }),
14816
15140
  inputKey: inputKeyOf(inputAnchor, inputFilter),
14817
- defaults: result.meta.defaultFilters,
14818
15141
  inVivoDefaults: result.meta.inVivoDefaults.filters,
14819
15142
  inVitroDefaults: result.meta.inVitroDefaults.filters,
14820
15143
  inPeptideDefaults: result.meta.inPeptideDefaults.filters
@@ -14823,17 +15146,23 @@ const platforma$1 = BlockModelV3.create({
14823
15146
  const inputAnchor = getInputAnchorRef(ctx.data);
14824
15147
  const inputFilter = getInputFilterRef(ctx.data);
14825
15148
  const result = buildCollection(inputAnchor, inputFilter);
14826
- if (!result) return void 0;
15149
+ if (!result || result.scoresPending) return void 0;
14827
15150
  const rankedColumnIds = new Set(ctx.data.rankingOrder.flatMap((r) => r.value ? [r.value.column] : []));
14828
15151
  const rankableMatches = result.meta.allMatches.filter((c) => c.getSpec().valueType !== "String").filter((c) => isRankableMatch(c, result.anchorSpec, rankedColumnIds));
14829
15152
  const labels = deriveDistinctLabels(rankableMatches.map((c) => c.getSpec()), { includeNativeLabel: true });
15153
+ const levelLabels = rankingLevelLabels(result.anchorSpec);
15154
+ const levelGroups = {
15155
+ cluster: `${levelLabels.cluster} metrics`,
15156
+ clonotype: `${levelLabels.clonotype} metrics`
15157
+ };
14830
15158
  return {
14831
15159
  options: rankableMatches.map((c, i) => ({
14832
15160
  label: labels[i],
14833
- value: matchToColumnId(c, inputAnchor)
15161
+ value: matchToColumnId(c, inputAnchor),
15162
+ group: levelGroups[rankingLevelOf(c.getSpec(), result.anchorSpec)]
14834
15163
  })),
15164
+ levelLabels,
14835
15165
  inputKey: inputKeyOf(inputAnchor, inputFilter),
14836
- defaults: result.meta.defaultRankingOrder,
14837
15166
  inVivoDefaults: result.meta.inVivoDefaults.rankingOrder,
14838
15167
  inVitroDefaults: result.meta.inVitroDefaults.rankingOrder,
14839
15168
  inPeptideDefaults: result.meta.inPeptideDefaults.rankingOrder
@@ -15039,18 +15368,15 @@ const platforma$1 = BlockModelV3.create({
15039
15368
  const linkers = ctx.resultPool.getOptions([{
15040
15369
  axes: axesToMatch,
15041
15370
  annotations: { [Annotation.IsLinkerColumn]: "true" }
15042
- }], { label: { forceTraceElements: CLUSTERING_TRACE_TYPES } });
15371
+ }]);
15043
15372
  for (const link of linkers) {
15044
15373
  const linkerSpec = getSpecByRef(link.ref);
15045
15374
  if (!linkerSpec) continue;
15046
15375
  const clusterAxis = linkerSpec.axesSpec.find((axis) => isClusterIdAxisName(axis.name));
15047
15376
  if (!clusterAxis) continue;
15048
15377
  if (datasetClusteringId !== void 0 && clusterAxis.domain?.["pl7.app/clustering/blockId"] === datasetClusteringId) continue;
15049
- let label = "Cluster";
15050
- try {
15051
- const clusteringElement = JSON.parse(linkerSpec.annotations?.[Annotation.Trace] ?? "[]").find((t) => CLUSTERING_TRACE_TYPES.includes(t.type ?? ""));
15052
- if (clusteringElement?.label) label = clusteringElement.label;
15053
- } catch {}
15378
+ const trace = readAnnotationJson(linkerSpec, Annotation.Trace);
15379
+ let label = (Array.isArray(trace) ? trace.at(-1)?.label : void 0) || "Cluster";
15054
15380
  const clusterSubset = inputSubsetOf(clusterAxis.domain);
15055
15381
  if (clusterSubset !== void 0) {
15056
15382
  const subsetRef = parseJsonSafely(clusterSubset);