@toclocoinc/lattice-grid 1.9.0 → 1.10.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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.9.0 — core + DOM renderer
2
+ * Lattice Grid 1.10.0 — core + DOM renderer
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -909,7 +909,14 @@ STDEV:(a)=>spread(numbers(a),true),
909
909
  STDEVP:(a)=>spread(numbers(a),false),
910
910
  VAR:(a)=>{const sd=spread(numbers(a),true);return sd*sd;},
911
911
  VARP:(a)=>{const sd=spread(numbers(a),false);return sd*sd;},
912
- COUNTDISTINCT:(a)=>new Set(a.filter((v)=>v!==null&&v!==undefined&&v!=='')).size,
912
+ COUNTDISTINCT:(a)=>{
913
+ const seen=new Set();
914
+ for(const arg of a){
915
+ const values=Array.isArray(arg)?arg:[arg];
916
+ for(const v of values)if(v!==null&&v!==undefined&&v!=='')seen.add(v);
917
+ }
918
+ return seen.size;
919
+ },
913
920
  IQR:(a)=>{
914
921
  const values=numbers(a);
915
922
  return percentileOf(values,0.75)-percentileOf(values,0.25);
@@ -6723,6 +6730,7 @@ const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6723
6730
  return key?api.running(source,spec.kind||'total',key):null;
6724
6731
  },
6725
6732
  };
6733
+ if(def.sort===undefined)m.sort={...(m.sort||{}),enabled:false};
6726
6734
  }
6727
6735
  const field=def.field??(isFunction(m.value&&m.value.compute)?null:(def.id??null));
6728
6736
  const computed=isFunction(m.value&&m.value.compute);
@@ -12943,14 +12951,22 @@ return this.#keyIndex.get(key);
12943
12951
  #changedColumns(previous,next){
12944
12952
  const changed=[];
12945
12953
  for(const colId of this.#queryColumns()){
12946
- const column=this.#column(colId);
12947
- if(!column)continue;
12948
- const before=isFunction(column.getValue)?column.getValue(previous):undefined;
12949
- const after=isFunction(column.getValue)?column.getValue(next):undefined;
12950
- if(!Object.is(before,after))changed.push(colId);
12954
+ if(this.#column(colId)&&this.#moved(colId,previous,next,new Set()))changed.push(colId);
12951
12955
  }
12952
12956
  return changed;
12953
12957
  }
12958
+ #moved(colId,previous,next,seen){
12959
+ if(seen.has(colId))return false;
12960
+ seen.add(colId);
12961
+ const column=this.#column(colId);
12962
+ if(!column)return false;
12963
+ const deps=column.value&&column.value.deps;
12964
+ if(Array.isArray(deps)&&deps.length){
12965
+ return deps.some((dep)=>this.#moved(String(dep),previous,next,seen));
12966
+ }
12967
+ if(!isFunction(column.getValue))return false;
12968
+ return!Object.is(column.getValue(previous),column.getValue(next));
12969
+ }
12954
12970
  #queryColumns(){
12955
12971
  const ids=new Set();
12956
12972
  for(const entry of this.#state('sort',[]))ids.add(entry.col);
@@ -13099,7 +13115,16 @@ handleFor(colId){
13099
13115
  return this.#handles.handle(colId);
13100
13116
  }
13101
13117
  #runSort(filtered){
13102
- const entries=this.#state('sort',[]);
13118
+ const entries=this.#state('sort',[]).filter((entry)=>{
13119
+ const column=this.#column(entry.col);
13120
+ if(!column||!column.running)return true;
13121
+ warnOnce(
13122
+ `source.sort.running.${entry.col}`,
13123
+ `sort ignores "${entry.col}": a running total is a function of the sort order, `
13124
+ +'so it cannot also decide it. Sort by the column it runs over instead.',
13125
+ );
13126
+ return false;
13127
+ });
13103
13128
  if(!entries.length)return filtered;
13104
13129
  const locale=(this.#ctx.config||{}).locale;
13105
13130
  if(entries.length===1){
@@ -15022,6 +15047,354 @@ if(isFunction(emit))emit(type,payload);
15022
15047
  }
15023
15048
  }
15024
15049
  });
15050
+ __def("packages/core/src/source/derive.js",function(__exports,__req){
15051
+ 'use strict';
15052
+ Object.defineProperty(__exports,"FOLLOW_MODES",{enumerable:true,get:function(){return FOLLOW_MODES;}});
15053
+ Object.defineProperty(__exports,"BUCKETS",{enumerable:true,get:function(){return BUCKETS;}});
15054
+ Object.defineProperty(__exports,"DERIVED_ROW_KEY",{enumerable:true,get:function(){return DERIVED_ROW_KEY;}});
15055
+ Object.defineProperty(__exports,"readPath",{enumerable:true,get:function(){return readPath;}});
15056
+ Object.defineProperty(__exports,"unnest",{enumerable:true,get:function(){return unnest;}});
15057
+ Object.defineProperty(__exports,"bucketOf",{enumerable:true,get:function(){return bucketOf;}});
15058
+ Object.defineProperty(__exports,"reduceValues",{enumerable:true,get:function(){return reduceValues;}});
15059
+ Object.defineProperty(__exports,"applyLimit",{enumerable:true,get:function(){return applyLimit;}});
15060
+ Object.defineProperty(__exports,"applyCumulative",{enumerable:true,get:function(){return applyCumulative;}});
15061
+ Object.defineProperty(__exports,"derive",{enumerable:true,get:function(){return derive;}});
15062
+ const __m0=__req("packages/core/src/internal/util.js");
15063
+ const isFunction=__m0["isFunction"];
15064
+ const isObject=__m0["isObject"];
15065
+ const __m1=__req("packages/core/src/compute/total.js");
15066
+ const TOTAL_FNS=__m1["TOTAL_FNS"];
15067
+ const FOLLOW_MODES=Object.freeze(['filtered','all','selected','grouped']);
15068
+ const BUCKETS=Object.freeze(['day','week','month','quarter','year']);
15069
+ const DERIVED_ROW_KEY='__key';
15070
+ function readPath(obj,path){
15071
+ if(!isObject(obj)||typeof path!=='string')return undefined;
15072
+ if(!path.includes('.'))return(obj)[path];
15073
+ let cursor=(obj);
15074
+ for(const part of path.split('.')){
15075
+ if(!isObject(cursor))return undefined;
15076
+ cursor=(cursor)[part];
15077
+ }
15078
+ return cursor;
15079
+ }
15080
+ function unnest(rows,path){
15081
+ const out=[];
15082
+ for(const row of rows){
15083
+ const list=readPath(row,path);
15084
+ if(!Array.isArray(list)||!list.length)continue;
15085
+ for(const item of list)out.push({...((row)),[path]:item});
15086
+ }
15087
+ return out;
15088
+ }
15089
+ function bucketOf(value,by){
15090
+ const at=value instanceof Date?value:new Date((value));
15091
+ const time=at.getTime();
15092
+ if(!Number.isFinite(time))return null;
15093
+ const y=at.getUTCFullYear();
15094
+ const m=at.getUTCMonth();
15095
+ const d=at.getUTCDate();
15096
+ const iso=(date)=>date.toISOString().slice(0,10);
15097
+ switch(by){
15098
+ case'year':return iso(new Date(Date.UTC(y,0,1)));
15099
+ case'quarter':return iso(new Date(Date.UTC(y,Math.floor(m/3)*3,1)));
15100
+ case'month':return iso(new Date(Date.UTC(y,m,1)));
15101
+ case'week':{
15102
+ const day=(at.getUTCDay()+6)%7;
15103
+ return iso(new Date(Date.UTC(y,m,d-day)));
15104
+ }
15105
+ default:return iso(new Date(Date.UTC(y,m,d)));
15106
+ }
15107
+ }
15108
+ function groupKeyOf(row,by,bucket){
15109
+ const values=by.map((path)=>(
15110
+ bucket&&bucket.of===path?bucketOf(readPath(row,path),bucket.by):readPath(row,path)
15111
+ ));
15112
+ return{key:values.map((v)=>(v===undefined||v===null?'\u0000':String(v))).join('\u001f'),values};
15113
+ }
15114
+ function reduceValues(values,fn){
15115
+ const kernel=TOTAL_FNS[fn];
15116
+ if(!kernel)return null;
15117
+ return kernel({get:(i)=>values[i]},ROW_INDICES(values.length));
15118
+ }
15119
+ function reduceGroup(rows,select){
15120
+ const out={};
15121
+ const indices=ROW_INDICES(rows.length);
15122
+ for(const[id,spec]of Object.entries(select)){
15123
+ const fn=spec.fn||'count';
15124
+ const kernel=TOTAL_FNS[fn];
15125
+ if(!kernel){out[id]=null;continue;}
15126
+ const values=spec.of?rows.map((row)=>readPath(row,spec.of)):[];
15127
+ out[id]=kernel({get:(i)=>values[i]},indices);
15128
+ }
15129
+ return out;
15130
+ }
15131
+ const ROW_INDICES=(()=>{
15132
+ const cache=new Map();
15133
+ return(n)=>{
15134
+ let hit=cache.get(n);
15135
+ if(!hit){
15136
+ hit=new Uint32Array(n);
15137
+ for(let i=0;i<n;i++)hit[i]=i;
15138
+ if(cache.size<512)cache.set(n,hit);
15139
+ }
15140
+ return hit;
15141
+ };
15142
+ })();
15143
+ function applyLimit(rows,limit,per){
15144
+ if(!Number.isFinite(limit)||limit<=0)return rows;
15145
+ if(!per)return rows.slice(0,limit);
15146
+ const seen=new Map();
15147
+ const out=[];
15148
+ for(const row of rows){
15149
+ const key=String(readPath(row,per));
15150
+ const taken=seen.get(key)||0;
15151
+ if(taken>=limit)continue;
15152
+ seen.set(key,taken+1);
15153
+ out.push(row);
15154
+ }
15155
+ return out;
15156
+ }
15157
+ function applyCumulative(rows,spec){
15158
+ const total=rows.reduce((sum,row)=>sum+(Number(readPath(row,spec.of))||0),0);
15159
+ if(!total)return rows;
15160
+ const cutoff=total*spec.upTo;
15161
+ let running=0;
15162
+ const out=[];
15163
+ for(const row of rows){
15164
+ out.push(row);
15165
+ running+=Number(readPath(row,spec.of))||0;
15166
+ if(running>=cutoff)break;
15167
+ }
15168
+ return out;
15169
+ }
15170
+ function sortRows(rows,spec){
15171
+ if(!Array.isArray(spec)||!spec.length)return rows;
15172
+ return[...rows].sort((a,b)=>{
15173
+ for(const entry of spec){
15174
+ const av=readPath(a,entry.col);
15175
+ const bv=readPath(b,entry.col);
15176
+ if(av===bv)continue;
15177
+ if(av===null||av===undefined)return 1;
15178
+ if(bv===null||bv===undefined)return-1;
15179
+ const less=typeof av==='number'&&typeof bv==='number'
15180
+ ?av<bv
15181
+ :String(av)<String(bv);
15182
+ return(less?-1:1)*(entry.dir==='desc'?-1:1);
15183
+ }
15184
+ return 0;
15185
+ });
15186
+ }
15187
+ function derive(rows,spec){
15188
+ let working=Array.isArray(rows)?rows:[];
15189
+ if(spec.unnest)working=unnest(working,spec.unnest);
15190
+ if(isFunction(spec.where))working=working.filter((row)=>!!spec.where(row));
15191
+ const by=spec.groupBy
15192
+ ?(Array.isArray(spec.groupBy)?spec.groupBy:[spec.groupBy])
15193
+ :null;
15194
+ const bucket=isObject(spec.bucket)?spec.bucket:null;
15195
+ let out;
15196
+ if(!by){
15197
+ out=working.map((row,i)=>({
15198
+ ...((row)),
15199
+ [DERIVED_ROW_KEY]:String(readPath(row,spec.rowKey||'id')??i),
15200
+ }));
15201
+ }else{
15202
+ const groups=new Map();
15203
+ for(const row of working){
15204
+ const{key,values}=groupKeyOf(row,by,bucket);
15205
+ let bucketed=groups.get(key);
15206
+ if(!bucketed){bucketed={values,rows:[]};groups.set(key,bucketed);}
15207
+ bucketed.rows.push(row);
15208
+ }
15209
+ out=[...groups.entries()].map(([key,group])=>{
15210
+ const row={[DERIVED_ROW_KEY]:key};
15211
+ by.forEach((path,i)=>{row[path.includes('.')?path.split('.').pop():path]=group.values[i];});
15212
+ Object.assign(row,reduceGroup(group.rows,spec.select||{}));
15213
+ return row;
15214
+ });
15215
+ }
15216
+ out=sortRows(out,spec.sort);
15217
+ if(isObject(spec.cumulative))out=applyCumulative(out,spec.cumulative);
15218
+ return applyLimit(out,spec.limit,spec.limitPer||null);
15219
+ }
15220
+ });
15221
+ __def("packages/core/src/source/derived.js",function(__exports,__req){
15222
+ 'use strict';
15223
+ Object.defineProperty(__exports,"IDLE_REFRESH_MS",{enumerable:true,get:function(){return IDLE_REFRESH_MS;}});
15224
+ Object.defineProperty(__exports,"PROFILE_FIELDS",{enumerable:true,get:function(){return PROFILE_FIELDS;}});
15225
+ Object.defineProperty(__exports,"DerivedSource",{enumerable:true,get:function(){return DerivedSource;}});
15226
+ Object.defineProperty(__exports,"createDerivedSource",{enumerable:true,get:function(){return createDerivedSource;}});
15227
+ const __m0=__req("packages/core/src/internal/util.js");
15228
+ const isFunction=__m0["isFunction"];
15229
+ const isObject=__m0["isObject"];
15230
+ const warnOnce=__m0["warnOnce"];
15231
+ const __m1=__req("packages/core/src/source/memory.js");
15232
+ const MemorySource=__m1["MemorySource"];
15233
+ const __m2=__req("packages/core/src/source/derive.js");
15234
+ const derive=__m2["derive"];
15235
+ const FOLLOW_MODES=__m2["FOLLOW_MODES"];
15236
+ const DERIVED_ROW_KEY=__m2["DERIVED_ROW_KEY"];
15237
+ const IDLE_REFRESH_MS=16;
15238
+ const PROFILE_FIELDS=Object.freeze([
15239
+ 'column','rows','present','missing','distinct',
15240
+ 'min','max','mean','median','q1','q3','iqr','stddev','outliers',
15241
+ ]);
15242
+ class DerivedSource extends MemorySource{
15243
+ #from=null;
15244
+ #spec={};
15245
+ #off=[];
15246
+ #pending=null;
15247
+ #gone=false;
15248
+ #ctx={};
15249
+ #deriving=false;
15250
+ constructor(config,ctx){
15251
+ super({mode:'memory',rows:[]},ctx);
15252
+ this.#ctx=ctx||{};
15253
+ this.#spec=isObject(config)?config:{};
15254
+ this.#from=(this.#spec.from)||null;
15255
+ if(!this.#from){
15256
+ warnOnce('source.derived.from','source.mode "derived" needs `from`: the grid to derive from.');
15257
+ return;
15258
+ }
15259
+ if(this.#spec.follow&&!FOLLOW_MODES.includes(String(this.#spec.follow))){
15260
+ warnOnce(
15261
+ `source.derived.follow.${this.#spec.follow}`,
15262
+ `unknown follow "${this.#spec.follow}"; using "filtered". Known: ${FOLLOW_MODES.join(', ')}.`,
15263
+ );
15264
+ }
15265
+ this.#watch();
15266
+ this.refresh();
15267
+ }
15268
+ #watch(){
15269
+ const grid=this.#from;
15270
+ if(!grid||!isFunction(grid.on))return;
15271
+ const follow=String(this.#spec.follow||'filtered');
15272
+ const events=['rows:changed'];
15273
+ if(follow==='filtered'||follow==='grouped')events.push('filter:changed');
15274
+ if(follow==='selected')events.push('selection:changed');
15275
+ if(follow==='grouped')events.push('column:grouped');
15276
+ for(const name of events){
15277
+ const handler=()=>this.schedule();
15278
+ grid.on(name,handler);
15279
+ this.#off.push(()=>isFunction(grid.off)&&grid.off(name,handler));
15280
+ }
15281
+ }
15282
+ schedule(){
15283
+ const mode=this.#spec.refresh===undefined?'idle':this.#spec.refresh;
15284
+ if(mode==='manual')return;
15285
+ if(mode==='live'){this.refresh();return;}
15286
+ const wait=typeof mode==='number'&&Number.isFinite(mode)?mode:IDLE_REFRESH_MS;
15287
+ if(this.#pending)return;
15288
+ this.#pending=setTimeout(()=>{this.#pending=null;this.refresh();},wait);
15289
+ }
15290
+ refresh(){
15291
+ if(this.#gone||!this.#from)return;
15292
+ if(this.#deriving){
15293
+ warnOnce(
15294
+ 'source.derived.cycle',
15295
+ 'a derived grid is deriving from itself, directly or through a chain. '
15296
+ +'The cycle was refused; check the `from` of each grid in the chain.',
15297
+ );
15298
+ return;
15299
+ }
15300
+ this.#deriving=true;
15301
+ try{
15302
+ const rows=this.#spec.profile
15303
+ ?this.#deriveProfile()
15304
+ :derive(this.#sourceRows(),this.#resolvedSpec());
15305
+ this.setRows(rows);
15306
+ this.invalidate('filter');
15307
+ if(isFunction(this.#ctx.emit)){
15308
+ (this.#ctx.emit)('rows:changed',{},'derived');
15309
+ }
15310
+ }finally{
15311
+ this.#deriving=false;
15312
+ }
15313
+ }
15314
+ #resolvedSpec(){
15315
+ if(String(this.#spec.follow||'filtered')!=='grouped')return this.#spec;
15316
+ const grid=this.#from;
15317
+ const state=grid&&grid.state&&isFunction(grid.state.get)?grid.state.get():null;
15318
+ const grouped=state&&Array.isArray(state.group)?state.group:[];
15319
+ if(!grouped.length)return this.#spec;
15320
+ return{...this.#spec,groupBy:[...grouped]};
15321
+ }
15322
+ #sourceRows(){
15323
+ const grid=this.#from;
15324
+ const follow=String(this.#spec.follow||'filtered');
15325
+ if(!grid||!grid.rows)return[];
15326
+ if(follow==='all'){
15327
+ const every=[];
15328
+ if(isFunction(grid.rows.forEachAll)){
15329
+ grid.rows.forEachAll((row)=>{if(!row.group)every.push(unwrap(row));});
15330
+ }
15331
+ return every;
15332
+ }
15333
+ if(follow==='selected'){
15334
+ const rows=grid.selection&&isFunction(grid.selection.rows)?grid.selection.rows():[];
15335
+ return rows.filter(Boolean).map(unwrap);
15336
+ }
15337
+ const out=[];
15338
+ if(isFunction(grid.rows.forEach)){
15339
+ grid.rows.forEach((row)=>{if(!row.group)out.push(unwrap(row));});
15340
+ }
15341
+ return out;
15342
+ }
15343
+ #deriveProfile(){
15344
+ const grid=this.#from;
15345
+ if(!grid||!grid.statistics||!isFunction(grid.statistics.profile))return[];
15346
+ const wanted=Array.isArray(this.#spec.profile)?this.#spec.profile:[this.#spec.profile];
15347
+ const rows=wanted.filter(Boolean).map((colId)=>{
15348
+ const stats=grid.statistics.profile(String(colId))||{};
15349
+ const row={[DERIVED_ROW_KEY]:String(colId)};
15350
+ for(const field of PROFILE_FIELDS){
15351
+ row[field]=field==='column'?String(colId):(stats[field]??null);
15352
+ }
15353
+ row.outliers=Array.isArray(stats.outliers)?stats.outliers.length:(stats.outliers??null);
15354
+ return row;
15355
+ });
15356
+ if(this.#spec.orient!=='metrics')return rows;
15357
+ const first=rows[0];
15358
+ if(!first)return[];
15359
+ return PROFILE_FIELDS.filter((f)=>f!=='column').map((field)=>({
15360
+ [DERIVED_ROW_KEY]:field,metric:field,value:first[field],
15361
+ }));
15362
+ }
15363
+ apply(change){
15364
+ const ops=['add','update','remove'];
15365
+ const rejected=[];
15366
+ for(const op of ops){
15367
+ for(const row of(change&&change[op])||[]){
15368
+ rejected.push({operation:op,id:row&&row.id,reason:'derived-read-only'});
15369
+ }
15370
+ }
15371
+ if(rejected.length){
15372
+ warnOnce(
15373
+ 'source.derived.readonly',
15374
+ 'a derived grid is read-only: its rows are computed from another grid. '
15375
+ +'Write to the source grid instead, and the derived one follows.',
15376
+ );
15377
+ }
15378
+ return{added:[],updated:[],removed:[],rejected};
15379
+ }
15380
+ destroy(){
15381
+ this.#gone=true;
15382
+ if(this.#pending){clearTimeout(this.#pending);this.#pending=null;}
15383
+ for(const off of this.#off){try{off();}catch{}}
15384
+ this.#off=[];
15385
+ this.#from=null;
15386
+ super.destroy();
15387
+ }
15388
+ }
15389
+ function unwrap(row){
15390
+ return isObject(row)&&'data'in(row)
15391
+ ?(row).data
15392
+ :row;
15393
+ }
15394
+ function createDerivedSource(config,ctx){
15395
+ return new DerivedSource(config,ctx);
15396
+ }
15397
+ });
15025
15398
  __def("packages/core/src/source/index.js",function(__exports,__req){
15026
15399
  'use strict';
15027
15400
  Object.defineProperty(__exports,"createMemorySource",{enumerable:true,get:function(){return createMemorySource;}});
@@ -15035,6 +15408,10 @@ Object.defineProperty(__exports,"PROTOCOL",{enumerable:true,get:function(){retur
15035
15408
  Object.defineProperty(__exports,"createStreamSource",{enumerable:true,get:function(){return createStreamSource;}});
15036
15409
  Object.defineProperty(__exports,"StreamSource",{enumerable:true,get:function(){return StreamSource;}});
15037
15410
  Object.defineProperty(__exports,"DEFAULT_PROMOTE_BELOW",{enumerable:true,get:function(){return DEFAULT_PROMOTE_BELOW;}});
15411
+ Object.defineProperty(__exports,"createDerivedSource",{enumerable:true,get:function(){return createDerivedSource;}});
15412
+ Object.defineProperty(__exports,"DerivedSource",{enumerable:true,get:function(){return DerivedSource;}});
15413
+ Object.defineProperty(__exports,"IDLE_REFRESH_MS",{enumerable:true,get:function(){return IDLE_REFRESH_MS;}});
15414
+ Object.defineProperty(__exports,"PROFILE_FIELDS",{enumerable:true,get:function(){return PROFILE_FIELDS;}});
15038
15415
  Object.defineProperty(__exports,"MODES",{enumerable:true,get:function(){return MODES;}});
15039
15416
  Object.defineProperty(__exports,"createSource",{enumerable:true,get:function(){return createSource;}});
15040
15417
  const __m0=__req("packages/core/src/internal/util.js");
@@ -15056,41 +15433,57 @@ const __m4=__req("packages/core/src/source/stream.js");
15056
15433
  const createStreamSource=__m4["createStreamSource"];
15057
15434
  const StreamSource=__m4["StreamSource"];
15058
15435
  const DEFAULT_PROMOTE_BELOW=__m4["DEFAULT_PROMOTE_BELOW"];
15059
- const __m5=__req("packages/core/src/source/abort.js");
15060
- Object.defineProperty(__exports,"AbortScope",{enumerable:true,get:function(){return __m5["AbortScope"];}});
15061
- Object.defineProperty(__exports,"RequestToken",{enumerable:true,get:function(){return __m5["RequestToken"];}});
15062
- Object.defineProperty(__exports,"SupersededError",{enumerable:true,get:function(){return __m5["SupersededError"];}});
15063
- Object.defineProperty(__exports,"createAbortScope",{enumerable:true,get:function(){return __m5["createAbortScope"];}});
15064
- Object.defineProperty(__exports,"isAbortError",{enumerable:true,get:function(){return __m5["isAbortError"];}});
15065
- const __m6=__req("packages/core/src/source/filterwire.js");
15066
- Object.defineProperty(__exports,"RELATIVE_TOKENS",{enumerable:true,get:function(){return __m6["RELATIVE_TOKENS"];}});
15067
- Object.defineProperty(__exports,"parseRelativeToken",{enumerable:true,get:function(){return __m6["parseRelativeToken"];}});
15068
- Object.defineProperty(__exports,"resolveRelativeRange",{enumerable:true,get:function(){return __m6["resolveRelativeRange"];}});
15069
- Object.defineProperty(__exports,"resolveRelativeCondition",{enumerable:true,get:function(){return __m6["resolveRelativeCondition"];}});
15070
- Object.defineProperty(__exports,"relativeTokenOf",{enumerable:true,get:function(){return __m6["relativeTokenOf"];}});
15071
- Object.defineProperty(__exports,"buildFilterSet",{enumerable:true,get:function(){return __m6["buildFilterSet"];}});
15072
- Object.defineProperty(__exports,"normaliseFilterSet",{enumerable:true,get:function(){return __m6["normaliseFilterSet"];}});
15073
- Object.defineProperty(__exports,"wireFilters",{enumerable:true,get:function(){return __m6["wireFilters"];}});
15074
- Object.defineProperty(__exports,"querySignature",{enumerable:true,get:function(){return __m6["querySignature"];}});
15075
- Object.defineProperty(__exports,"mapConditions",{enumerable:true,get:function(){return __m6["mapConditions"];}});
15076
- Object.defineProperty(__exports,"forEachCondition",{enumerable:true,get:function(){return __m6["forEachCondition"];}});
15077
- Object.defineProperty(__exports,"isGroup",{enumerable:true,get:function(){return __m6["isGroup"];}});
15078
- const __m7=__req("packages/core/src/source/blockcache.js");
15079
- Object.defineProperty(__exports,"BlockCache",{enumerable:true,get:function(){return __m7["BlockCache"];}});
15080
- Object.defineProperty(__exports,"DEFAULT_PAGE_SIZE",{enumerable:true,get:function(){return __m7["DEFAULT_PAGE_SIZE"];}});
15081
- Object.defineProperty(__exports,"DEFAULT_MAX_CACHED_PAGES",{enumerable:true,get:function(){return __m7["DEFAULT_MAX_CACHED_PAGES"];}});
15082
- const __m8=__req("packages/core/src/source/gapbuffer.js");
15083
- Object.defineProperty(__exports,"GapBuffer",{enumerable:true,get:function(){return __m8["GapBuffer"];}});
15084
- const __m9=__req("packages/core/src/source/rows.js");
15085
- Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return __m9["RowFactory"];}});
15086
- Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function(){return __m9["createRowFactory"];}});
15087
- Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return __m9["groupKey"];}});
15088
- Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return __m9["lazyRowView"];}});
15089
- Object.defineProperty(__exports,"DEFAULT_ROW_HEIGHT",{enumerable:true,get:function(){return __m9["DEFAULT_ROW_HEIGHT"];}});
15090
- const __m10=__req("packages/core/src/source/handles.js");
15091
- Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function(){return __m10["HandleProvider"];}});
15092
- Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return __m10["createHandleProvider"];}});
15093
- const MODES=Object.freeze(['memory','paged','remote','stream']);
15436
+ const __m5=__req("packages/core/src/source/derived.js");
15437
+ const createDerivedSource=__m5["createDerivedSource"];
15438
+ const DerivedSource=__m5["DerivedSource"];
15439
+ const IDLE_REFRESH_MS=__m5["IDLE_REFRESH_MS"];
15440
+ const PROFILE_FIELDS=__m5["PROFILE_FIELDS"];
15441
+ const __m6=__req("packages/core/src/source/derive.js");
15442
+ Object.defineProperty(__exports,"derive",{enumerable:true,get:function(){return __m6["derive"];}});
15443
+ Object.defineProperty(__exports,"unnest",{enumerable:true,get:function(){return __m6["unnest"];}});
15444
+ Object.defineProperty(__exports,"readPath",{enumerable:true,get:function(){return __m6["readPath"];}});
15445
+ Object.defineProperty(__exports,"bucketOf",{enumerable:true,get:function(){return __m6["bucketOf"];}});
15446
+ Object.defineProperty(__exports,"applyLimit",{enumerable:true,get:function(){return __m6["applyLimit"];}});
15447
+ Object.defineProperty(__exports,"applyCumulative",{enumerable:true,get:function(){return __m6["applyCumulative"];}});
15448
+ Object.defineProperty(__exports,"reduceValues",{enumerable:true,get:function(){return __m6["reduceValues"];}});
15449
+ Object.defineProperty(__exports,"FOLLOW_MODES",{enumerable:true,get:function(){return __m6["FOLLOW_MODES"];}});
15450
+ Object.defineProperty(__exports,"BUCKETS",{enumerable:true,get:function(){return __m6["BUCKETS"];}});
15451
+ Object.defineProperty(__exports,"DERIVED_ROW_KEY",{enumerable:true,get:function(){return __m6["DERIVED_ROW_KEY"];}});
15452
+ const __m7=__req("packages/core/src/source/abort.js");
15453
+ Object.defineProperty(__exports,"AbortScope",{enumerable:true,get:function(){return __m7["AbortScope"];}});
15454
+ Object.defineProperty(__exports,"RequestToken",{enumerable:true,get:function(){return __m7["RequestToken"];}});
15455
+ Object.defineProperty(__exports,"SupersededError",{enumerable:true,get:function(){return __m7["SupersededError"];}});
15456
+ Object.defineProperty(__exports,"createAbortScope",{enumerable:true,get:function(){return __m7["createAbortScope"];}});
15457
+ Object.defineProperty(__exports,"isAbortError",{enumerable:true,get:function(){return __m7["isAbortError"];}});
15458
+ const __m8=__req("packages/core/src/source/filterwire.js");
15459
+ Object.defineProperty(__exports,"RELATIVE_TOKENS",{enumerable:true,get:function(){return __m8["RELATIVE_TOKENS"];}});
15460
+ Object.defineProperty(__exports,"parseRelativeToken",{enumerable:true,get:function(){return __m8["parseRelativeToken"];}});
15461
+ Object.defineProperty(__exports,"resolveRelativeRange",{enumerable:true,get:function(){return __m8["resolveRelativeRange"];}});
15462
+ Object.defineProperty(__exports,"resolveRelativeCondition",{enumerable:true,get:function(){return __m8["resolveRelativeCondition"];}});
15463
+ Object.defineProperty(__exports,"relativeTokenOf",{enumerable:true,get:function(){return __m8["relativeTokenOf"];}});
15464
+ Object.defineProperty(__exports,"buildFilterSet",{enumerable:true,get:function(){return __m8["buildFilterSet"];}});
15465
+ Object.defineProperty(__exports,"normaliseFilterSet",{enumerable:true,get:function(){return __m8["normaliseFilterSet"];}});
15466
+ Object.defineProperty(__exports,"wireFilters",{enumerable:true,get:function(){return __m8["wireFilters"];}});
15467
+ Object.defineProperty(__exports,"querySignature",{enumerable:true,get:function(){return __m8["querySignature"];}});
15468
+ Object.defineProperty(__exports,"mapConditions",{enumerable:true,get:function(){return __m8["mapConditions"];}});
15469
+ Object.defineProperty(__exports,"forEachCondition",{enumerable:true,get:function(){return __m8["forEachCondition"];}});
15470
+ Object.defineProperty(__exports,"isGroup",{enumerable:true,get:function(){return __m8["isGroup"];}});
15471
+ const __m9=__req("packages/core/src/source/blockcache.js");
15472
+ Object.defineProperty(__exports,"BlockCache",{enumerable:true,get:function(){return __m9["BlockCache"];}});
15473
+ Object.defineProperty(__exports,"DEFAULT_PAGE_SIZE",{enumerable:true,get:function(){return __m9["DEFAULT_PAGE_SIZE"];}});
15474
+ Object.defineProperty(__exports,"DEFAULT_MAX_CACHED_PAGES",{enumerable:true,get:function(){return __m9["DEFAULT_MAX_CACHED_PAGES"];}});
15475
+ const __m10=__req("packages/core/src/source/gapbuffer.js");
15476
+ Object.defineProperty(__exports,"GapBuffer",{enumerable:true,get:function(){return __m10["GapBuffer"];}});
15477
+ const __m11=__req("packages/core/src/source/rows.js");
15478
+ Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return __m11["RowFactory"];}});
15479
+ Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function(){return __m11["createRowFactory"];}});
15480
+ Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return __m11["groupKey"];}});
15481
+ Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return __m11["lazyRowView"];}});
15482
+ Object.defineProperty(__exports,"DEFAULT_ROW_HEIGHT",{enumerable:true,get:function(){return __m11["DEFAULT_ROW_HEIGHT"];}});
15483
+ const __m12=__req("packages/core/src/source/handles.js");
15484
+ Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function(){return __m12["HandleProvider"];}});
15485
+ Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return __m12["createHandleProvider"];}});
15486
+ const MODES=Object.freeze(['memory','paged','remote','stream','derived']);
15094
15487
  function createSource(config,ctx){
15095
15488
  if(!ctx)fail('createSource requires a SourceContext');
15096
15489
  const resolved=isObject(config)?config:{mode:'memory'};
@@ -15100,6 +15493,7 @@ case'memory':return createMemorySource((resolved),ctx);
15100
15493
  case'paged':return createPagedSource((resolved),ctx);
15101
15494
  case'remote':return createRemoteSource((resolved),ctx);
15102
15495
  case'stream':return createStreamSource((resolved),ctx);
15496
+ case'derived':return createDerivedSource((resolved),ctx);
15103
15497
  default:
15104
15498
  warnOnce(
15105
15499
  `source.mode.${mode}`,
@@ -25190,6 +25584,7 @@ const __m19=__req("packages/core/src/compute/index.js");
25190
25584
  const compute=__m19;
25191
25585
  const __m20=__req("packages/core/src/source/index.js");
25192
25586
  const createSource=__m20["createSource"];
25587
+ const DERIVED_ROW_KEY=__m20["DERIVED_ROW_KEY"];
25193
25588
  const __m21=__req("packages/core/src/source/rows.js");
25194
25589
  const pinnedRow=__m21["pinnedRow"];
25195
25590
  const DEFAULT_ROW_HEIGHT=__m21["DEFAULT_ROW_HEIGHT"];
@@ -25446,6 +25841,10 @@ for(const[name,fn]of Object.entries(this.#config.totalFns||{})){
25446
25841
  if(isFunction(fn))this.#registry.register('totalFn',name,fn);
25447
25842
  }
25448
25843
  this.#pool=new MaskPool();
25844
+ if(this.#config.rowKey===undefined&&isObject(this.#config.source)
25845
+ &&(this.#config.source).mode==='derived'){
25846
+ this.#config.rowKey=DERIVED_ROW_KEY;
25847
+ }
25449
25848
  this.#rowKeyResolver=createRowKey(this.#config.rowKey);
25450
25849
  this.#rowKey=(data,index)=>this.#rowKeyResolver.key(data,index);
25451
25850
  if(Array.isArray(this.#config.pinnedTopRows))this.#pinnedTop=this.#config.pinnedTopRows.slice();
@@ -28625,6 +29024,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
28625
29024
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return parseRadix;}});
28626
29025
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return formatRadix;}});
28627
29026
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return createUnitType;}});
29027
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return registerUnitSystem;}});
29028
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return defineUnit;}});
28628
29029
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return UNIT_SYSTEMS;}});
28629
29030
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return parseUnit;}});
28630
29031
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return formatUnit;}});
@@ -28635,6 +29036,8 @@ const RADIX_PRESETS=__m0["RADIX_PRESETS"];
28635
29036
  const parseRadix=__m0["parseRadix"];
28636
29037
  const formatRadix=__m0["formatRadix"];
28637
29038
  const createUnitType=__m0["createUnitType"];
29039
+ const registerUnitSystem=__m0["registerUnitSystem"];
29040
+ const defineUnit=__m0["defineUnit"];
28638
29041
  const UNIT_SYSTEMS=__m0["UNIT_SYSTEMS"];
28639
29042
  const parseUnit=__m0["parseUnit"];
28640
29043
  const formatUnit=__m0["formatUnit"];
@@ -38086,6 +38489,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
38086
38489
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m5["parseRadix"];}});
38087
38490
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m5["formatRadix"];}});
38088
38491
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m5["createUnitType"];}});
38492
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m5["registerUnitSystem"];}});
38493
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m5["defineUnit"];}});
38089
38494
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m5["UNIT_SYSTEMS"];}});
38090
38495
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m5["parseUnit"];}});
38091
38496
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m5["formatUnit"];}});
@@ -38417,6 +38822,7 @@ const PREFIX='lat';
38417
38822
  const NAMESPACE='lattice';
38418
38823
  const CLASS={
38419
38824
  root:`${PREFIX}-grid-root`,
38825
+ title:`${PREFIX}-title`,
38420
38826
  header:`${PREFIX}-header`,
38421
38827
  headerStart:`${PREFIX}-header-left-pinned`,
38422
38828
  headerCentreClip:`${PREFIX}-header-centre-clip`,
@@ -38472,6 +38878,8 @@ fail('DomRenderer needs a DOM. Use createHeadlessGrid() on the server.');
38472
38878
  this.#document=document;
38473
38879
  this.#host=element;
38474
38880
  this.root=el(document,`${NAMESPACE} ${CLASS.root}`);
38881
+ this.title=el(document,CLASS.title);
38882
+ this.title.hidden=true;
38475
38883
  this.header=el(document,CLASS.header);
38476
38884
  this.headerStart=el(document,CLASS.headerStart);
38477
38885
  this.headerCentreClip=el(document,CLASS.headerCentreClip);
@@ -38501,6 +38909,7 @@ this.stickyBottom=el(document,CLASS.stickyBottom);
38501
38909
  this.overlays=el(document,CLASS.overlays);
38502
38910
  this.statusBar=el(document,CLASS.statusBar);
38503
38911
  this.measureLayer=el(document,CLASS.measure);
38912
+ this.root.appendChild(this.title);
38504
38913
  this.root.appendChild(this.header);
38505
38914
  this.root.appendChild(this.bodyViewport);
38506
38915
  this.root.appendChild(this.stickyTop);
@@ -38510,6 +38919,14 @@ this.root.appendChild(this.statusBar);
38510
38919
  this.root.appendChild(this.measureLayer);
38511
38920
  }
38512
38921
  get document(){return this.#document;}
38922
+ setTitle(text){
38923
+ const value=text===null||text===undefined?'':String(text);
38924
+ this.title.textContent=value;
38925
+ this.title.hidden=value==='';
38926
+ }
38927
+ setHeaderVisible(visible){
38928
+ this.header.hidden=!visible;
38929
+ }
38513
38930
  mount(){
38514
38931
  this.#host.appendChild(this.root);
38515
38932
  }
@@ -42257,6 +42674,7 @@ this.#host=host;
42257
42674
  this.#cellLayer=host.cellLayer||textCellLayer;
42258
42675
  this.#overscan=Number.isFinite(host.config?.overscan)?host.config.overscan:DEFAULT_OVERSCAN;
42259
42676
  this.#viewport=new Viewport(element,{document:host.document});
42677
+ this.#applyChrome(host.config);
42260
42678
  this.#layout=new ColumnLayout({
42261
42679
  columns:()=>this.#visibleColumns(),
42262
42680
  threshold:host.config?.columnVirtualisationAbove,
@@ -42326,6 +42744,11 @@ onFrame:(ctx)=>this.#frame(ctx),
42326
42744
  onScrollEnd:()=>this.#host.emit('scroll:end',this.scrollPosition()),
42327
42745
  });
42328
42746
  }
42747
+ #applyChrome(config){
42748
+ const title=config&&config.title;
42749
+ this.#viewport.setTitle(typeof title==='string'?title:null);
42750
+ this.#viewport.setHeaderVisible(!(config&&config.showHeader===false));
42751
+ }
42329
42752
  mount(){
42330
42753
  if(this.#mountedOnce)return;
42331
42754
  this.#mountedOnce=true;
@@ -59659,6 +60082,12 @@ const __m3=__req("packages/dom/src/renderer/textentry.js");
59659
60082
  const isTextEntry=__m3["isTextEntry"];
59660
60083
  const IN_RANGE='lat-cell--range';
59661
60084
  const RANGE_EDGE='lat-cell--range-edge';
60085
+ const EDGE_SIDES=Object.freeze({
60086
+ top:'lat-cell--range-top',
60087
+ right:'lat-cell--range-right',
60088
+ bottom:'lat-cell--range-bottom',
60089
+ left:'lat-cell--range-left',
60090
+ });
59662
60091
  const DRAG_THRESHOLD=3;
59663
60092
  class RangeController{
59664
60093
  #grid;
@@ -59920,7 +60349,13 @@ if(!Number.isFinite(index)||index<0)continue;
59920
60349
  const inRange=hasRange&&selection.inRange(index,colId);
59921
60350
  const inPreview=!!preview&&this.#inFillPreview(index,colId,preview);
59922
60351
  cell.classList.toggle(IN_RANGE,inRange||inPreview);
59923
- cell.classList.toggle(RANGE_EDGE,(inRange||inPreview)&&this.#isEdge(index,colId,selection));
60352
+ const edges=(inRange||inPreview)
60353
+ ?this.#edgesOf(index,colId,selection)
60354
+ :null;
60355
+ cell.classList.toggle(RANGE_EDGE,!!edges&&edges.any);
60356
+ for(const[side,className]of Object.entries(EDGE_SIDES)){
60357
+ cell.classList.toggle(className,!!edges&&edges[side]);
60358
+ }
59924
60359
  }
59925
60360
  this.#placeHandle();
59926
60361
  }
@@ -59932,15 +60367,19 @@ if(!columns.has(colId))return false;
59932
60367
  const last=this.#indexOfKey([...new Set(cells.map((c)=>c.key))].pop());
59933
60368
  return index>last&&index<=preview.rowIndex;
59934
60369
  }
59935
- #isEdge(index,colId,selection){
60370
+ #edgesOf(index,colId,selection){
59936
60371
  const columns=this.#grid.columns.visible().map((c)=>c.id);
59937
60372
  const at=columns.indexOf(colId);
59938
- const left=at>0?columns[at-1]:null;
59939
- const right=at<columns.length-1?columns[at+1]:null;
59940
- return!selection.inRange(index-1,colId)
59941
- ||!selection.inRange(index+1,colId)
59942
- ||!left||!selection.inRange(index,left)
59943
- ||!right||!selection.inRange(index,right);
60373
+ const before=at>0?columns[at-1]:null;
60374
+ const after=at>=0&&at<columns.length-1?columns[at+1]:null;
60375
+ const edges={
60376
+ top:!selection.inRange(index-1,colId),
60377
+ bottom:!selection.inRange(index+1,colId),
60378
+ left:!before||!selection.inRange(index,before),
60379
+ right:!after||!selection.inRange(index,after),
60380
+ };
60381
+ edges.any=edges.top||edges.bottom||edges.left||edges.right;
60382
+ return edges;
59944
60383
  }
59945
60384
  #placeHandle(){
59946
60385
  const corner=this.#grid.selection.corner();
@@ -62986,6 +63425,229 @@ grids.push(el.tagName==='TABLE'?hydrateTable(el,config):createGrid(el,config));
62986
63425
  return grids;
62987
63426
  }
62988
63427
  });
63428
+ __def("packages/dom/src/stat.js",function(__exports,__req){
63429
+ 'use strict';
63430
+ Object.defineProperty(__exports,"deltaOf",{enumerable:true,get:function(){return deltaOf;}});
63431
+ Object.defineProperty(__exports,"toneOf",{enumerable:true,get:function(){return toneOf;}});
63432
+ Object.defineProperty(__exports,"createStat",{enumerable:true,get:function(){return createStat;}});
63433
+ const __m0=__req("packages/core/src/internal/util.js");
63434
+ const isFunction=__m0["isFunction"];
63435
+ const isObject=__m0["isObject"];
63436
+ const warnOnce=__m0["warnOnce"];
63437
+ const __m1=__req("packages/core/src/source/derive.js");
63438
+ const reduceValues=__m1["reduceValues"];
63439
+ const CLS={
63440
+ root:'lat-stat',
63441
+ title:'lat-stat__title',
63442
+ value:'lat-stat__value',
63443
+ delta:'lat-stat__delta',
63444
+ footer:'lat-stat__footer',
63445
+ };
63446
+ const UNIT_PRESERVING=new Set([
63447
+ 'sum','min','max','avg','first','last','mode',
63448
+ 'median','p25','p75','p90','p95','p99',
63449
+ 'stddev','stddevP','mad','range','iqr',
63450
+ 'trimmedMean','winsorizedMean','geomean','harmean',
63451
+ ]);
63452
+ const NO_DELTA=Object.freeze({direction:'flat',change:null,percent:null});
63453
+ function deltaOf(value,baseline){
63454
+ if(!Number.isFinite((value))
63455
+ ||!Number.isFinite((baseline)))return NO_DELTA;
63456
+ const change=(value)-(baseline);
63457
+ const direction=change>0?'up':(change<0?'down':'flat');
63458
+ const percent=baseline===0?null:(change/Math.abs((baseline)))*100;
63459
+ return{direction,change,percent};
63460
+ }
63461
+ function toneOf(direction,goodWhen){
63462
+ if(direction==='flat'||goodWhen==='neither')return'flat';
63463
+ return direction===goodWhen?'good':'bad';
63464
+ }
63465
+ function createStat(spec){
63466
+ const config=isObject(spec)?spec:{};
63467
+ const grid=config.grid||null;
63468
+ const host=resolveContainer(config.container,grid);
63469
+ if(!host){
63470
+ warnOnce('stat.container','createStat needs a `container`: an element or a selector.');
63471
+ return inert();
63472
+ }
63473
+ const doc=host.ownerDocument||(typeof document==='undefined'?null:document);
63474
+ if(!doc){
63475
+ warnOnce('stat.document','createStat needs a document; it draws DOM.');
63476
+ return inert();
63477
+ }
63478
+ const root=doc.createElement('div');
63479
+ root.className=['lattice',CLS.root,config.class].filter(Boolean).join(' ');
63480
+ root.setAttribute('role','group');
63481
+ const titleEl=doc.createElement('div');
63482
+ titleEl.className=CLS.title;
63483
+ const valueEl=doc.createElement('div');
63484
+ valueEl.className=CLS.value;
63485
+ const deltaEl=doc.createElement('div');
63486
+ deltaEl.className=CLS.delta;
63487
+ const footerEl=doc.createElement('div');
63488
+ footerEl.className=CLS.footer;
63489
+ root.appendChild(titleEl);
63490
+ root.appendChild(valueEl);
63491
+ root.appendChild(deltaEl);
63492
+ root.appendChild(footerEl);
63493
+ host.appendChild(root);
63494
+ let current=null;
63495
+ const off=[];
63496
+ let gone=false;
63497
+ function compute(){
63498
+ if(isFunction(config.value))return config.value(grid);
63499
+ if(config.value!==undefined&&!isObject(config.value))return config.value;
63500
+ const from=isObject(config.value)?config.value:config;
63501
+ const col=from.of;
63502
+ const fn=from.fn||'sum';
63503
+ const show=from.show;
63504
+ if(!grid)return null;
63505
+ if(fn==='count')return rowsInScope().length;
63506
+ if(!col)return null;
63507
+ if(show)return pick(String(col),String(fn),String(show));
63508
+ if(scope()==='filtered'&&grid.statistics&&isFunction(grid.statistics.reduce)){
63509
+ return grid.statistics.reduce(String(col),String(fn));
63510
+ }
63511
+ return reduceValues(rowsInScope().map((row)=>valueOf(row,String(col))),String(fn));
63512
+ }
63513
+ function scope(){
63514
+ return String(config.scope||'filtered');
63515
+ }
63516
+ function rowsInScope(){
63517
+ if(!grid||!grid.rows)return[];
63518
+ const want=scope();
63519
+ if(want==='all'){
63520
+ const every=[];
63521
+ if(isFunction(grid.rows.forEachAll))grid.rows.forEachAll((row)=>{if(!row.group)every.push(plain(row));});
63522
+ return every;
63523
+ }
63524
+ if(want==='selected'){
63525
+ const rows=grid.selection&&isFunction(grid.selection.rows)?grid.selection.rows():[];
63526
+ return rows.filter(Boolean).map(plain);
63527
+ }
63528
+ const out=[];
63529
+ if(isFunction(grid.rows.forEach)){
63530
+ grid.rows.forEach((row)=>{if(!row.group)out.push(plain(row));});
63531
+ }
63532
+ return out;
63533
+ }
63534
+ function pick(col,fn,show){
63535
+ if(fn!=='min'&&fn!=='max'){
63536
+ warnOnce(
63537
+ `stat.show.${fn}`,
63538
+ `\`show\` needs \`fn: 'min'\` or \`fn: 'max'\`: "${fn}" reduces to a value that no single `
63539
+ +'row holds, so there is no row to report from.',
63540
+ );
63541
+ return null;
63542
+ }
63543
+ let best=null;
63544
+ let bestRow=null;
63545
+ for(const row of rowsInScope()){
63546
+ const value=Number(valueOf(row,col));
63547
+ if(!Number.isFinite(value))continue;
63548
+ if(best===null||(fn==='max'?value>best:value<best)){
63549
+ best=value;
63550
+ bestRow=row;
63551
+ }
63552
+ }
63553
+ return bestRow===null?null:valueOf(bestRow,show);
63554
+ }
63555
+ function render(value){
63556
+ if(isFunction(config.format))return String(config.format(value,grid));
63557
+ if(value===null||value===undefined)return config.empty??'—';
63558
+ const from=isObject(config.value)?config.value:config;
63559
+ const source=from.show||from.of;
63560
+ const borrow=from.show?true:UNIT_PRESERVING.has(String(from.fn||'sum'));
63561
+ if(borrow&&grid&&source&&isFunction(grid.columns?.get)){
63562
+ const column=grid.columns.get(String(source));
63563
+ if(column&&isFunction(column.formatValue))return column.formatValue(value);
63564
+ }
63565
+ if(typeof value==='number'){
63566
+ return Number.isInteger(value)?String(value):value.toFixed(config.decimals??2);
63567
+ }
63568
+ return String(value);
63569
+ }
63570
+ function refresh(){
63571
+ if(gone)return;
63572
+ const value=compute();
63573
+ const baseline=isFunction(config.baseline)?config.baseline(grid):config.baseline;
63574
+ current=value;
63575
+ titleEl.textContent=config.title??'';
63576
+ titleEl.hidden=!config.title;
63577
+ valueEl.textContent=render(value);
63578
+ const delta=baseline===undefined||baseline===null
63579
+ ?NO_DELTA
63580
+ :deltaOf(typeof value==='number'?value:null,Number(baseline));
63581
+ const tone=toneOf(delta.direction,config.goodWhen||'up');
63582
+ deltaEl.hidden=delta.change===null;
63583
+ if(delta.change!==null){
63584
+ const arrow=delta.direction==='up'?'↑':(delta.direction==='down'?'↓':'→');
63585
+ const size=delta.percent===null
63586
+ ?render(Math.abs(delta.change))
63587
+ :`${Math.abs(delta.percent).toFixed(1)}%`;
63588
+ deltaEl.textContent=`${arrow} ${size}`;
63589
+ deltaEl.setAttribute('data-tone',tone);
63590
+ deltaEl.setAttribute('data-direction',delta.direction);
63591
+ }
63592
+ footerEl.textContent=isFunction(config.footer)?String(config.footer(value,grid)):(config.footer??'');
63593
+ footerEl.hidden=!footerEl.textContent;
63594
+ root.setAttribute('aria-label',[
63595
+ config.title,valueEl.textContent,
63596
+ delta.change===null?'':deltaEl.textContent,
63597
+ footerEl.textContent,
63598
+ ].filter(Boolean).join(', '));
63599
+ }
63600
+ if(grid&&isFunction(grid.on)&&config.live!==false){
63601
+ for(const event of['rows:changed','filter:changed','selection:changed']){
63602
+ const handler=()=>refresh();
63603
+ grid.on(event,handler);
63604
+ off.push(()=>isFunction(grid.off)&&grid.off(event,handler));
63605
+ }
63606
+ }
63607
+ refresh();
63608
+ return{
63609
+ element:()=>root,
63610
+ value:()=>current,
63611
+ refresh,
63612
+ destroy(){
63613
+ gone=true;
63614
+ for(const remove of off){try{remove();}catch{}}
63615
+ off.length=0;
63616
+ root.remove();
63617
+ },
63618
+ };
63619
+ }
63620
+ function plain(row){
63621
+ return isObject(row)&&'data'in(row)
63622
+ ?(row).data
63623
+ :row;
63624
+ }
63625
+ function valueOf(row,path){
63626
+ if(!isObject(row))return undefined;
63627
+ if(!path.includes('.'))return(row)[path];
63628
+ let cursor=(row);
63629
+ for(const part of path.split('.')){
63630
+ if(!isObject(cursor))return undefined;
63631
+ cursor=(cursor)[part];
63632
+ }
63633
+ return cursor;
63634
+ }
63635
+ function resolveContainer(container,grid){
63636
+ if(container&&typeof container==='object')return(container);
63637
+ if(typeof container!=='string')return null;
63638
+ const doc=(grid&&grid.element&&grid.element.ownerDocument)
63639
+ ||(typeof document==='undefined'?null:document);
63640
+ return doc?doc.querySelector(container):null;
63641
+ }
63642
+ function inert(){
63643
+ return{
63644
+ element:()=>null,
63645
+ value:()=>null,
63646
+ refresh(){},
63647
+ destroy(){},
63648
+ };
63649
+ }
63650
+ });
62989
63651
  __def("packages/dom/src/index.js",function(__exports,__req){
62990
63652
  'use strict';
62991
63653
  Object.defineProperty(__exports,"LatticeGrid",{enumerable:true,get:function(){return LatticeGrid;}});
@@ -63008,6 +63670,10 @@ const serialiseState=__m4["serialiseState"];
63008
63670
  const restoreState=__m4["restoreState"];
63009
63671
  Object.defineProperty(__exports,"createGrid",{enumerable:true,get:function(){return __m0["createGrid"];}});
63010
63672
  Object.defineProperty(__exports,"gridElementsWithin",{enumerable:true,get:function(){return __m0["gridElementsWithin"];}});
63673
+ const __m5=__req("packages/dom/src/stat.js");
63674
+ Object.defineProperty(__exports,"createStat",{enumerable:true,get:function(){return __m5["createStat"];}});
63675
+ Object.defineProperty(__exports,"deltaOf",{enumerable:true,get:function(){return __m5["deltaOf"];}});
63676
+ Object.defineProperty(__exports,"toneOf",{enumerable:true,get:function(){return __m5["toneOf"];}});
63011
63677
  Object.defineProperty(__exports,"readTable",{enumerable:true,get:function(){return __m1["readTable"];}});
63012
63678
  Object.defineProperty(__exports,"hydrateTable",{enumerable:true,get:function(){return __m1["hydrateTable"];}});
63013
63679
  Object.defineProperty(__exports,"autoInit",{enumerable:true,get:function(){return __m2["autoInit"];}});
@@ -63043,6 +63709,8 @@ Object.defineProperty(__exports,"RADIX_PRESETS",{enumerable:true,get:function(){
63043
63709
  Object.defineProperty(__exports,"parseRadix",{enumerable:true,get:function(){return __m4["parseRadix"];}});
63044
63710
  Object.defineProperty(__exports,"formatRadix",{enumerable:true,get:function(){return __m4["formatRadix"];}});
63045
63711
  Object.defineProperty(__exports,"createUnitType",{enumerable:true,get:function(){return __m4["createUnitType"];}});
63712
+ Object.defineProperty(__exports,"registerUnitSystem",{enumerable:true,get:function(){return __m4["registerUnitSystem"];}});
63713
+ Object.defineProperty(__exports,"defineUnit",{enumerable:true,get:function(){return __m4["defineUnit"];}});
63046
63714
  Object.defineProperty(__exports,"UNIT_SYSTEMS",{enumerable:true,get:function(){return __m4["UNIT_SYSTEMS"];}});
63047
63715
  Object.defineProperty(__exports,"parseUnit",{enumerable:true,get:function(){return __m4["parseUnit"];}});
63048
63716
  Object.defineProperty(__exports,"formatUnit",{enumerable:true,get:function(){return __m4["formatUnit"];}});
@@ -63114,71 +63782,71 @@ Object.defineProperty(__exports,"STATE_VERSION",{enumerable:true,get:function(){
63114
63782
  Object.defineProperty(__exports,"serialiseState",{enumerable:true,get:function(){return __m4["serialiseState"];}});
63115
63783
  Object.defineProperty(__exports,"restoreState",{enumerable:true,get:function(){return __m4["restoreState"];}});
63116
63784
  Object.defineProperty(__exports,"VERSION",{enumerable:true,get:function(){return __m4["VERSION"];}});
63117
- const __m5=__req("packages/dom/src/renderer/index.js");
63118
- Object.defineProperty(__exports,"DomRenderer",{enumerable:true,get:function(){return __m5["DomRenderer"];}});
63119
- const __m6=__req("packages/dom/src/filtermenu.js");
63120
- Object.defineProperty(__exports,"FilterMenu",{enumerable:true,get:function(){return __m6["FilterMenu"];}});
63121
- Object.defineProperty(__exports,"mergeColumnFilter",{enumerable:true,get:function(){return __m6["mergeColumnFilter"];}});
63122
- Object.defineProperty(__exports,"branchFor",{enumerable:true,get:function(){return __m6["branchFor"];}});
63123
- const __m7=__req("packages/dom/src/columnmenu.js");
63124
- Object.defineProperty(__exports,"ColumnMenu",{enumerable:true,get:function(){return __m7["ColumnMenu"];}});
63125
- Object.defineProperty(__exports,"columnMenuItems",{enumerable:true,get:function(){return __m7["columnMenuItems"];}});
63126
- Object.defineProperty(__exports,"cellMenuItems",{enumerable:true,get:function(){return __m7["cellMenuItems"];}});
63127
- Object.defineProperty(__exports,"autoGroupMenuItems",{enumerable:true,get:function(){return __m7["autoGroupMenuItems"];}});
63128
- const __m8=__req("packages/dom/src/alignedgrids.js");
63129
- Object.defineProperty(__exports,"AlignedGrids",{enumerable:true,get:function(){return __m8["AlignedGrids"];}});
63130
- Object.defineProperty(__exports,"alignGrids",{enumerable:true,get:function(){return __m8["alignGrids"];}});
63131
- Object.defineProperty(__exports,"layoutState",{enumerable:true,get:function(){return __m8["layoutState"];}});
63132
- const __m9=__req("packages/dom/src/toolpanelmount.js");
63133
- Object.defineProperty(__exports,"ToolPanelDock",{enumerable:true,get:function(){return __m9["ToolPanelDock"];}});
63134
- Object.defineProperty(__exports,"panelHost",{enumerable:true,get:function(){return __m9["panelHost"];}});
63135
- Object.defineProperty(__exports,"mountPanel",{enumerable:true,get:function(){return __m9["mountPanel"];}});
63136
- const __m10=__req("packages/dom/src/celledit.js");
63137
- Object.defineProperty(__exports,"CellEditController",{enumerable:true,get:function(){return __m10["CellEditController"];}});
63138
- const __m11=__req("packages/dom/src/editbar.js");
63139
- Object.defineProperty(__exports,"EditBar",{enumerable:true,get:function(){return __m11["EditBar"];}});
63140
- const __m12=__req("packages/dom/src/historybar.js");
63141
- Object.defineProperty(__exports,"HistoryBar",{enumerable:true,get:function(){return __m12["HistoryBar"];}});
63142
- Object.defineProperty(__exports,"HISTORY_CLS",{enumerable:true,get:function(){return __m12["HISTORY_CLS"];}});
63143
- const __m13=__req("packages/dom/src/diffpaint.js");
63144
- Object.defineProperty(__exports,"DiffPainter",{enumerable:true,get:function(){return __m13["DiffPainter"];}});
63145
- const __m14=__req("packages/dom/src/viewpicker.js");
63146
- Object.defineProperty(__exports,"ViewPicker",{enumerable:true,get:function(){return __m14["ViewPicker"];}});
63147
- Object.defineProperty(__exports,"VIEW_CLS",{enumerable:true,get:function(){return __m14["VIEW_CLS"];}});
63148
- Object.defineProperty(__exports,"summariseDiff",{enumerable:true,get:function(){return __m14["summariseDiff"];}});
63149
- const __m15=__req("packages/dom/src/promptbar.js");
63150
- Object.defineProperty(__exports,"PromptBar",{enumerable:true,get:function(){return __m15["PromptBar"];}});
63151
- Object.defineProperty(__exports,"PROMPT_CLASS",{enumerable:true,get:function(){return __m15["PROMPT_CLASS"];}});
63152
- const __m16=__req("packages/dom/src/cell/index.js");
63153
- Object.defineProperty(__exports,"createCellLayer",{enumerable:true,get:function(){return __m16["createCellLayer"];}});
63154
- Object.defineProperty(__exports,"compileTemplate",{enumerable:true,get:function(){return __m16["compileTemplate"];}});
63155
- Object.defineProperty(__exports,"compileVariant",{enumerable:true,get:function(){return __m16["compileVariant"];}});
63156
- Object.defineProperty(__exports,"checkVariant",{enumerable:true,get:function(){return __m16["checkVariant"];}});
63157
- Object.defineProperty(__exports,"VariantRegistry",{enumerable:true,get:function(){return __m16["VariantRegistry"];}});
63158
- Object.defineProperty(__exports,"BUILTIN_RENDERERS",{enumerable:true,get:function(){return __m16["BUILTIN_RENDERERS"];}});
63159
- Object.defineProperty(__exports,"BUILTIN_VARIANTS",{enumerable:true,get:function(){return __m16["BUILTIN_VARIANTS"];}});
63160
- Object.defineProperty(__exports,"BUILTIN_PIPES",{enumerable:true,get:function(){return __m16["BUILTIN_PIPES"];}});
63161
- const __m17=__req("packages/dom/src/editors/index.js");
63162
- Object.defineProperty(__exports,"editors",{enumerable:true,get:function(){return __m17["editors"];}});
63163
- Object.defineProperty(__exports,"createEditor",{enumerable:true,get:function(){return __m17["createEditor"];}});
63164
- Object.defineProperty(__exports,"editorFor",{enumerable:true,get:function(){return __m17["editorFor"];}});
63165
- Object.defineProperty(__exports,"BaseEditor",{enumerable:true,get:function(){return __m17["BaseEditor"];}});
63166
- const __m18=__req("packages/dom/src/filters/index.js");
63167
- Object.defineProperty(__exports,"filters",{enumerable:true,get:function(){return __m18["filters"];}});
63168
- Object.defineProperty(__exports,"createFilter",{enumerable:true,get:function(){return __m18["createFilter"];}});
63169
- Object.defineProperty(__exports,"filterFor",{enumerable:true,get:function(){return __m18["filterFor"];}});
63170
- Object.defineProperty(__exports,"parseExpression",{enumerable:true,get:function(){return __m18["parseExpression"];}});
63171
- const __m19=__req("packages/dom/src/ui/index.js");
63172
- Object.defineProperty(__exports,"StatusBar",{enumerable:true,get:function(){return __m19["StatusBar"];}});
63173
- Object.defineProperty(__exports,"ContextMenu",{enumerable:true,get:function(){return __m19["ContextMenu"];}});
63174
- Object.defineProperty(__exports,"ToolPanel",{enumerable:true,get:function(){return __m19["ToolPanel"];}});
63175
- Object.defineProperty(__exports,"TooltipManager",{enumerable:true,get:function(){return __m19["TooltipManager"];}});
63176
- Object.defineProperty(__exports,"Pagination",{enumerable:true,get:function(){return __m19["Pagination"];}});
63177
- Object.defineProperty(__exports,"OverlayLayer",{enumerable:true,get:function(){return __m19["OverlayLayer"];}});
63178
- const __m20=__req("packages/core/src/registry/licence.js");
63179
- Object.defineProperty(__exports,"setLicense",{enumerable:true,get:function(){return __m20["setLicence"];}});
63180
- Object.defineProperty(__exports,"licenseInfo",{enumerable:true,get:function(){return __m20["licenceInfo"];}});
63181
- Object.defineProperty(__exports,"licenseState",{enumerable:true,get:function(){return __m20["licenceState"];}});
63785
+ const __m6=__req("packages/dom/src/renderer/index.js");
63786
+ Object.defineProperty(__exports,"DomRenderer",{enumerable:true,get:function(){return __m6["DomRenderer"];}});
63787
+ const __m7=__req("packages/dom/src/filtermenu.js");
63788
+ Object.defineProperty(__exports,"FilterMenu",{enumerable:true,get:function(){return __m7["FilterMenu"];}});
63789
+ Object.defineProperty(__exports,"mergeColumnFilter",{enumerable:true,get:function(){return __m7["mergeColumnFilter"];}});
63790
+ Object.defineProperty(__exports,"branchFor",{enumerable:true,get:function(){return __m7["branchFor"];}});
63791
+ const __m8=__req("packages/dom/src/columnmenu.js");
63792
+ Object.defineProperty(__exports,"ColumnMenu",{enumerable:true,get:function(){return __m8["ColumnMenu"];}});
63793
+ Object.defineProperty(__exports,"columnMenuItems",{enumerable:true,get:function(){return __m8["columnMenuItems"];}});
63794
+ Object.defineProperty(__exports,"cellMenuItems",{enumerable:true,get:function(){return __m8["cellMenuItems"];}});
63795
+ Object.defineProperty(__exports,"autoGroupMenuItems",{enumerable:true,get:function(){return __m8["autoGroupMenuItems"];}});
63796
+ const __m9=__req("packages/dom/src/alignedgrids.js");
63797
+ Object.defineProperty(__exports,"AlignedGrids",{enumerable:true,get:function(){return __m9["AlignedGrids"];}});
63798
+ Object.defineProperty(__exports,"alignGrids",{enumerable:true,get:function(){return __m9["alignGrids"];}});
63799
+ Object.defineProperty(__exports,"layoutState",{enumerable:true,get:function(){return __m9["layoutState"];}});
63800
+ const __m10=__req("packages/dom/src/toolpanelmount.js");
63801
+ Object.defineProperty(__exports,"ToolPanelDock",{enumerable:true,get:function(){return __m10["ToolPanelDock"];}});
63802
+ Object.defineProperty(__exports,"panelHost",{enumerable:true,get:function(){return __m10["panelHost"];}});
63803
+ Object.defineProperty(__exports,"mountPanel",{enumerable:true,get:function(){return __m10["mountPanel"];}});
63804
+ const __m11=__req("packages/dom/src/celledit.js");
63805
+ Object.defineProperty(__exports,"CellEditController",{enumerable:true,get:function(){return __m11["CellEditController"];}});
63806
+ const __m12=__req("packages/dom/src/editbar.js");
63807
+ Object.defineProperty(__exports,"EditBar",{enumerable:true,get:function(){return __m12["EditBar"];}});
63808
+ const __m13=__req("packages/dom/src/historybar.js");
63809
+ Object.defineProperty(__exports,"HistoryBar",{enumerable:true,get:function(){return __m13["HistoryBar"];}});
63810
+ Object.defineProperty(__exports,"HISTORY_CLS",{enumerable:true,get:function(){return __m13["HISTORY_CLS"];}});
63811
+ const __m14=__req("packages/dom/src/diffpaint.js");
63812
+ Object.defineProperty(__exports,"DiffPainter",{enumerable:true,get:function(){return __m14["DiffPainter"];}});
63813
+ const __m15=__req("packages/dom/src/viewpicker.js");
63814
+ Object.defineProperty(__exports,"ViewPicker",{enumerable:true,get:function(){return __m15["ViewPicker"];}});
63815
+ Object.defineProperty(__exports,"VIEW_CLS",{enumerable:true,get:function(){return __m15["VIEW_CLS"];}});
63816
+ Object.defineProperty(__exports,"summariseDiff",{enumerable:true,get:function(){return __m15["summariseDiff"];}});
63817
+ const __m16=__req("packages/dom/src/promptbar.js");
63818
+ Object.defineProperty(__exports,"PromptBar",{enumerable:true,get:function(){return __m16["PromptBar"];}});
63819
+ Object.defineProperty(__exports,"PROMPT_CLASS",{enumerable:true,get:function(){return __m16["PROMPT_CLASS"];}});
63820
+ const __m17=__req("packages/dom/src/cell/index.js");
63821
+ Object.defineProperty(__exports,"createCellLayer",{enumerable:true,get:function(){return __m17["createCellLayer"];}});
63822
+ Object.defineProperty(__exports,"compileTemplate",{enumerable:true,get:function(){return __m17["compileTemplate"];}});
63823
+ Object.defineProperty(__exports,"compileVariant",{enumerable:true,get:function(){return __m17["compileVariant"];}});
63824
+ Object.defineProperty(__exports,"checkVariant",{enumerable:true,get:function(){return __m17["checkVariant"];}});
63825
+ Object.defineProperty(__exports,"VariantRegistry",{enumerable:true,get:function(){return __m17["VariantRegistry"];}});
63826
+ Object.defineProperty(__exports,"BUILTIN_RENDERERS",{enumerable:true,get:function(){return __m17["BUILTIN_RENDERERS"];}});
63827
+ Object.defineProperty(__exports,"BUILTIN_VARIANTS",{enumerable:true,get:function(){return __m17["BUILTIN_VARIANTS"];}});
63828
+ Object.defineProperty(__exports,"BUILTIN_PIPES",{enumerable:true,get:function(){return __m17["BUILTIN_PIPES"];}});
63829
+ const __m18=__req("packages/dom/src/editors/index.js");
63830
+ Object.defineProperty(__exports,"editors",{enumerable:true,get:function(){return __m18["editors"];}});
63831
+ Object.defineProperty(__exports,"createEditor",{enumerable:true,get:function(){return __m18["createEditor"];}});
63832
+ Object.defineProperty(__exports,"editorFor",{enumerable:true,get:function(){return __m18["editorFor"];}});
63833
+ Object.defineProperty(__exports,"BaseEditor",{enumerable:true,get:function(){return __m18["BaseEditor"];}});
63834
+ const __m19=__req("packages/dom/src/filters/index.js");
63835
+ Object.defineProperty(__exports,"filters",{enumerable:true,get:function(){return __m19["filters"];}});
63836
+ Object.defineProperty(__exports,"createFilter",{enumerable:true,get:function(){return __m19["createFilter"];}});
63837
+ Object.defineProperty(__exports,"filterFor",{enumerable:true,get:function(){return __m19["filterFor"];}});
63838
+ Object.defineProperty(__exports,"parseExpression",{enumerable:true,get:function(){return __m19["parseExpression"];}});
63839
+ const __m20=__req("packages/dom/src/ui/index.js");
63840
+ Object.defineProperty(__exports,"StatusBar",{enumerable:true,get:function(){return __m20["StatusBar"];}});
63841
+ Object.defineProperty(__exports,"ContextMenu",{enumerable:true,get:function(){return __m20["ContextMenu"];}});
63842
+ Object.defineProperty(__exports,"ToolPanel",{enumerable:true,get:function(){return __m20["ToolPanel"];}});
63843
+ Object.defineProperty(__exports,"TooltipManager",{enumerable:true,get:function(){return __m20["TooltipManager"];}});
63844
+ Object.defineProperty(__exports,"Pagination",{enumerable:true,get:function(){return __m20["Pagination"];}});
63845
+ Object.defineProperty(__exports,"OverlayLayer",{enumerable:true,get:function(){return __m20["OverlayLayer"];}});
63846
+ const __m21=__req("packages/core/src/registry/licence.js");
63847
+ Object.defineProperty(__exports,"setLicense",{enumerable:true,get:function(){return __m21["setLicence"];}});
63848
+ Object.defineProperty(__exports,"licenseInfo",{enumerable:true,get:function(){return __m21["licenceInfo"];}});
63849
+ Object.defineProperty(__exports,"licenseState",{enumerable:true,get:function(){return __m21["licenceState"];}});
63182
63850
  const LatticeGrid={
63183
63851
  createGrid,
63184
63852
  createHeadlessGrid,
@@ -63200,6 +63868,9 @@ const __entry=__req("packages/dom/src/index.js");
63200
63868
  export const
63201
63869
  createGrid=__entry.createGrid,
63202
63870
  gridElementsWithin=__entry.gridElementsWithin,
63871
+ createStat=__entry.createStat,
63872
+ deltaOf=__entry.deltaOf,
63873
+ toneOf=__entry.toneOf,
63203
63874
  readTable=__entry.readTable,
63204
63875
  hydrateTable=__entry.hydrateTable,
63205
63876
  autoInit=__entry.autoInit,
@@ -63235,6 +63906,8 @@ RADIX_PRESETS=__entry.RADIX_PRESETS,
63235
63906
  parseRadix=__entry.parseRadix,
63236
63907
  formatRadix=__entry.formatRadix,
63237
63908
  createUnitType=__entry.createUnitType,
63909
+ registerUnitSystem=__entry.registerUnitSystem,
63910
+ defineUnit=__entry.defineUnit,
63238
63911
  UNIT_SYSTEMS=__entry.UNIT_SYSTEMS,
63239
63912
  parseUnit=__entry.parseUnit,
63240
63913
  formatUnit=__entry.formatUnit,