@toclocoinc/lattice-grid 1.16.0 → 1.18.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.16.0, core + DOM renderer
2
+ * Lattice Grid 1.18.0, core + DOM renderer
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -49,9 +49,10 @@ Object.defineProperty(__exports,"now",{enumerable:true,get:function(){return now
49
49
  Object.defineProperty(__exports,"nextFrame",{enumerable:true,get:function(){return nextFrame;}});
50
50
  Object.defineProperty(__exports,"cancelFrame",{enumerable:true,get:function(){return cancelFrame;}});
51
51
  Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){return frameBatched;}});
52
+ Object.defineProperty(__exports,"settleDebounce",{enumerable:true,get:function(){return settleDebounce;}});
52
53
  Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
53
54
  Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
54
- const STAMPED_VERSION="1.16.0";
55
+ const STAMPED_VERSION="1.18.0";
55
56
  async function resolveVersion(){
56
57
  if(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;
57
58
  try{
@@ -68,7 +69,7 @@ return JSON.parse(text).version||STAMPED_VERSION;
68
69
  return STAMPED_VERSION;
69
70
  }
70
71
  }
71
- const VERSION="1.16.0";
72
+ const VERSION="1.18.0";
72
73
  const warned=new Set();
73
74
  const reported=[];
74
75
  const REPORT_LIMIT=500;
@@ -362,6 +363,47 @@ run();
362
363
  };
363
364
  return wrapped;
364
365
  }
366
+ function settleDebounce(fn,waitMs){
367
+ let timer=null;
368
+ let held=null;
369
+ const trailing=()=>{
370
+ timer=null;
371
+ if(held===null)return;
372
+ const args=held;
373
+ held=null;
374
+ fn(...args);
375
+ arm();
376
+ };
377
+ const arm=()=>{
378
+ timer=setTimeout(trailing,waitMs);
379
+ if(typeof timer?.unref==='function')timer.unref();
380
+ };
381
+ const wrapped=(...args)=>{
382
+ if(timer===null){
383
+ fn(...args);
384
+ arm();
385
+ }else{
386
+ held=args;
387
+ clearTimeout(timer);
388
+ arm();
389
+ }
390
+ };
391
+ wrapped.flush=()=>{
392
+ if(timer!==null)clearTimeout(timer);
393
+ timer=null;
394
+ if(held===null)return;
395
+ const args=held;
396
+ held=null;
397
+ fn(...args);
398
+ };
399
+ wrapped.cancel=()=>{
400
+ if(timer!==null)clearTimeout(timer);
401
+ timer=null;
402
+ held=null;
403
+ };
404
+ wrapped.pending=()=>timer!==null||held!==null;
405
+ return wrapped;
406
+ }
365
407
  function whenIdle(fn,timeout=50){
366
408
  if(typeof requestIdleCallback==='function'){
367
409
  return requestIdleCallback(fn,{timeout});
@@ -3656,6 +3698,9 @@ other:'Paste preview: {changes} cell changes, {rejected} rejected. Review, then
3656
3698
  'menu.totalColumn':'Total this column',
3657
3699
  'menu.aggregate':'Aggregate',
3658
3700
  'menu.aggregateNone':'None',
3701
+ 'menu.aggregateGroup':'Group subtotals',
3702
+ 'menu.aggregateGrand':'Grand total',
3703
+ 'menu.aggregateSame':'Same as total',
3659
3704
  'menu.redactColumn':'Redact column',
3660
3705
  'menu.stopRedacting':'Stop redacting',
3661
3706
  'menu.stopRedactingAll':'Stop redacting everything',
@@ -4550,6 +4595,28 @@ resolved={index,base,binary:cfg.binary===true};
4550
4595
  if(typeof cfg==='object'&&cfg!==null)configs.set(cfg,resolved);
4551
4596
  return resolved;
4552
4597
  }
4598
+ const compounds=new WeakMap();
4599
+ function resolveCompound(cfg,ctx){
4600
+ if(!cfg||!ctx||!Array.isArray(cfg.compound)||cfg.compound.length===0)return null;
4601
+ const memo=compounds.get(cfg);
4602
+ if(memo!==undefined)return memo;
4603
+ const seen=new Set();
4604
+ const units=[];
4605
+ for(const symbol of cfg.compound){
4606
+ const u=findUnit(cfg.system||'data',symbol);
4607
+ if(!u){
4608
+ warnOnce(`unit:compound:${cfg.system}:${symbol}`,`unknown compound unit "${symbol}" in system "${cfg.system||'data'}"; ignoring it`);
4609
+ continue;
4610
+ }
4611
+ if(seen.has(u.symbol))continue;
4612
+ seen.add(u.symbol);
4613
+ units.push(u);
4614
+ }
4615
+ units.sort((a,b)=>b.factor-a.factor);
4616
+ const out=units.length>=2?units:null;
4617
+ compounds.set(cfg,out);
4618
+ return out;
4619
+ }
4553
4620
  function convert(value,from,to){
4554
4621
  if(from===to||from.factor===to.factor)return value;
4555
4622
  return(value*from.factor)/to.factor;
@@ -4603,6 +4670,34 @@ const ladder=ladderOf(index,binary);
4603
4670
  const onLadder=candidates.filter((u)=>ladder.includes(u));
4604
4671
  return onLadder.length===1?onLadder[0]:null;
4605
4672
  }
4673
+ function parseCompound(s,ctx,parts,opts){
4674
+ let rest=s;
4675
+ let total=0;
4676
+ let read=false;
4677
+ let bare=false;
4678
+ while(rest!==''){
4679
+ const head=NUMBER_HEAD.exec(rest)[0];
4680
+ if(head==='')return null;
4681
+ const n=parseLocaleNumber(head,opts&&opts.locale);
4682
+ if(n===null)return null;
4683
+ rest=rest.slice(head.length).trim();
4684
+ const nextNum=rest.search(/[+-]?[\d]/);
4685
+ const token=(nextNum>=0?rest.slice(0,nextNum):rest).trim();
4686
+ rest=nextNum>=0?rest.slice(nextNum).trim():'';
4687
+ if(token===''){
4688
+ if(read)return null;
4689
+ bare=true;
4690
+ total+=convert(n,parts[0],ctx.base);
4691
+ }else{
4692
+ const from=resolveToken(token,ctx.index,ctx.binary);
4693
+ if(!from)return null;
4694
+ total+=convert(n,from,ctx.base);
4695
+ }
4696
+ read=true;
4697
+ if(bare&&rest!=='')return null;
4698
+ }
4699
+ return read?total:null;
4700
+ }
4606
4701
  function parseUnit(text,opts){
4607
4702
  if(isNil(text))return null;
4608
4703
  if(typeof text==='number')return Number.isFinite(text)?text:null;
@@ -4612,6 +4707,13 @@ let s=String(text).trim();
4612
4707
  if(s==='')return null;
4613
4708
  let negative=false;
4614
4709
  if(s.startsWith('(')&&s.endsWith(')')){negative=true;s=s.slice(1,-1).trim();}
4710
+ const parts=resolveCompound(opts,ctx);
4711
+ if(parts){
4712
+ if(s.startsWith('-')){negative=true;s=s.slice(1).trim();}
4713
+ const value=parseCompound(s,ctx,parts,opts);
4714
+ if(value===null)return null;
4715
+ return negative?-value:value;
4716
+ }
4615
4717
  let leading=null;
4616
4718
  const front=LEADING_SYMBOL.exec(s);
4617
4719
  if(front&&front[0]){
@@ -4683,6 +4785,30 @@ if(loose&&loose!==AMBIGUOUS)return loose;
4683
4785
  warnOnce(`unit:display:${symbol}`,`unknown display unit "${symbol}"; rendering in ${ctx.base.symbol}`);
4684
4786
  return ctx.base;
4685
4787
  }
4788
+ function formatCompound(value,ctx,parts,cfg){
4789
+ const negative=value<0;
4790
+ let remaining=Math.abs(value)*ctx.base.factor;
4791
+ const min=typeof cfg.decimals==='number'?cfg.decimals:(cfg.minDecimals??0);
4792
+ const max=typeof cfg.decimals==='number'?cfg.decimals:(cfg.maxDecimals??Math.max(min,2));
4793
+ const gap=cfg.space??' ';
4794
+ const pieces=[];
4795
+ for(let i=0;i<parts.length;i++){
4796
+ const u=parts[i];
4797
+ const last=i===parts.length-1;
4798
+ let count=last?remaining/u.factor:Math.floor(remaining/u.factor);
4799
+ remaining-=count*u.factor;
4800
+ if(last){
4801
+ const p=10**max;
4802
+ count=Math.round(count*p)/p+0;
4803
+ }
4804
+ const fmt=last
4805
+ ?numberFormat(cfg.locale,min,max,cfg.group!==false)
4806
+ :numberFormat(cfg.locale,0,0,cfg.group!==false);
4807
+ pieces.push(`${fmt.format(count)}${gap}${u.symbol}`);
4808
+ }
4809
+ const body=pieces.join(' ');
4810
+ return negative?`-${body}`:body;
4811
+ }
4686
4812
  function formatUnit(value,opts){
4687
4813
  const cfg=opts||{};
4688
4814
  const blank=cfg.nullDisplay??'';
@@ -4691,6 +4817,8 @@ const n=typeof value==='number'?value:Number(value);
4691
4817
  if(!Number.isFinite(n))return blank;
4692
4818
  const ctx=resolve(cfg);
4693
4819
  if(!ctx)return String(n);
4820
+ const parts=resolveCompound(cfg,ctx);
4821
+ if(parts)return formatCompound(n,ctx,parts,cfg);
4694
4822
  const figures=typeof cfg.significantFigures==='number'&&cfg.significantFigures>0
4695
4823
  ?cfg.significantFigures:0;
4696
4824
  const rounded=figures?roundToSignificant(n,figures):n;
@@ -6891,6 +7019,12 @@ filter:{...(m.filter||{})},
6891
7019
  group:{enabled:false,index:-1,explode:false,...(m.group||{})},
6892
7020
  pivot:{enabled:false,index:-1,...(m.pivot||{})},
6893
7021
  total:this.#resolveTotal(m.total,type,def.id||def.field||'(unnamed)'),
7022
+ groupTotal:m.groupTotal===undefined
7023
+ ?null
7024
+ :this.#resolveTotal(m.groupTotal,type,def.id||def.field||'(unnamed)'),
7025
+ grandTotal:m.grandTotal===undefined
7026
+ ?null
7027
+ :this.#resolveTotal(m.grandTotal,type,def.id||def.field||'(unnamed)'),
6894
7028
  tags:normaliseTags(m.tags),
6895
7029
  typeOptions:m.typeOptions??null,
6896
7030
  ...(isObject(m[typeName])?{[typeName]:m[typeName]}:{}),
@@ -7095,6 +7229,8 @@ sortIndex:c.sort.direction?(c.sort.order??0):null,
7095
7229
  groupIndex:c.group.enabled?(c.group.index??0):null,
7096
7230
  pivotIndex:c.pivot.enabled?(c.pivot.index??0):null,
7097
7231
  total:typeof c.total==='string'?c.total:null,
7232
+ groupTotal:typeof c.groupTotal==='string'?c.groupTotal:undefined,
7233
+ grandTotal:typeof c.grandTotal==='string'?c.grandTotal:undefined,
7098
7234
  }));
7099
7235
  }
7100
7236
  applyState(state){
@@ -7114,6 +7250,8 @@ if(entry.sortIndex!=null)column.sort.order=entry.sortIndex;
7114
7250
  if(entry.groupIndex!=null){column.group.enabled=true;column.group.index=entry.groupIndex;}
7115
7251
  if(entry.pivotIndex!=null){column.pivot.enabled=true;column.pivot.index=entry.pivotIndex;}
7116
7252
  if(entry.total!==undefined)column.total=entry.total;
7253
+ if(entry.groupTotal!==undefined)column.groupTotal=entry.groupTotal;
7254
+ if(entry.grandTotal!==undefined)column.grandTotal=entry.grandTotal;
7117
7255
  report.applied.push(entry.id);
7118
7256
  }
7119
7257
  const ids=order||list.map((e)=>e&&e.id).filter(Boolean);
@@ -8163,7 +8301,7 @@ varianceP:'rescan',
8163
8301
  stddev:'rescan',
8164
8302
  stddevP:'rescan',
8165
8303
  sumSquares:'rescan',
8166
- weightedAvg:'maintained',
8304
+ weightedAvg:'rescan',
8167
8305
  median:'rescan',
8168
8306
  p25:'rescan',
8169
8307
  p75:'rescan',
@@ -10219,6 +10357,548 @@ this.#fill=w;
10219
10357
  }
10220
10358
  }
10221
10359
  });
10360
+ __def("packages/core/src/compute/sort.js",function(__exports,__req){
10361
+ 'use strict';
10362
+ Object.defineProperty(__exports,"radixSortFloat64",{enumerable:true,get:function(){return radixSortFloat64;}});
10363
+ Object.defineProperty(__exports,"radixSortInt32",{enumerable:true,get:function(){return radixSortInt32;}});
10364
+ Object.defineProperty(__exports,"rankSortDictionary",{enumerable:true,get:function(){return rankSortDictionary;}});
10365
+ Object.defineProperty(__exports,"mergeSortComparator",{enumerable:true,get:function(){return mergeSortComparator;}});
10366
+ Object.defineProperty(__exports,"rankSortStrings",{enumerable:true,get:function(){return rankSortStrings;}});
10367
+ Object.defineProperty(__exports,"collateStringRanks",{enumerable:true,get:function(){return collateStringRanks;}});
10368
+ Object.defineProperty(__exports,"sortColumn",{enumerable:true,get:function(){return sortColumn;}});
10369
+ Object.defineProperty(__exports,"sortMulti",{enumerable:true,get:function(){return sortMulti;}});
10370
+ const __m0=__req("packages/core/src/compute/handle.js");
10371
+ const bitReader=__m0["bitReader"];
10372
+ const dictRanks=__m0["dictRanks"];
10373
+ const dictSize=__m0["dictSize"];
10374
+ const identity=__m0["identity"];
10375
+ const isMissing=__m0["isMissing"];
10376
+ const presenceReader=__m0["presenceReader"];
10377
+ const rowCount=__m0["rowCount"];
10378
+ const valueComparator=__m0["valueComparator"];
10379
+ const valueReader=__m0["valueReader"];
10380
+ const EMPTY_INDICES=new Uint32Array(0);
10381
+ const SCRATCH=new ArrayBuffer(8);
10382
+ const SCRATCH_F64=new Float64Array(SCRATCH);
10383
+ const SCRATCH_U32=new Uint32Array(SCRATCH);
10384
+ const HI=(()=>{
10385
+ SCRATCH_F64[0]=-1;
10386
+ return(SCRATCH_U32[1]&0x80000000)!==0?1:0;
10387
+ })();
10388
+ const LO=HI===1?0:1;
10389
+ function transformDouble(value,out){
10390
+ SCRATCH_F64[0]=value;
10391
+ let hi=SCRATCH_U32[HI];
10392
+ let lo=SCRATCH_U32[LO];
10393
+ if((hi&0x80000000)!==0){
10394
+ hi=~hi>>>0;
10395
+ lo=~lo>>>0;
10396
+ }else{
10397
+ hi=(hi^0x80000000)>>>0;
10398
+ }
10399
+ out[0]=lo;
10400
+ out[1]=hi;
10401
+ }
10402
+ function radixLsd64(idx,lo,hi,n){
10403
+ if(n<2)return idx;
10404
+ const hist=new Uint32Array(256*8);
10405
+ for(let i=0;i<n;i++){
10406
+ const l=lo[i];
10407
+ const h=hi[i];
10408
+ hist[l&0xff]++;
10409
+ hist[256+((l>>>8)&0xff)]++;
10410
+ hist[512+((l>>>16)&0xff)]++;
10411
+ hist[768+((l>>>24)&0xff)]++;
10412
+ hist[1024+(h&0xff)]++;
10413
+ hist[1280+((h>>>8)&0xff)]++;
10414
+ hist[1536+((h>>>16)&0xff)]++;
10415
+ hist[1792+((h>>>24)&0xff)]++;
10416
+ }
10417
+ let srcIdx=idx;
10418
+ let srcLo=lo;
10419
+ let srcHi=hi;
10420
+ let dstIdx=new Uint32Array(n);
10421
+ let dstLo=new Uint32Array(n);
10422
+ let dstHi=new Uint32Array(n);
10423
+ const offset=new Uint32Array(256);
10424
+ for(let pass=0;pass<8;pass++){
10425
+ const base=pass<<8;
10426
+ const shift=(pass&3)<<3;
10427
+ const useHi=pass>=4;
10428
+ let skip=false;
10429
+ for(let b=0;b<256;b++){
10430
+ if(hist[base+b]===n){skip=true;break;}
10431
+ }
10432
+ if(skip)continue;
10433
+ let sum=0;
10434
+ for(let b=0;b<256;b++){
10435
+ offset[b]=sum;
10436
+ sum+=hist[base+b];
10437
+ }
10438
+ for(let i=0;i<n;i++){
10439
+ const l=srcLo[i];
10440
+ const h=srcHi[i];
10441
+ const digit=((useHi?h:l)>>>shift)&0xff;
10442
+ const p=offset[digit]++;
10443
+ dstIdx[p]=srcIdx[i];
10444
+ dstLo[p]=l;
10445
+ dstHi[p]=h;
10446
+ }
10447
+ let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
10448
+ t=srcLo;srcLo=dstLo;dstLo=t;
10449
+ t=srcHi;srcHi=dstHi;dstHi=t;
10450
+ }
10451
+ return srcIdx;
10452
+ }
10453
+ function radixLsd32(idx,keys,n){
10454
+ if(n<2)return idx;
10455
+ const hist=new Uint32Array(256*4);
10456
+ for(let i=0;i<n;i++){
10457
+ const k=keys[i];
10458
+ hist[k&0xff]++;
10459
+ hist[256+((k>>>8)&0xff)]++;
10460
+ hist[512+((k>>>16)&0xff)]++;
10461
+ hist[768+((k>>>24)&0xff)]++;
10462
+ }
10463
+ let srcIdx=idx;
10464
+ let srcKeys=keys;
10465
+ let dstIdx=new Uint32Array(n);
10466
+ let dstKeys=new Uint32Array(n);
10467
+ const offset=new Uint32Array(256);
10468
+ for(let pass=0;pass<4;pass++){
10469
+ const base=pass<<8;
10470
+ const shift=pass<<3;
10471
+ let skip=false;
10472
+ for(let b=0;b<256;b++){
10473
+ if(hist[base+b]===n){skip=true;break;}
10474
+ }
10475
+ if(skip)continue;
10476
+ let sum=0;
10477
+ for(let b=0;b<256;b++){
10478
+ offset[b]=sum;
10479
+ sum+=hist[base+b];
10480
+ }
10481
+ for(let i=0;i<n;i++){
10482
+ const k=srcKeys[i];
10483
+ const p=offset[(k>>>shift)&0xff]++;
10484
+ dstIdx[p]=srcIdx[i];
10485
+ dstKeys[p]=k;
10486
+ }
10487
+ let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
10488
+ t=srcKeys;srcKeys=dstKeys;dstKeys=t;
10489
+ }
10490
+ return srcIdx;
10491
+ }
10492
+ function countingSort(idx,keys,n,radix){
10493
+ const counts=new Uint32Array(radix+1);
10494
+ for(let i=0;i<n;i++)counts[keys[i]]++;
10495
+ let sum=0;
10496
+ for(let k=0;k<=radix;k++){
10497
+ const c=counts[k];
10498
+ counts[k]=sum;
10499
+ sum+=c;
10500
+ }
10501
+ const out=new Uint32Array(n);
10502
+ for(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];
10503
+ return out;
10504
+ }
10505
+ function sortUint32Keys(idx,keys,n,radix){
10506
+ if(n<2)return idx;
10507
+ if(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);
10508
+ return radixLsd32(idx,keys,n);
10509
+ }
10510
+ function exact(buffer,n){
10511
+ if(buffer.length===n&&buffer.byteOffset===0)return buffer;
10512
+ return Uint32Array.prototype.slice.call(buffer,0,n);
10513
+ }
10514
+ function radixSortFloat64(values,order,descending=false){
10515
+ const src=order||identity(values.length);
10516
+ const n=src.length;
10517
+ if(n<2)return Uint32Array.from(src);
10518
+ const idx=new Uint32Array(n);
10519
+ const lo=new Uint32Array(n);
10520
+ const hi=new Uint32Array(n);
10521
+ const nans=new Uint32Array(n);
10522
+ const pair=new Uint32Array(2);
10523
+ let m=0;
10524
+ let nanCount=0;
10525
+ for(let i=0;i<n;i++){
10526
+ const row=src[i];
10527
+ const v=values[row];
10528
+ if(Number.isNaN(v)){nans[nanCount++]=row;continue;}
10529
+ transformDouble(v,pair);
10530
+ if(descending){
10531
+ lo[m]=~pair[0]>>>0;
10532
+ hi[m]=~pair[1]>>>0;
10533
+ }else{
10534
+ lo[m]=pair[0];
10535
+ hi[m]=pair[1];
10536
+ }
10537
+ idx[m++]=row;
10538
+ }
10539
+ const sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);
10540
+ if(nanCount===0)return exact(sorted,m);
10541
+ const out=new Uint32Array(n);
10542
+ out.set(sorted.subarray(0,m),0);
10543
+ out.set(nans.subarray(0,nanCount),m);
10544
+ return out;
10545
+ }
10546
+ function radixSortInt32(values,order,descending=false){
10547
+ const src=order||identity(values.length);
10548
+ const n=src.length;
10549
+ if(n<2)return Uint32Array.from(src);
10550
+ const idx=Uint32Array.from(src);
10551
+ const keys=new Uint32Array(n);
10552
+ for(let i=0;i<n;i++){
10553
+ const k=(values[idx[i]]^0x80000000)>>>0;
10554
+ keys[i]=descending?(~k>>>0):k;
10555
+ }
10556
+ return exact(radixLsd32(idx,keys,n),n);
10557
+ }
10558
+ function rankSortDictionary(handle,order,opts={}){
10559
+ const src=order||identity(rowCount(handle,opts));
10560
+ const n=src.length;
10561
+ if(n<2)return Uint32Array.from(src);
10562
+ const ranks=dictRanks(handle.dict,opts.locale);
10563
+ const codes=handle.values;
10564
+ const present=presenceReader(handle);
10565
+ const size=Math.max(dictSize(handle.dict),ranks.length);
10566
+ const absentRank=size;
10567
+ const idx=Uint32Array.from(src);
10568
+ const keys=new Uint32Array(n);
10569
+ const descending=!!opts.descending;
10570
+ for(let i=0;i<n;i++){
10571
+ const row=idx[i];
10572
+ let rank=present&&present(row)===0?absentRank:ranks[codes[row]];
10573
+ if(rank===undefined)rank=absentRank;
10574
+ keys[i]=descending?absentRank-rank:rank;
10575
+ }
10576
+ return exact(sortUint32Keys(idx,keys,n,size+1),n);
10577
+ }
10578
+ function mergeSortComparator(values,order,compare){
10579
+ const n=order.length;
10580
+ let src=Uint32Array.from(order);
10581
+ if(n<2)return src;
10582
+ let dst=new Uint32Array(n);
10583
+ for(let width=1;width<n;width<<=1){
10584
+ for(let start=0;start<n;start+=width<<1){
10585
+ const mid=Math.min(start+width,n);
10586
+ const end=Math.min(start+(width<<1),n);
10587
+ let i=start;
10588
+ let j=mid;
10589
+ let k=start;
10590
+ while(i<mid&&j<end){
10591
+ dst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];
10592
+ }
10593
+ while(i<mid)dst[k++]=src[i++];
10594
+ while(j<end)dst[k++]=src[j++];
10595
+ }
10596
+ const t=src;src=dst;dst=t;
10597
+ }
10598
+ return src;
10599
+ }
10600
+ function sortBitsetColumn(handle,idx,descending){
10601
+ const bit=bitReader(handle.values);
10602
+ const n=idx.length;
10603
+ const out=new Uint32Array(n);
10604
+ const first=descending?1:0;
10605
+ let k=0;
10606
+ for(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];
10607
+ for(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];
10608
+ return out;
10609
+ }
10610
+ function indexableValues(handle,idx){
10611
+ const values=handle.values;
10612
+ const kind=handle.kind;
10613
+ const direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));
10614
+ if(direct&&!handle.presence)return values;
10615
+ const reader=valueReader(handle);
10616
+ const materialised=new Array(rowCount(handle)||0);
10617
+ for(let i=0;i<idx.length;i++){
10618
+ const row=idx[i];
10619
+ materialised[row]=reader(row);
10620
+ }
10621
+ return materialised;
10622
+ }
10623
+ function allStrings(values,idx){
10624
+ for(let i=0;i<idx.length;i++){
10625
+ if(typeof values[idx[i]]!=='string')return false;
10626
+ }
10627
+ return true;
10628
+ }
10629
+ function rankSortStrings(idx,codes,ranks,d,descending){
10630
+ const n=idx.length;
10631
+ const idxOut=Uint32Array.from(idx);
10632
+ if(n<2||d<1)return idxOut;
10633
+ const keys=new Uint32Array(n);
10634
+ const top=d-1;
10635
+ for(let i=0;i<n;i++){
10636
+ const rank=ranks[codes[i]];
10637
+ keys[i]=descending?top-rank:rank;
10638
+ }
10639
+ return exact(sortUint32Keys(idxOut,keys,n,d),n);
10640
+ }
10641
+ function collateStringRanks(table,d,locale){
10642
+ const compare=valueComparator(locale);
10643
+ const order=new Array(d);
10644
+ for(let i=0;i<d;i++)order[i]=i;
10645
+ order.sort((a,b)=>compare(table[a],table[b])||a-b);
10646
+ const ranks=new Uint32Array(d);
10647
+ for(let r=0;r<d;r++)ranks[order[r]]=r;
10648
+ return ranks;
10649
+ }
10650
+ function keyedSortStrings(values,idx,opts){
10651
+ const n=idx.length;
10652
+ const codeOf=new Map();
10653
+ const table=[];
10654
+ const codes=new Uint32Array(n);
10655
+ for(let i=0;i<n;i++){
10656
+ const v=values[idx[i]];
10657
+ let c=codeOf.get(v);
10658
+ if(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}
10659
+ codes[i]=c;
10660
+ }
10661
+ const d=table.length;
10662
+ const ranks=collateStringRanks(table,d,opts.locale);
10663
+ return rankSortStrings(idx,codes,ranks,d,!!opts.descending);
10664
+ }
10665
+ function sortByComparator(handle,idx,opts){
10666
+ const values=indexableValues(handle,idx);
10667
+ if(idx.length>=2&&allStrings(values,idx)){
10668
+ const index=handle.stringRank;
10669
+ if(index&&index.version===handle.version&&index.usable(idx,values,opts.locale)){
10670
+ return index.sort(idx,opts);
10671
+ }
10672
+ return keyedSortStrings(values,idx,opts);
10673
+ }
10674
+ const base=valueComparator(opts.locale);
10675
+ const compare=opts.descending?(a,b)=>base(b,a):base;
10676
+ return mergeSortComparator(values,idx,compare);
10677
+ }
10678
+ function sortByCompare(handle,idx,opts){
10679
+ const values=indexableValues(handle,idx);
10680
+ const user=opts.compare;
10681
+ const descending=!!opts.descending;
10682
+ const compare=descending
10683
+ ?(a,b)=>-user(a,b,undefined,undefined,true)
10684
+ :(a,b)=>user(a,b,undefined,undefined,false);
10685
+ return mergeSortComparator(values,idx,compare);
10686
+ }
10687
+ function partitionPresent(handle,idx){
10688
+ const n=idx.length;
10689
+ const present=presenceReader(handle);
10690
+ const values=handle.values;
10691
+ const checkNaN=handle.kind==='float64'&&!!values;
10692
+ const looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;
10693
+ if(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};
10694
+ const keep=new Uint32Array(n);
10695
+ const drop=new Uint32Array(n);
10696
+ let p=0;
10697
+ let a=0;
10698
+ if(present&&checkNaN){
10699
+ for(let i=0;i<n;i++){
10700
+ const row=idx[i];
10701
+ if(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
10702
+ }
10703
+ }else if(checkNaN&&!present){
10704
+ for(let i=0;i<n;i++){
10705
+ const row=idx[i];
10706
+ if(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
10707
+ }
10708
+ }else if(present&&!looseKind){
10709
+ for(let i=0;i<n;i++){
10710
+ const row=idx[i];
10711
+ if(present(row)===1)keep[p++]=row;else drop[a++]=row;
10712
+ }
10713
+ }else{
10714
+ const reader=valueReader(handle);
10715
+ for(let i=0;i<n;i++){
10716
+ const row=idx[i];
10717
+ if(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;
10718
+ }
10719
+ }
10720
+ if(a===0)return{present:idx,absent:EMPTY_INDICES};
10721
+ return{present:keep.subarray(0,p),absent:drop.subarray(0,a)};
10722
+ }
10723
+ function joinRuns(sorted,absent,nullsFirst){
10724
+ if(absent.length===0)return sorted;
10725
+ const out=new Uint32Array(sorted.length+absent.length);
10726
+ if(nullsFirst){
10727
+ out.set(absent,0);
10728
+ out.set(sorted,absent.length);
10729
+ }else{
10730
+ out.set(sorted,0);
10731
+ out.set(absent,sorted.length);
10732
+ }
10733
+ return out;
10734
+ }
10735
+ function sortColumn(handle,order,opts={}){
10736
+ const src=order||identity(rowCount(handle,opts));
10737
+ if(!handle||src.length<2)return Uint32Array.from(src);
10738
+ const{present,absent}=partitionPresent(handle,src);
10739
+ if(present.length===0)return Uint32Array.from(src);
10740
+ const descending=!!opts.descending;
10741
+ let sorted;
10742
+ if(typeof opts.compare==='function'){
10743
+ sorted=sortByCompare(handle,present,opts);
10744
+ }else{
10745
+ switch(handle.kind){
10746
+ case'float64':
10747
+ sorted=radixSortFloat64(handle.values,present,descending);
10748
+ break;
10749
+ case'int32':
10750
+ sorted=radixSortInt32(handle.values,present,descending);
10751
+ break;
10752
+ case'dictionary':
10753
+ sorted=rankSortDictionary(handle,present,opts);
10754
+ break;
10755
+ case'bitset':
10756
+ sorted=sortBitsetColumn(handle,present,descending);
10757
+ break;
10758
+ default:
10759
+ sorted=sortByComparator(handle,present,opts);
10760
+ break;
10761
+ }
10762
+ }
10763
+ return joinRuns(sorted,absent,!!opts.nullsFirst);
10764
+ }
10765
+ function sortMulti(handles,entries,order,opts={}){
10766
+ const list=entries||[];
10767
+ const first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);
10768
+ let current=order||identity(rowCount(first,opts));
10769
+ for(let i=list.length-1;i>=0;i--){
10770
+ const entry=list[i];
10771
+ const handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);
10772
+ if(!handle)continue;
10773
+ current=sortColumn(handle,current,{
10774
+ descending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',
10775
+ nullsFirst:!!entry.nullsFirst,
10776
+ locale:entry.locale!==undefined?entry.locale:opts.locale,
10777
+ compare:entry.compare,
10778
+ });
10779
+ }
10780
+ return current instanceof Uint32Array?current:Uint32Array.from(current);
10781
+ }
10782
+ function byId(handles,id){
10783
+ if(!handles||id===undefined)return undefined;
10784
+ for(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];
10785
+ return undefined;
10786
+ }
10787
+ });
10788
+ __def("packages/core/src/store/stringrank.js",function(__exports,__req){
10789
+ 'use strict';
10790
+ Object.defineProperty(__exports,"DEFAULT_MAX_DISTINCT",{enumerable:true,get:function(){return DEFAULT_MAX_DISTINCT;}});
10791
+ Object.defineProperty(__exports,"StringRankIndex",{enumerable:true,get:function(){return StringRankIndex;}});
10792
+ const __m0=__req("packages/core/src/compute/sort.js");
10793
+ const collateStringRanks=__m0["collateStringRanks"];
10794
+ const rankSortStrings=__m0["rankSortStrings"];
10795
+ const DEFAULT_MAX_DISTINCT=100000;
10796
+ class StringRankIndex{
10797
+ #table=[];
10798
+ #codeOf=new Map();
10799
+ #codeByRow;
10800
+ #length=0;
10801
+ #generation=0;
10802
+ #stamp=-1;
10803
+ #maxDistinct;
10804
+ #capped=false;
10805
+ #ranks=null;
10806
+ #ranksGeneration=-1;
10807
+ #ranksLocale='\u0000';
10808
+ constructor(maxDistinct=DEFAULT_MAX_DISTINCT){
10809
+ this.#maxDistinct=maxDistinct>0?maxDistinct:DEFAULT_MAX_DISTINCT;
10810
+ this.#codeByRow=new Uint32Array(0);
10811
+ }
10812
+ get version(){return this.#stamp;}
10813
+ set version(version){this.#stamp=version;}
10814
+ get generation(){return this.#generation;}
10815
+ get size(){return this.#table.length;}
10816
+ get capped(){return this.#capped;}
10817
+ get length(){return this.#length;}
10818
+ get bytes(){
10819
+ let total=this.#codeByRow.byteLength;
10820
+ const table=this.#table;
10821
+ for(let i=0;i<table.length;i++)total+=table[i].length*2+24;
10822
+ return total;
10823
+ }
10824
+ #intern(value,capOnGrowth){
10825
+ const existing=this.#codeOf.get(value);
10826
+ if(existing!==undefined)return existing;
10827
+ if(this.#capped)return-1;
10828
+ if(capOnGrowth&&this.#table.length>=this.#maxDistinct){
10829
+ this.#capped=true;
10830
+ return-1;
10831
+ }
10832
+ const code=this.#table.length;
10833
+ this.#table.push(value);
10834
+ this.#codeOf.set(value,code);
10835
+ this.#generation++;
10836
+ return code;
10837
+ }
10838
+ build(values,count){
10839
+ const n=count|0;
10840
+ this.#table=[];
10841
+ this.#codeOf=new Map();
10842
+ this.#generation=0;
10843
+ this.#capped=false;
10844
+ this.#ranks=null;
10845
+ this.#ranksGeneration=-1;
10846
+ this.#codeByRow=new Uint32Array(n);
10847
+ for(let row=0;row<n;row++){
10848
+ const v=values[row];
10849
+ const code=typeof v==='string'?this.#intern(v,false):-1;
10850
+ this.#codeByRow[row]=code<0?0:code;
10851
+ }
10852
+ this.#length=n;
10853
+ }
10854
+ append(values,from,count){
10855
+ const to=(from|0)+(count|0);
10856
+ if(to>this.#codeByRow.length){
10857
+ const next=new Uint32Array(to);
10858
+ next.set(this.#codeByRow.subarray(0,this.#length));
10859
+ this.#codeByRow=next;
10860
+ }
10861
+ for(let row=from|0;row<to;row++){
10862
+ const v=values[row];
10863
+ const code=typeof v==='string'?this.#intern(v,true):-1;
10864
+ this.#codeByRow[row]=code<0?0:code;
10865
+ }
10866
+ this.#length=Math.max(this.#length,to);
10867
+ }
10868
+ ranks(locale){
10869
+ const key=locale||'';
10870
+ if(this.#ranks&&this.#ranksGeneration===this.#generation&&this.#ranksLocale===key){
10871
+ return this.#ranks;
10872
+ }
10873
+ const ranks=collateStringRanks(this.#table,this.#table.length,locale);
10874
+ this.#ranks=ranks;
10875
+ this.#ranksGeneration=this.#generation;
10876
+ this.#ranksLocale=key;
10877
+ return ranks;
10878
+ }
10879
+ usable(idx,values,locale){
10880
+ if(this.#capped||this.#table.length===0)return false;
10881
+ const codeByRow=this.#codeByRow;
10882
+ const table=this.#table;
10883
+ const covered=this.#length;
10884
+ for(let i=0;i<idx.length;i++){
10885
+ const row=idx[i];
10886
+ if(row>=covered)return false;
10887
+ if(table[codeByRow[row]]!==values[row])return false;
10888
+ }
10889
+ return true;
10890
+ }
10891
+ sort(idx,opts){
10892
+ const ranks=this.ranks(opts.locale);
10893
+ const d=this.#table.length;
10894
+ const n=idx.length;
10895
+ const codes=new Uint32Array(n);
10896
+ const codeByRow=this.#codeByRow;
10897
+ for(let i=0;i<n;i++)codes[i]=codeByRow[idx[i]];
10898
+ return rankSortStrings(idx,codes,ranks,d,!!opts.descending);
10899
+ }
10900
+ }
10901
+ });
10222
10902
  __def("packages/core/src/store/columnstore.js",function(__exports,__req){
10223
10903
  'use strict';
10224
10904
  Object.defineProperty(__exports,"REMOVED",{enumerable:true,get:function(){return REMOVED;}});
@@ -10235,6 +10915,8 @@ const __m2=__req("packages/core/src/store/dictionary.js");
10235
10915
  const Dictionary=__m2["Dictionary"];
10236
10916
  const __m3=__req("packages/core/src/store/multivalue.js");
10237
10917
  const MultiValue=__m3["MultiValue"];
10918
+ const __m4=__req("packages/core/src/store/stringrank.js");
10919
+ const StringRankIndex=__m4["StringRankIndex"];
10238
10920
  const REMOVED=0xFFFFFFFF;
10239
10921
  const DEFAULT_CAPACITY=1024;
10240
10922
  const DEFAULT_COLUMNAR_BELOW=5000;
@@ -10301,6 +10983,10 @@ class ColumnHandle{
10301
10983
  #bits=null;
10302
10984
  #mv=null;
10303
10985
  #dict=null;
10986
+ #stringRank=null;
10987
+ #stringRankOn;
10988
+ #stringRankMax;
10989
+ #stringRankVersion=-1;
10304
10990
  #presence=null;
10305
10991
  #capacity=0;
10306
10992
  #version=0;
@@ -10322,6 +11008,10 @@ this.#host=host;
10322
11008
  this.#read=isFunction(schema.read)
10323
11009
  ?schema.read
10324
11010
  :pathGetter(schema.field||schema.id);
11011
+ this.#stringRankOn=schema.stringRankIndex!=='off';
11012
+ this.#stringRankMax=typeof schema.stringRankMaxDistinct==='number'
11013
+ ?schema.stringRankMaxDistinct
11014
+ :0;
10325
11015
  this.#overlay=new Map();
10326
11016
  }
10327
11017
  get id(){return this.#id;}
@@ -10343,6 +11033,33 @@ get dict(){
10343
11033
  if(this.#released||!this.#columnar)return null;
10344
11034
  return this.#kind==='dictionary'||this.#kind==='multi'?this.#dict:null;
10345
11035
  }
11036
+ get stringRank(){
11037
+ if(this.#released||!this.#stringRankOn)return null;
11038
+ if(this.kind!=='object')return null;
11039
+ const values=this.values;
11040
+ const n=this.#host.physical();
11041
+ if(!values||n===0)return null;
11042
+ if(this.#stringRank===null){
11043
+ if(typeof values[0]!=='string')return null;
11044
+ const index=new StringRankIndex(this.#resolveStringRankMax());
11045
+ index.build(values,n);
11046
+ index.version=this.#version;
11047
+ this.#stringRank=index;
11048
+ this.#stringRankVersion=this.#version;
11049
+ return index.capped?null:index;
11050
+ }
11051
+ if(this.#stringRank.length<n){
11052
+ this.#stringRank.append(values,this.#stringRank.length,n-this.#stringRank.length);
11053
+ }
11054
+ this.#stringRank.version=this.#version;
11055
+ this.#stringRankVersion=this.#version;
11056
+ return this.#stringRank.capped?null:this.#stringRank;
11057
+ }
11058
+ #resolveStringRankMax(){return this.#stringRankMax;}
11059
+ #dropStringRank(){
11060
+ this.#stringRank=null;
11061
+ this.#stringRankVersion=-1;
11062
+ }
10346
11063
  get offsets(){
10347
11064
  if(this.#released||!this.#columnar||this.#kind!=='multi')return null;
10348
11065
  return this.#mv.offsets;
@@ -10381,6 +11098,7 @@ set(physical,value){
10381
11098
  if(this.#released)return;
10382
11099
  if(this.#columnar)this.#writeValue(physical,value);
10383
11100
  else this.#overlay.set(physical,value===undefined?null:value);
11101
+ if(this.#stringRank)this.#dropStringRank();
10384
11102
  this.#version++;
10385
11103
  }
10386
11104
  read(row){return this.#read(row);}
@@ -10473,6 +11191,11 @@ if(sawAbsent){
10473
11191
  warnOnce(`store.null.${this.#id}`,
10474
11192
  `column "${this.#id}" is declared non-nullable but received null; storing a filler value`);
10475
11193
  }
11194
+ if(this.#stringRank&&this.#kind==='object'){
11195
+ this.#stringRank.append(this.#buf,from,n);
11196
+ this.#stringRank.version=this.#version+1;
11197
+ this.#stringRankVersion=this.#version+1;
11198
+ }
10476
11199
  this.#version++;
10477
11200
  }
10478
11201
  appendPacked(frag,from,n){
@@ -10548,6 +11271,7 @@ this.#alloc(capacity);
10548
11271
  for(let p=0;p<fill;p++)this.#writeValue(p,values[p]);
10549
11272
  this.#overlay.clear();
10550
11273
  this.#cache=null;
11274
+ this.#dropStringRank();
10551
11275
  this.#version++;
10552
11276
  }
10553
11277
  grow(capacity){
@@ -10581,11 +11305,13 @@ const gone=presence!==null&&presence.get(p)===0;
10581
11305
  if(gone&&kind!=='multi')continue;
10582
11306
  this.#writeValue(p,gone?null:decodeFrom(old,p));
10583
11307
  }
11308
+ this.#dropStringRank();
10584
11309
  this.#version++;
10585
11310
  return true;
10586
11311
  }
10587
11312
  compact(remap,oldFill,liveCount){
10588
11313
  if(this.#released)return;
11314
+ this.#dropStringRank();
10589
11315
  if(!this.#columnar){
10590
11316
  const overlay=this.#overlay;
10591
11317
  if(overlay.size){
@@ -10631,6 +11357,7 @@ this.#mv=null;
10631
11357
  if(this.#presence)this.#presence.release();
10632
11358
  this.#presence=null;
10633
11359
  this.#dict=null;
11360
+ this.#stringRank=null;
10634
11361
  this.#overlay=new Map();
10635
11362
  this.#cache=null;
10636
11363
  this.#capacity=0;
@@ -10979,418 +11706,6 @@ return shared;
10979
11706
  }
10980
11707
  let shared=null;
10981
11708
  });
10982
- __def("packages/core/src/compute/sort.js",function(__exports,__req){
10983
- 'use strict';
10984
- Object.defineProperty(__exports,"radixSortFloat64",{enumerable:true,get:function(){return radixSortFloat64;}});
10985
- Object.defineProperty(__exports,"radixSortInt32",{enumerable:true,get:function(){return radixSortInt32;}});
10986
- Object.defineProperty(__exports,"rankSortDictionary",{enumerable:true,get:function(){return rankSortDictionary;}});
10987
- Object.defineProperty(__exports,"mergeSortComparator",{enumerable:true,get:function(){return mergeSortComparator;}});
10988
- Object.defineProperty(__exports,"sortColumn",{enumerable:true,get:function(){return sortColumn;}});
10989
- Object.defineProperty(__exports,"sortMulti",{enumerable:true,get:function(){return sortMulti;}});
10990
- const __m0=__req("packages/core/src/compute/handle.js");
10991
- const bitReader=__m0["bitReader"];
10992
- const dictRanks=__m0["dictRanks"];
10993
- const dictSize=__m0["dictSize"];
10994
- const identity=__m0["identity"];
10995
- const isMissing=__m0["isMissing"];
10996
- const presenceReader=__m0["presenceReader"];
10997
- const rowCount=__m0["rowCount"];
10998
- const valueComparator=__m0["valueComparator"];
10999
- const valueReader=__m0["valueReader"];
11000
- const EMPTY_INDICES=new Uint32Array(0);
11001
- const SCRATCH=new ArrayBuffer(8);
11002
- const SCRATCH_F64=new Float64Array(SCRATCH);
11003
- const SCRATCH_U32=new Uint32Array(SCRATCH);
11004
- const HI=(()=>{
11005
- SCRATCH_F64[0]=-1;
11006
- return(SCRATCH_U32[1]&0x80000000)!==0?1:0;
11007
- })();
11008
- const LO=HI===1?0:1;
11009
- function transformDouble(value,out){
11010
- SCRATCH_F64[0]=value;
11011
- let hi=SCRATCH_U32[HI];
11012
- let lo=SCRATCH_U32[LO];
11013
- if((hi&0x80000000)!==0){
11014
- hi=~hi>>>0;
11015
- lo=~lo>>>0;
11016
- }else{
11017
- hi=(hi^0x80000000)>>>0;
11018
- }
11019
- out[0]=lo;
11020
- out[1]=hi;
11021
- }
11022
- function radixLsd64(idx,lo,hi,n){
11023
- if(n<2)return idx;
11024
- const hist=new Uint32Array(256*8);
11025
- for(let i=0;i<n;i++){
11026
- const l=lo[i];
11027
- const h=hi[i];
11028
- hist[l&0xff]++;
11029
- hist[256+((l>>>8)&0xff)]++;
11030
- hist[512+((l>>>16)&0xff)]++;
11031
- hist[768+((l>>>24)&0xff)]++;
11032
- hist[1024+(h&0xff)]++;
11033
- hist[1280+((h>>>8)&0xff)]++;
11034
- hist[1536+((h>>>16)&0xff)]++;
11035
- hist[1792+((h>>>24)&0xff)]++;
11036
- }
11037
- let srcIdx=idx;
11038
- let srcLo=lo;
11039
- let srcHi=hi;
11040
- let dstIdx=new Uint32Array(n);
11041
- let dstLo=new Uint32Array(n);
11042
- let dstHi=new Uint32Array(n);
11043
- const offset=new Uint32Array(256);
11044
- for(let pass=0;pass<8;pass++){
11045
- const base=pass<<8;
11046
- const shift=(pass&3)<<3;
11047
- const useHi=pass>=4;
11048
- let skip=false;
11049
- for(let b=0;b<256;b++){
11050
- if(hist[base+b]===n){skip=true;break;}
11051
- }
11052
- if(skip)continue;
11053
- let sum=0;
11054
- for(let b=0;b<256;b++){
11055
- offset[b]=sum;
11056
- sum+=hist[base+b];
11057
- }
11058
- for(let i=0;i<n;i++){
11059
- const l=srcLo[i];
11060
- const h=srcHi[i];
11061
- const digit=((useHi?h:l)>>>shift)&0xff;
11062
- const p=offset[digit]++;
11063
- dstIdx[p]=srcIdx[i];
11064
- dstLo[p]=l;
11065
- dstHi[p]=h;
11066
- }
11067
- let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
11068
- t=srcLo;srcLo=dstLo;dstLo=t;
11069
- t=srcHi;srcHi=dstHi;dstHi=t;
11070
- }
11071
- return srcIdx;
11072
- }
11073
- function radixLsd32(idx,keys,n){
11074
- if(n<2)return idx;
11075
- const hist=new Uint32Array(256*4);
11076
- for(let i=0;i<n;i++){
11077
- const k=keys[i];
11078
- hist[k&0xff]++;
11079
- hist[256+((k>>>8)&0xff)]++;
11080
- hist[512+((k>>>16)&0xff)]++;
11081
- hist[768+((k>>>24)&0xff)]++;
11082
- }
11083
- let srcIdx=idx;
11084
- let srcKeys=keys;
11085
- let dstIdx=new Uint32Array(n);
11086
- let dstKeys=new Uint32Array(n);
11087
- const offset=new Uint32Array(256);
11088
- for(let pass=0;pass<4;pass++){
11089
- const base=pass<<8;
11090
- const shift=pass<<3;
11091
- let skip=false;
11092
- for(let b=0;b<256;b++){
11093
- if(hist[base+b]===n){skip=true;break;}
11094
- }
11095
- if(skip)continue;
11096
- let sum=0;
11097
- for(let b=0;b<256;b++){
11098
- offset[b]=sum;
11099
- sum+=hist[base+b];
11100
- }
11101
- for(let i=0;i<n;i++){
11102
- const k=srcKeys[i];
11103
- const p=offset[(k>>>shift)&0xff]++;
11104
- dstIdx[p]=srcIdx[i];
11105
- dstKeys[p]=k;
11106
- }
11107
- let t=srcIdx;srcIdx=dstIdx;dstIdx=t;
11108
- t=srcKeys;srcKeys=dstKeys;dstKeys=t;
11109
- }
11110
- return srcIdx;
11111
- }
11112
- function countingSort(idx,keys,n,radix){
11113
- const counts=new Uint32Array(radix+1);
11114
- for(let i=0;i<n;i++)counts[keys[i]]++;
11115
- let sum=0;
11116
- for(let k=0;k<=radix;k++){
11117
- const c=counts[k];
11118
- counts[k]=sum;
11119
- sum+=c;
11120
- }
11121
- const out=new Uint32Array(n);
11122
- for(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];
11123
- return out;
11124
- }
11125
- function sortUint32Keys(idx,keys,n,radix){
11126
- if(n<2)return idx;
11127
- if(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);
11128
- return radixLsd32(idx,keys,n);
11129
- }
11130
- function exact(buffer,n){
11131
- if(buffer.length===n&&buffer.byteOffset===0)return buffer;
11132
- return Uint32Array.prototype.slice.call(buffer,0,n);
11133
- }
11134
- function radixSortFloat64(values,order,descending=false){
11135
- const src=order||identity(values.length);
11136
- const n=src.length;
11137
- if(n<2)return Uint32Array.from(src);
11138
- const idx=new Uint32Array(n);
11139
- const lo=new Uint32Array(n);
11140
- const hi=new Uint32Array(n);
11141
- const nans=new Uint32Array(n);
11142
- const pair=new Uint32Array(2);
11143
- let m=0;
11144
- let nanCount=0;
11145
- for(let i=0;i<n;i++){
11146
- const row=src[i];
11147
- const v=values[row];
11148
- if(Number.isNaN(v)){nans[nanCount++]=row;continue;}
11149
- transformDouble(v,pair);
11150
- if(descending){
11151
- lo[m]=~pair[0]>>>0;
11152
- hi[m]=~pair[1]>>>0;
11153
- }else{
11154
- lo[m]=pair[0];
11155
- hi[m]=pair[1];
11156
- }
11157
- idx[m++]=row;
11158
- }
11159
- const sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);
11160
- if(nanCount===0)return exact(sorted,m);
11161
- const out=new Uint32Array(n);
11162
- out.set(sorted.subarray(0,m),0);
11163
- out.set(nans.subarray(0,nanCount),m);
11164
- return out;
11165
- }
11166
- function radixSortInt32(values,order,descending=false){
11167
- const src=order||identity(values.length);
11168
- const n=src.length;
11169
- if(n<2)return Uint32Array.from(src);
11170
- const idx=Uint32Array.from(src);
11171
- const keys=new Uint32Array(n);
11172
- for(let i=0;i<n;i++){
11173
- const k=(values[idx[i]]^0x80000000)>>>0;
11174
- keys[i]=descending?(~k>>>0):k;
11175
- }
11176
- return exact(radixLsd32(idx,keys,n),n);
11177
- }
11178
- function rankSortDictionary(handle,order,opts={}){
11179
- const src=order||identity(rowCount(handle,opts));
11180
- const n=src.length;
11181
- if(n<2)return Uint32Array.from(src);
11182
- const ranks=dictRanks(handle.dict,opts.locale);
11183
- const codes=handle.values;
11184
- const present=presenceReader(handle);
11185
- const size=Math.max(dictSize(handle.dict),ranks.length);
11186
- const absentRank=size;
11187
- const idx=Uint32Array.from(src);
11188
- const keys=new Uint32Array(n);
11189
- const descending=!!opts.descending;
11190
- for(let i=0;i<n;i++){
11191
- const row=idx[i];
11192
- let rank=present&&present(row)===0?absentRank:ranks[codes[row]];
11193
- if(rank===undefined)rank=absentRank;
11194
- keys[i]=descending?absentRank-rank:rank;
11195
- }
11196
- return exact(sortUint32Keys(idx,keys,n,size+1),n);
11197
- }
11198
- function mergeSortComparator(values,order,compare){
11199
- const n=order.length;
11200
- let src=Uint32Array.from(order);
11201
- if(n<2)return src;
11202
- let dst=new Uint32Array(n);
11203
- for(let width=1;width<n;width<<=1){
11204
- for(let start=0;start<n;start+=width<<1){
11205
- const mid=Math.min(start+width,n);
11206
- const end=Math.min(start+(width<<1),n);
11207
- let i=start;
11208
- let j=mid;
11209
- let k=start;
11210
- while(i<mid&&j<end){
11211
- dst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];
11212
- }
11213
- while(i<mid)dst[k++]=src[i++];
11214
- while(j<end)dst[k++]=src[j++];
11215
- }
11216
- const t=src;src=dst;dst=t;
11217
- }
11218
- return src;
11219
- }
11220
- function sortBitsetColumn(handle,idx,descending){
11221
- const bit=bitReader(handle.values);
11222
- const n=idx.length;
11223
- const out=new Uint32Array(n);
11224
- const first=descending?1:0;
11225
- let k=0;
11226
- for(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];
11227
- for(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];
11228
- return out;
11229
- }
11230
- function indexableValues(handle,idx){
11231
- const values=handle.values;
11232
- const kind=handle.kind;
11233
- const direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));
11234
- if(direct&&!handle.presence)return values;
11235
- const reader=valueReader(handle);
11236
- const materialised=new Array(rowCount(handle)||0);
11237
- for(let i=0;i<idx.length;i++){
11238
- const row=idx[i];
11239
- materialised[row]=reader(row);
11240
- }
11241
- return materialised;
11242
- }
11243
- function allStrings(values,idx){
11244
- for(let i=0;i<idx.length;i++){
11245
- if(typeof values[idx[i]]!=='string')return false;
11246
- }
11247
- return true;
11248
- }
11249
- function keyedSortStrings(values,idx,opts){
11250
- const n=idx.length;
11251
- const codeOf=new Map();
11252
- const table=[];
11253
- const codes=new Uint32Array(n);
11254
- for(let i=0;i<n;i++){
11255
- const v=values[idx[i]];
11256
- let c=codeOf.get(v);
11257
- if(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}
11258
- codes[i]=c;
11259
- }
11260
- const d=table.length;
11261
- const compare=valueComparator(opts.locale);
11262
- const order=new Array(d);
11263
- for(let i=0;i<d;i++)order[i]=i;
11264
- order.sort((a,b)=>compare(table[a],table[b])||a-b);
11265
- const ranks=new Uint32Array(d);
11266
- for(let r=0;r<d;r++)ranks[order[r]]=r;
11267
- const descending=!!opts.descending;
11268
- const idxOut=Uint32Array.from(idx);
11269
- const keys=new Uint32Array(n);
11270
- const top=d-1;
11271
- for(let i=0;i<n;i++){
11272
- const rank=ranks[codes[i]];
11273
- keys[i]=descending?top-rank:rank;
11274
- }
11275
- return exact(sortUint32Keys(idxOut,keys,n,d),n);
11276
- }
11277
- function sortByComparator(handle,idx,opts){
11278
- const values=indexableValues(handle,idx);
11279
- if(idx.length>=2&&allStrings(values,idx))return keyedSortStrings(values,idx,opts);
11280
- const base=valueComparator(opts.locale);
11281
- const compare=opts.descending?(a,b)=>base(b,a):base;
11282
- return mergeSortComparator(values,idx,compare);
11283
- }
11284
- function sortByCompare(handle,idx,opts){
11285
- const values=indexableValues(handle,idx);
11286
- const user=opts.compare;
11287
- const descending=!!opts.descending;
11288
- const compare=descending
11289
- ?(a,b)=>-user(a,b,undefined,undefined,true)
11290
- :(a,b)=>user(a,b,undefined,undefined,false);
11291
- return mergeSortComparator(values,idx,compare);
11292
- }
11293
- function partitionPresent(handle,idx){
11294
- const n=idx.length;
11295
- const present=presenceReader(handle);
11296
- const values=handle.values;
11297
- const checkNaN=handle.kind==='float64'&&!!values;
11298
- const looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;
11299
- if(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};
11300
- const keep=new Uint32Array(n);
11301
- const drop=new Uint32Array(n);
11302
- let p=0;
11303
- let a=0;
11304
- if(present&&checkNaN){
11305
- for(let i=0;i<n;i++){
11306
- const row=idx[i];
11307
- if(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
11308
- }
11309
- }else if(checkNaN&&!present){
11310
- for(let i=0;i<n;i++){
11311
- const row=idx[i];
11312
- if(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;
11313
- }
11314
- }else if(present&&!looseKind){
11315
- for(let i=0;i<n;i++){
11316
- const row=idx[i];
11317
- if(present(row)===1)keep[p++]=row;else drop[a++]=row;
11318
- }
11319
- }else{
11320
- const reader=valueReader(handle);
11321
- for(let i=0;i<n;i++){
11322
- const row=idx[i];
11323
- if(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;
11324
- }
11325
- }
11326
- if(a===0)return{present:idx,absent:EMPTY_INDICES};
11327
- return{present:keep.subarray(0,p),absent:drop.subarray(0,a)};
11328
- }
11329
- function joinRuns(sorted,absent,nullsFirst){
11330
- if(absent.length===0)return sorted;
11331
- const out=new Uint32Array(sorted.length+absent.length);
11332
- if(nullsFirst){
11333
- out.set(absent,0);
11334
- out.set(sorted,absent.length);
11335
- }else{
11336
- out.set(sorted,0);
11337
- out.set(absent,sorted.length);
11338
- }
11339
- return out;
11340
- }
11341
- function sortColumn(handle,order,opts={}){
11342
- const src=order||identity(rowCount(handle,opts));
11343
- if(!handle||src.length<2)return Uint32Array.from(src);
11344
- const{present,absent}=partitionPresent(handle,src);
11345
- if(present.length===0)return Uint32Array.from(src);
11346
- const descending=!!opts.descending;
11347
- let sorted;
11348
- if(typeof opts.compare==='function'){
11349
- sorted=sortByCompare(handle,present,opts);
11350
- }else{
11351
- switch(handle.kind){
11352
- case'float64':
11353
- sorted=radixSortFloat64(handle.values,present,descending);
11354
- break;
11355
- case'int32':
11356
- sorted=radixSortInt32(handle.values,present,descending);
11357
- break;
11358
- case'dictionary':
11359
- sorted=rankSortDictionary(handle,present,opts);
11360
- break;
11361
- case'bitset':
11362
- sorted=sortBitsetColumn(handle,present,descending);
11363
- break;
11364
- default:
11365
- sorted=sortByComparator(handle,present,opts);
11366
- break;
11367
- }
11368
- }
11369
- return joinRuns(sorted,absent,!!opts.nullsFirst);
11370
- }
11371
- function sortMulti(handles,entries,order,opts={}){
11372
- const list=entries||[];
11373
- const first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);
11374
- let current=order||identity(rowCount(first,opts));
11375
- for(let i=list.length-1;i>=0;i--){
11376
- const entry=list[i];
11377
- const handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);
11378
- if(!handle)continue;
11379
- current=sortColumn(handle,current,{
11380
- descending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',
11381
- nullsFirst:!!entry.nullsFirst,
11382
- locale:entry.locale!==undefined?entry.locale:opts.locale,
11383
- compare:entry.compare,
11384
- });
11385
- }
11386
- return current instanceof Uint32Array?current:Uint32Array.from(current);
11387
- }
11388
- function byId(handles,id){
11389
- if(!handles||id===undefined)return undefined;
11390
- for(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];
11391
- return undefined;
11392
- }
11393
- });
11394
11709
  __def("packages/core/src/compute/filter.js",function(__exports,__req){
11395
11710
  'use strict';
11396
11711
  Object.defineProperty(__exports,"releaseMask",{enumerable:true,get:function(){return releaseMask;}});
@@ -12384,7 +12699,9 @@ Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function
12384
12699
  Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return RowFactory;}});
12385
12700
  Object.defineProperty(__exports,"pinnedRow",{enumerable:true,get:function(){return pinnedRow;}});
12386
12701
  Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return lazyRowView;}});
12702
+ Object.defineProperty(__exports,"groupPathElement",{enumerable:true,get:function(){return groupPathElement;}});
12387
12703
  Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return groupKey;}});
12704
+ Object.defineProperty(__exports,"groupPrefixKeys",{enumerable:true,get:function(){return groupPrefixKeys;}});
12388
12705
  const __m0=__req("packages/core/src/internal/util.js");
12389
12706
  const warnOnce=__m0["warnOnce"];
12390
12707
  const isFunction=__m0["isFunction"];
@@ -12582,8 +12899,20 @@ return Reflect.has(target,prop);
12582
12899
  },
12583
12900
  })));
12584
12901
  }
12902
+ function groupPathElement(value){
12903
+ return value===null||value===undefined?'':String(value);
12904
+ }
12585
12905
  function groupKey(path){
12586
- return`g${KEY_SEP}${(path||[]).map((p)=>(p===null||p===undefined?'':String(p))).join(KEY_SEP)}`;
12906
+ return`g${KEY_SEP}${(path||[]).map(groupPathElement).join(KEY_SEP)}`;
12907
+ }
12908
+ function groupPrefixKeys(path){
12909
+ const keys=new Array(path.length);
12910
+ const acc=[];
12911
+ for(let level=0;level<path.length;level++){
12912
+ acc.push(groupPathElement(path[level]));
12913
+ keys[level]=groupKey(acc);
12914
+ }
12915
+ return keys;
12587
12916
  }
12588
12917
  });
12589
12918
  __def("packages/core/src/source/handles.js",function(__exports,__req){
@@ -12592,14 +12921,17 @@ Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function()
12592
12921
  Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return createHandleProvider;}});
12593
12922
  const __m0=__req("packages/core/src/internal/util.js");
12594
12923
  const isFunction=__m0["isFunction"];
12924
+ const warnOnce=__m0["warnOnce"];
12595
12925
  class HandleProvider{
12596
12926
  #ctx;
12597
12927
  #readRows;
12928
+ #dropped;
12598
12929
  #cache=new Map();
12599
12930
  #version=0;
12600
- constructor(ctx,readRows){
12931
+ constructor(ctx,readRows,dropped){
12601
12932
  this.#ctx=ctx;
12602
12933
  this.#readRows=readRows;
12934
+ this.#dropped=isFunction(dropped)?dropped:()=>false;
12603
12935
  }
12604
12936
  get store(){
12605
12937
  const store=(this.#ctx).store;
@@ -12618,6 +12950,17 @@ const cached=this.#cache.get(colId);
12618
12950
  if(cached&&cached.builtAt===this.#version)return cached.handle;
12619
12951
  const column=this.#column(colId);
12620
12952
  if(!column)return undefined;
12953
+ if(store&&this.#dropped()){
12954
+ warnOnce(
12955
+ `source.dropped.${colId}`,
12956
+ `column "${colId}" cannot be served under ingest.dropSourceRows: it is an `
12957
+ +'impure computed column (a shadow or a positional/rank column) that is '
12958
+ +'never stored, so it can only be read from the caller\'s row objects — '
12959
+ +'which dropSourceRows has released. Do not sort, filter, group or total '
12960
+ +'on such a column with dropSourceRows enabled.',
12961
+ );
12962
+ return undefined;
12963
+ }
12621
12964
  const handle=this.#buildObjectHandle(column);
12622
12965
  this.#cache.set(colId,{handle,builtAt:this.#version});
12623
12966
  return handle;
@@ -12648,8 +12991,8 @@ version,
12648
12991
  };
12649
12992
  }
12650
12993
  }
12651
- function createHandleProvider(ctx,readRows){
12652
- return new HandleProvider(ctx,readRows);
12994
+ function createHandleProvider(ctx,readRows,dropped){
12995
+ return new HandleProvider(ctx,readRows,dropped);
12653
12996
  }
12654
12997
  });
12655
12998
  __def("packages/core/src/compute/incremental.js",function(__exports,__req){
@@ -13269,6 +13612,8 @@ const mergeRow=__m0["mergeRow"];
13269
13612
  const __m1=__req("packages/core/src/source/rows.js");
13270
13613
  const createRowFactory=__m1["createRowFactory"];
13271
13614
  const groupKey=__m1["groupKey"];
13615
+ const groupPathElement=__m1["groupPathElement"];
13616
+ const groupPrefixKeys=__m1["groupPrefixKeys"];
13272
13617
  const lazyRowView=__m1["lazyRowView"];
13273
13618
  const __m2=__req("packages/core/src/source/handles.js");
13274
13619
  const createHandleProvider=__m2["createHandleProvider"];
@@ -13287,6 +13632,11 @@ const resolveTree=__m6["resolveTree"];
13287
13632
  const indexTree=__m6["indexTree"];
13288
13633
  const STAGES=Object.freeze(['filter','sort','group','total','pivot','flatten']);
13289
13634
  const EMPTY_HEADINGS=Object.freeze([]);
13635
+ function totalFnFor(column,scope){
13636
+ if(!column)return null;
13637
+ const override=scope==='grand'?column.grandTotal:column.groupTotal;
13638
+ return override!=null?override:column.total;
13639
+ }
13290
13640
  function comparatorFor(column){
13291
13641
  if(!column)return undefined;
13292
13642
  if(column.value&&isFunction(column.value.compare))return column.value.compare;
@@ -13329,6 +13679,8 @@ mode='memory';
13329
13679
  #ctx;
13330
13680
  #config;
13331
13681
  #rows;
13682
+ #dropped=false;
13683
+ #priorRows=null;
13332
13684
  #factory;
13333
13685
  #handles;
13334
13686
  #stages=new Map();
@@ -13340,6 +13692,9 @@ mode='memory';
13340
13692
  #running=new Map();
13341
13693
  #runningId=-1;
13342
13694
  #totalDeltas=[];
13695
+ #groupRunning=new Map();
13696
+ #groupRunningId=-1;
13697
+ #groupDeltas=[];
13343
13698
  #totalsDirty=null;
13344
13699
  #totalsBasis=null;
13345
13700
  #lastGrand=null;
@@ -13360,7 +13715,7 @@ this.#ctx=ctx||{};
13360
13715
  const gridConfig=(this.#ctx.config)||{};
13361
13716
  this.#rows=(this.#config.rows||gridConfig.rows||[]);
13362
13717
  this.#factory=createRowFactory((this.#ctx));
13363
- this.#handles=createHandleProvider(this.#ctx,()=>this.#rows);
13718
+ this.#handles=createHandleProvider(this.#ctx,()=>this.#rows,()=>this.#dropped);
13364
13719
  this.#rowCache=new Lru(Number(gridConfig.rowCacheSize)||DEFAULT_ROW_CACHE);
13365
13720
  for(const name of STAGES)this.#stages.set(name,{key:null,result:null,id:0,computed:false});
13366
13721
  }
@@ -13409,13 +13764,7 @@ return this.#materialise(index,index);
13409
13764
  }
13410
13765
  byKey(key){
13411
13766
  this.#run();
13412
- if(!this.#keyIndex){
13413
- this.#keyIndex=new Map();
13414
- for(let i=0;i<this.#rows.length;i++){
13415
- if(this.#rows[i]===undefined)continue;
13416
- this.#keyIndex.set(this.#factory.keyOf(this.#rows[i],i),i);
13417
- }
13418
- }
13767
+ if(!this.#keyIndex)this.#buildKeyIndex();
13419
13768
  const physical=this.#keyIndex.get(key);
13420
13769
  if(physical!==undefined)return this.#leafRow(physical);
13421
13770
  for(let i=0;i<this.#slots.length;i++){
@@ -13461,8 +13810,10 @@ if(physical===undefined){
13461
13810
  rejected.push({operation:'remove',id:this.#keyOfTarget(target),reason:'unknown-id'});
13462
13811
  continue;
13463
13812
  }
13464
- result.removed.push(this.#factory.keyOf(this.#rows[physical],physical));
13465
- this.#rows[physical]=undefined;
13813
+ result.removed.push(this.#factory.keyOf(
13814
+ this.#dropped?this.#dataAt(physical):this.#rows[physical],physical,
13815
+ ));
13816
+ if(!this.#dropped)this.#rows[physical]=undefined;
13466
13817
  this.#rowCache.delete(physical);
13467
13818
  this.#quickText.delete(physical);
13468
13819
  structural=true;
@@ -13472,17 +13823,25 @@ if(change.update&&change.update.length){
13472
13823
  const totalCols=this.#running.size||this.#onlyChangedTotals()
13473
13824
  ?this.#totalColumns()
13474
13825
  :null;
13826
+ const groupCols=this.#groupRunning.size?this.#groupByColumns():null;
13827
+ const groupTotalCols=groupCols&&groupCols.length?this.#totalColumns():null;
13475
13828
  for(const next of change.update){
13476
13829
  const physical=this.#physicalOf(next);
13477
13830
  if(physical===undefined){
13478
13831
  rejected.push({operation:'update',id:this.#rowKeyOf(next),reason:'unknown-id'});
13479
13832
  continue;
13480
13833
  }
13481
- const previous=this.#rows[physical];
13834
+ const previous=this.#dropped
13835
+ ?(this.#priorRows&&this.#priorRows.has(physical)
13836
+ ?this.#priorRows.get(physical):this.#dataAt(physical))
13837
+ :this.#rows[physical];
13482
13838
  const merged=mergeRow(previous,next);
13483
13839
  for(const colId of this.#changedColumns(previous,merged))touched.add(colId);
13484
- this.#rows[physical]=merged;
13840
+ if(!this.#dropped)this.#rows[physical]=merged;
13485
13841
  if(totalCols)this.#recordDeltas(totalCols,physical,previous,merged);
13842
+ if(groupTotalCols){
13843
+ this.#recordGroupDeltas(groupCols,groupTotalCols,physical,previous,merged);
13844
+ }
13486
13845
  if(this.#keyIndex){
13487
13846
  const wasKey=this.#factory.keyOf(previous,physical);
13488
13847
  const nowKey=this.#factory.keyOf(merged,physical);
@@ -13496,7 +13855,18 @@ this.#quickText.delete(physical);
13496
13855
  result.updated.push(this.#leafRow(physical));
13497
13856
  }
13498
13857
  }
13499
- if(change.add&&change.add.length){
13858
+ if(change.add&&change.add.length&&this.#dropped){
13859
+ if(typeof change.at==='number'&&change.at<this.#physicalCount()){
13860
+ this.#rowCache.clear();
13861
+ this.#quickText.clear();
13862
+ }
13863
+ this.#keyIndex=null;
13864
+ for(const item of change.add){
13865
+ const physical=this.#byKeyIndex(this.#rowKeyOf(item));
13866
+ if(physical!==undefined)result.added.push(this.#leafRow(physical));
13867
+ }
13868
+ structural=true;
13869
+ }else if(change.add&&change.add.length){
13500
13870
  const at=typeof change.at==='number'?change.at:this.#rows.length;
13501
13871
  const before=this.#rows.length;
13502
13872
  let additions=change.add===this.#rows?change.add.slice():change.add;
@@ -13542,6 +13912,7 @@ this.#emit('rows:changed',{
13542
13912
  companion:true,
13543
13913
  added:result.added.length,updated:result.updated.length,removed:result.removed.length,
13544
13914
  });
13915
+ this.#priorRows=null;
13545
13916
  return result;
13546
13917
  }
13547
13918
  groupHeadingsAt(index){
@@ -13562,6 +13933,15 @@ chain.reverse();
13562
13933
  return chain;
13563
13934
  }
13564
13935
  moveRow(from,to){
13936
+ if(this.#dropped){
13937
+ warnOnce(
13938
+ 'source.moveRow.dropped',
13939
+ 'rows.move() is not supported under ingest.dropSourceRows: the source '
13940
+ +'objects have been released and the store cannot reorder its columns in '
13941
+ +'place. Enable retainSource (leave dropSourceRows off) to reorder rows.',
13942
+ );
13943
+ return false;
13944
+ }
13565
13945
  const rows=this.#rows;
13566
13946
  if(!Number.isInteger(from)||!Number.isInteger(to))return false;
13567
13947
  if(from<0||from>=rows.length)return false;
@@ -13606,6 +13986,7 @@ for(const name of STAGES)this.#stages.set(name,{key:null,result:null,id:0,comput
13606
13986
  }
13607
13987
  setRows(rows){
13608
13988
  this.#rows=rows||[];
13989
+ this.#dropped=false;
13609
13990
  this.#dataVersion++;
13610
13991
  this.#queryVersion++;
13611
13992
  this.#keyIndex=null;
@@ -13615,7 +13996,26 @@ this.#dropTotalState();
13615
13996
  this.#handles.invalidate();
13616
13997
  this.invalidate('filter');
13617
13998
  }
13618
- data(){return this.#rows;}
13999
+ notePriorRows(prior){
14000
+ this.#priorRows=prior||null;
14001
+ }
14002
+ releaseSource(){
14003
+ this.#dropped=true;
14004
+ this.#rows=[];
14005
+ this.#keyIndex=null;
14006
+ this.#rowCache.clear();
14007
+ this.#quickText.clear();
14008
+ this.#handles.invalidate();
14009
+ }
14010
+ data(){
14011
+ if(!this.#dropped)return this.#rows;
14012
+ const store=(this.#ctx.store);
14013
+ if(!store||!isFunction(store.source))return this.#rows;
14014
+ const n=store.physical||0;
14015
+ const out=new Array(n);
14016
+ for(let p=0;p<n;p++)out[p]=store.live&&!store.live(p)?undefined:store.source(p);
14017
+ return out;
14018
+ }
13619
14019
  #detailInline(){
13620
14020
  const detail=this.#state('detail',null);
13621
14021
  if(!detail||!isFunction(detail.isOpen)||detail.inline===false)return null;
@@ -13662,17 +14062,25 @@ const key=this.#factory.keyOf(target,-1);
13662
14062
  const found=this.#byKeyIndex(key);
13663
14063
  if(found!==undefined)return found;
13664
14064
  }
14065
+ if(this.#dropped)return undefined;
13665
14066
  const direct=this.#rows.indexOf(target);
13666
14067
  return direct>=0?direct:undefined;
13667
14068
  }
13668
14069
  #byKeyIndex(key){
13669
- if(!this.#keyIndex){
13670
- this.#keyIndex=new Map();
13671
- for(let i=0;i<this.#rows.length;i++){
13672
- if(this.#rows[i]!==undefined)this.#keyIndex.set(this.#factory.keyOf(this.#rows[i],i),i);
14070
+ if(!this.#keyIndex)this.#buildKeyIndex();
14071
+ return this.#keyIndex.get(key);
13673
14072
  }
14073
+ #buildKeyIndex(){
14074
+ this.#keyIndex=new Map();
14075
+ const n=this.#physicalCount();
14076
+ const store=(this.#ctx.store);
14077
+ const isLive=store&&isFunction(store.live)?(i)=>store.live(i):null;
14078
+ for(let i=0;i<n;i++){
14079
+ if(isLive&&!isLive(i))continue;
14080
+ const data=this.#dataAt(i);
14081
+ if(data===undefined)continue;
14082
+ this.#keyIndex.set(this.#factory.keyOf(data,i),i);
13674
14083
  }
13675
- return this.#keyIndex.get(key);
13676
14084
  }
13677
14085
  #changedColumns(previous,next){
13678
14086
  const changed=[];
@@ -13926,7 +14334,7 @@ const tuple=keys[b];
13926
14334
  let parent=null;
13927
14335
  const path=[];
13928
14336
  for(let level=0;level<tuple.length;level++){
13929
- path.push(tuple[level]===null||tuple[level]===undefined?'':String(tuple[level]));
14337
+ path.push(groupPathElement(tuple[level]));
13930
14338
  const key=groupKey(path);
13931
14339
  let node=nodes.get(key);
13932
14340
  if(!node){
@@ -13989,6 +14397,7 @@ const dirty=this.#onlyChangedTotals()&&reusable?this.#totalsDirty:null;
13989
14397
  const groupColumns=dirty?columns.filter((c)=>dirty.has(c.id)):columns;
13990
14398
  const previousGrand=reusable?this.#lastGrand:null;
13991
14399
  const unfiltered=this.#totalFilteredOnly()?null:this.#unfilteredGroups();
14400
+ const groupRunning=this.#syncGroupRunning(columns);
13992
14401
  const reduce=(row)=>{
13993
14402
  const node=grouped.nodes.get(row.key);
13994
14403
  let leaves=node&&node.leaves?node.leaves:null;
@@ -14003,9 +14412,10 @@ leaves=merged;
14003
14412
  }
14004
14413
  leaves=leaves||new Uint32Array(0);
14005
14414
  const scope=unfiltered?(unfiltered.get(row.key)||EMPTY_INDICES):leaves;
14006
- row.totals=dirty
14007
- ?{...row.totals,...this.#totalsFor(groupColumns,scope,row)}
14008
- :this.#totalsFor(columns,scope,row);
14415
+ const computed=this.#groupTotalsFor(
14416
+ row,dirty?groupColumns:columns,scope,groupRunning,
14417
+ );
14418
+ row.totals=dirty?{...row.totals,...computed}:computed;
14009
14419
  return leaves;
14010
14420
  };
14011
14421
  if(grouped.roots&&groupColumns.length)for(const root of grouped.roots)reduce(root);
@@ -14027,13 +14437,13 @@ this.#totalDeltas=[];
14027
14437
  for(const column of columns){
14028
14438
  const handle=this.#handles.handle(column.id);
14029
14439
  if(!handle)continue;
14030
- const fn=column.total;
14440
+ const fn=totalFnFor(column,'grand');
14031
14441
  if(!isIncremental(fn,handle)){
14032
14442
  if(dirty&&!dirty.has(column.id)&&carried&&column.id in carried){
14033
14443
  totals[column.id]=carried[column.id];
14034
14444
  continue;
14035
14445
  }
14036
- totals[column.id]=this.#totalsFor([column],leaves,null)[column.id];
14446
+ totals[column.id]=this.#totalsFor([column],leaves,null,'grand')[column.id];
14037
14447
  continue;
14038
14448
  }
14039
14449
  let running=this.#running.get(column.id);
@@ -14053,10 +14463,78 @@ running.invalidate();
14053
14463
  running.seedColumn(handle.values,presenceReader(handle),leaves);
14054
14464
  totals[column.id]=running.valid
14055
14465
  ?running.value()
14056
- :this.#totalsFor([column],leaves,null)[column.id];
14466
+ :this.#totalsFor([column],leaves,null,'grand')[column.id];
14057
14467
  }
14058
14468
  return totals;
14059
14469
  }
14470
+ #syncGroupRunning(columns){
14471
+ const id=this.#idOf('group');
14472
+ if(id!==this.#groupRunningId){
14473
+ this.#groupRunning.clear();
14474
+ this.#groupRunningId=id;
14475
+ }
14476
+ const incremental=new Map();
14477
+ for(const column of columns){
14478
+ const handle=this.#handles.handle(column.id);
14479
+ const fn=totalFnFor(column,'group');
14480
+ if(isIncremental(fn,handle))incremental.set(column.id,{fn:(fn)});
14481
+ }
14482
+ if(!incremental.size){this.#groupDeltas.length=0;return incremental;}
14483
+ const deltas=this.#groupDeltas;
14484
+ this.#groupDeltas=[];
14485
+ for(const record of deltas){
14486
+ const{beforeKeys,afterKeys,colDeltas}=record;
14487
+ const beforeSet=beforeKeys.length?new Set(beforeKeys):null;
14488
+ const afterSet=afterKeys.length?new Set(afterKeys):null;
14489
+ for(const{colId,before,after}of colDeltas){
14490
+ if(!incremental.has(colId))continue;
14491
+ for(const key of beforeKeys){
14492
+ if(afterSet&&afterSet.has(key))continue;
14493
+ this.#applyGroupDelta(key,colId,before,null);
14494
+ }
14495
+ for(const key of afterKeys){
14496
+ if(beforeSet&&beforeSet.has(key))continue;
14497
+ this.#applyGroupDelta(key,colId,null,after);
14498
+ }
14499
+ for(const key of beforeKeys){
14500
+ if(afterSet&&!afterSet.has(key))continue;
14501
+ this.#applyGroupDelta(key,colId,before,after);
14502
+ }
14503
+ }
14504
+ }
14505
+ return incremental;
14506
+ }
14507
+ #applyGroupDelta(key,colId,before,after){
14508
+ const perColumn=this.#groupRunning.get(key);
14509
+ const running=perColumn&&perColumn.get(colId);
14510
+ if(!running||!running.valid)return;
14511
+ if(!running.update(before,after))running.invalidate();
14512
+ }
14513
+ #groupTotalsFor(row,columns,scope,incremental){
14514
+ if(!incremental||!incremental.size)return this.#totalsFor(columns,scope,row);
14515
+ const totals={};
14516
+ let rescan=null;
14517
+ let perColumn=this.#groupRunning.get(row.key);
14518
+ for(const column of columns){
14519
+ const spec=incremental.get(column.id);
14520
+ if(!spec){(rescan||(rescan=[])).push(column);continue;}
14521
+ const handle=this.#handles.handle(column.id);
14522
+ if(!handle)continue;
14523
+ if(!perColumn){perColumn=new Map();this.#groupRunning.set(row.key,perColumn);}
14524
+ let running=perColumn.get(column.id);
14525
+ if(!running||running.fn!==spec.fn){
14526
+ running=new RunningTotal(spec.fn);
14527
+ perColumn.set(column.id,running);
14528
+ }
14529
+ if(!running.valid){
14530
+ running.seedColumn(handle.values,presenceReader(handle),scope);
14531
+ }
14532
+ if(running.valid){totals[column.id]=running.value();continue;}
14533
+ (rescan||(rescan=[])).push(column);
14534
+ }
14535
+ if(rescan)Object.assign(totals,this.#totalsFor(rescan,scope,row));
14536
+ return totals;
14537
+ }
14060
14538
  #recordDeltas(columns,physical,previous,merged){
14061
14539
  const counted=!this.#totalFilteredOnly()||this.#inFilteredSet(physical);
14062
14540
  for(const column of columns){
@@ -14071,6 +14549,41 @@ this.#totalDeltas.push({colId:column.id,before,after});
14071
14549
  }
14072
14550
  }
14073
14551
  }
14552
+ #groupByColumns(){
14553
+ const groupBy=this.#state('groupBy',[]);
14554
+ const out=[];
14555
+ for(const colId of groupBy){
14556
+ const column=this.#column(colId);
14557
+ if(column)out.push(column);
14558
+ }
14559
+ return out;
14560
+ }
14561
+ #groupPathOf(groupCols,data){
14562
+ const path=new Array(groupCols.length);
14563
+ for(let i=0;i<groupCols.length;i++){
14564
+ const read=groupCols[i].getValue;
14565
+ path[i]=groupPathElement(isFunction(read)?read(data):undefined);
14566
+ }
14567
+ return path;
14568
+ }
14569
+ #recordGroupDeltas(groupCols,columns,physical,previous,merged){
14570
+ if(this.#totalFilteredOnly()&&!this.#inFilteredSet(physical))return;
14571
+ const beforeKeys=groupPrefixKeys(this.#groupPathOf(groupCols,previous));
14572
+ const afterKeys=groupPrefixKeys(this.#groupPathOf(groupCols,merged));
14573
+ const moved=beforeKeys.length!==afterKeys.length
14574
+ ||beforeKeys.some((k,i)=>k!==afterKeys[i]);
14575
+ const colDeltas=[];
14576
+ for(const column of columns){
14577
+ const read=column.getValue;
14578
+ if(!isFunction(read))continue;
14579
+ const before=read(previous);
14580
+ const after=read(merged);
14581
+ if(!moved&&Object.is(before,after))continue;
14582
+ colDeltas.push({colId:column.id,before,after});
14583
+ }
14584
+ if(!colDeltas.length&&!moved)return;
14585
+ this.#groupDeltas.push({beforeKeys,afterKeys,colDeltas});
14586
+ }
14074
14587
  #inFilteredSet(physical){
14075
14588
  const entry=this.#stages.get('filter');
14076
14589
  const indices=(entry&&entry.computed?entry.result:null);
@@ -14121,7 +14634,7 @@ for(let b=0;b<buckets.length;b++){
14121
14634
  const tuple=keys[b];
14122
14635
  const path=[];
14123
14636
  for(let level=0;level<tuple.length;level++){
14124
- path.push(tuple[level]===null||tuple[level]===undefined?'':String(tuple[level]));
14637
+ path.push(groupPathElement(tuple[level]));
14125
14638
  const at=groupKey(path);
14126
14639
  let list=collected.get(at);
14127
14640
  if(!list){list=[];collected.set(at,list);}
@@ -14139,6 +14652,7 @@ return!!((this.#ctx.config||{}))
14139
14652
  }
14140
14653
  #dropTotalState(){
14141
14654
  this.#dropRunning();
14655
+ this.#dropGroupRunning();
14142
14656
  this.#totalsDirty=null;
14143
14657
  this.#totalsBasis=null;
14144
14658
  this.#lastGrand=null;
@@ -14148,6 +14662,11 @@ this.#running.clear();
14148
14662
  this.#totalDeltas.length=0;
14149
14663
  this.#runningId=-1;
14150
14664
  }
14665
+ #dropGroupRunning(){
14666
+ this.#groupRunning.clear();
14667
+ this.#groupDeltas.length=0;
14668
+ this.#groupRunningId=-1;
14669
+ }
14151
14670
  #runPivot(grouped){
14152
14671
  const pivotBy=this.#state('pivotBy',[]);
14153
14672
  if(!pivotBy.length){this.#pivot=null;return null;}
@@ -14165,7 +14684,7 @@ groups:grouped.keys&&grouped.buckets
14165
14684
  :null,
14166
14685
  totals:totalColumns.map((c)=>c.id),
14167
14686
  handle:(colId)=>this.#handles.handle(colId),
14168
- totalOf:(colId)=>(totalColumns.find((c)=>c.id===colId)||{}).total,
14687
+ totalOf:(colId)=>totalFnFor(totalColumns.find((c)=>c.id===colId),'group'),
14169
14688
  separator:((this.#ctx.config||{}).pivot||{}).separator,
14170
14689
  maxColumns:((this.#ctx.config||{}).pivot||{}).maxColumns,
14171
14690
  })||null;
@@ -14358,15 +14877,18 @@ return matches(text);
14358
14877
  #totalColumns(){
14359
14878
  const named=this.#state('totals',[]);
14360
14879
  const wanted=named&&named.length?new Set(named):null;
14361
- return this.#columnList().filter((c)=>(wanted?wanted.has(c.id):!!c.total));
14880
+ return this.#columnList().filter((c)=>(
14881
+ wanted?wanted.has(c.id):!!(c.total||c.groupTotal||c.grandTotal)
14882
+ ));
14362
14883
  }
14363
- #totalsFor(columns,leaves,row){
14884
+ #totalsFor(columns,leaves,row,scope='group'){
14364
14885
  const totals={};
14365
14886
  const reduce=(this.#ctx.compute||{}).total;
14366
14887
  for(const column of columns){
14367
14888
  const handle=this.#handles.handle(column.id);
14368
14889
  if(!handle)continue;
14369
- const fn=column.total;
14890
+ const fn=totalFnFor(column,scope);
14891
+ if(!fn)continue;
14370
14892
  if(isFunction(fn)){
14371
14893
  const values=new Array(leaves.length);
14372
14894
  for(let i=0;i<leaves.length;i++)values[i]=handle.get(leaves[i]);
@@ -14629,12 +15151,14 @@ this.#blocks.set(id,block);
14629
15151
  });
14630
15152
  __def("packages/core/src/source/paged.js",function(__exports,__req){
14631
15153
  'use strict';
15154
+ Object.defineProperty(__exports,"HINT_SETTLE_MS",{enumerable:true,get:function(){return HINT_SETTLE_MS;}});
14632
15155
  Object.defineProperty(__exports,"createPagedSource",{enumerable:true,get:function(){return createPagedSource;}});
14633
15156
  Object.defineProperty(__exports,"PagedSource",{enumerable:true,get:function(){return PagedSource;}});
14634
15157
  const __m0=__req("packages/core/src/internal/util.js");
14635
15158
  const Lru=__m0["Lru"];
14636
15159
  const isFunction=__m0["isFunction"];
14637
15160
  const warnOnce=__m0["warnOnce"];
15161
+ const settleDebounce=__m0["settleDebounce"];
14638
15162
  const __m1=__req("packages/core/src/source/abort.js");
14639
15163
  const createAbortScope=__m1["createAbortScope"];
14640
15164
  const isAbortError=__m1["isAbortError"];
@@ -14648,6 +15172,7 @@ const __m4=__req("packages/core/src/source/filterwire.js");
14648
15172
  const wireFilters=__m4["wireFilters"];
14649
15173
  const querySignature=__m4["querySignature"];
14650
15174
  const warnHostFilterNotApplied=__m4["warnHostFilterNotApplied"];
15175
+ const HINT_SETTLE_MS=120;
14651
15176
  function createPagedSource(config,ctx){
14652
15177
  return new PagedSource(config,ctx);
14653
15178
  }
@@ -14665,6 +15190,7 @@ mode='paged';
14665
15190
  #discovered=0;
14666
15191
  #signature='';
14667
15192
  #viewport={start:0,end:0};
15193
+ #settledFetch;
14668
15194
  #destroyed=false;
14669
15195
  constructor(config,ctx){
14670
15196
  this.#config=config||({mode:'paged'});
@@ -14675,6 +15201,10 @@ maxCachedPages:this.#config.maxCachedPages||DEFAULT_MAX_CACHED_PAGES,
14675
15201
  });
14676
15202
  this.#factory=createRowFactory((this.#ctx));
14677
15203
  this.#rows=new Lru(this.#cache.pageSize*4);
15204
+ this.#settledFetch=settleDebounce(
15205
+ (start,end)=>this.#fetchWindow(start,end),
15206
+ HINT_SETTLE_MS,
15207
+ );
14678
15208
  this.#signature=this.#querySignature();
14679
15209
  if(!isFunction(this.#config.fetch)){
14680
15210
  warnOnce('source.paged.fetch','source.mode "paged" requires a fetch function; the grid will stay empty.');
@@ -14713,11 +15243,18 @@ return this.#cache.rowLoaded(index);
14713
15243
  }
14714
15244
  hint(start,end){
14715
15245
  if(this.#destroyed)return;
14716
- this.#restartIfQueryChanged();
15246
+ const queryChanged=this.#restartIfQueryChanged();
14717
15247
  const from=Math.max(0,Math.floor(start));
14718
15248
  const to=Math.max(from,Math.floor(end));
14719
15249
  this.#viewport={start:from,end:to};
14720
15250
  this.#cache.protect(from,to);
15251
+ for(const id of this.#cache.evict())this.#forgetBlock(id);
15252
+ this.#settledFetch(from,to);
15253
+ if(queryChanged)this.#settledFetch.flush();
15254
+ }
15255
+ #fetchWindow(from,to){
15256
+ if(this.#destroyed)return;
15257
+ this.#cache.protect(from,to);
14721
15258
  const firstBlock=this.#cache.blockOf(from);
14722
15259
  const lastBlock=this.#cache.blockOf(to);
14723
15260
  for(let id=firstBlock;id<=lastBlock;id++){
@@ -14725,7 +15262,6 @@ if(this.#total!==null&&id*this.#cache.pageSize>=this.#total)break;
14725
15262
  if(this.#cache.has(id))continue;
14726
15263
  this.#fetchBlock(id);
14727
15264
  }
14728
- for(const id of this.#cache.evict())this.#forgetBlock(id);
14729
15265
  }
14730
15266
  apply(change){
14731
15267
  const result={added:[],updated:[],removed:[]};
@@ -14748,10 +15284,12 @@ return result;
14748
15284
  }
14749
15285
  reload(_opts){
14750
15286
  this.#invalidateAll('reload');
15287
+ this.#settledFetch.cancel();
14751
15288
  this.hint(this.#viewport.start,this.#viewport.end);
14752
15289
  }
14753
15290
  destroy(){
14754
15291
  this.#destroyed=true;
15292
+ this.#settledFetch.cancel();
14755
15293
  this.#scope.abortAll('destroyed');
14756
15294
  this.#cache.clear();
14757
15295
  this.#rows.clear();
@@ -14808,9 +15346,10 @@ this.#rows.delete(i);
14808
15346
  }
14809
15347
  #restartIfQueryChanged(){
14810
15348
  const signature=this.#querySignature();
14811
- if(signature===this.#signature)return;
15349
+ if(signature===this.#signature)return false;
14812
15350
  this.#signature=signature;
14813
15351
  this.#invalidateAll('query');
15352
+ return true;
14814
15353
  }
14815
15354
  #invalidateAll(reason){
14816
15355
  this.#scope.abortAll(reason);
@@ -14851,12 +15390,14 @@ if(isFunction(emit))emit(type,payload);
14851
15390
  __def("packages/core/src/source/remote.js",function(__exports,__req){
14852
15391
  'use strict';
14853
15392
  Object.defineProperty(__exports,"PROTOCOL",{enumerable:true,get:function(){return PROTOCOL;}});
15393
+ Object.defineProperty(__exports,"HINT_SETTLE_MS",{enumerable:true,get:function(){return HINT_SETTLE_MS;}});
14854
15394
  Object.defineProperty(__exports,"createRemoteSource",{enumerable:true,get:function(){return createRemoteSource;}});
14855
15395
  Object.defineProperty(__exports,"RemoteSource",{enumerable:true,get:function(){return RemoteSource;}});
14856
15396
  const __m0=__req("packages/core/src/internal/util.js");
14857
15397
  const Lru=__m0["Lru"];
14858
15398
  const isFunction=__m0["isFunction"];
14859
15399
  const warnOnce=__m0["warnOnce"];
15400
+ const settleDebounce=__m0["settleDebounce"];
14860
15401
  const __m1=__req("packages/core/src/source/abort.js");
14861
15402
  const createAbortScope=__m1["createAbortScope"];
14862
15403
  const isAbortError=__m1["isAbortError"];
@@ -14871,7 +15412,10 @@ const __m4=__req("packages/core/src/source/filterwire.js");
14871
15412
  const wireFilters=__m4["wireFilters"];
14872
15413
  const querySignature=__m4["querySignature"];
14873
15414
  const warnHostFilterNotApplied=__m4["warnHostFilterNotApplied"];
15415
+ const __m5=__req("packages/core/src/source/memory.js");
15416
+ const MemorySource=__m5["MemorySource"];
14874
15417
  const PROTOCOL=1;
15418
+ const HINT_SETTLE_MS=120;
14875
15419
  function createRemoteSource(config,ctx){
14876
15420
  return new RemoteSource(config,ctx);
14877
15421
  }
@@ -14901,16 +15445,32 @@ mode='remote';
14901
15445
  #keys=new Map();
14902
15446
  #pivotFields=[];
14903
15447
  #signature='';
15448
+ #settledFetch;
14904
15449
  #destroyed=false;
15450
+ #fullMemory=null;
15451
+ #fullFrameVersion=-1;
14905
15452
  constructor(config,ctx){
14906
15453
  this.#config=config||({mode:'remote'});
14907
15454
  this.#ctx=ctx||{};
15455
+ if(isFunction((this.#config).fullFrame)){
15456
+ this.filteredIndices=()=>this.#fullFilteredIndices();
15457
+ this.unfilteredIndices=()=>this.#fullUnfilteredIndices();
15458
+ this.handleFor=(colId)=>this.#fullHandleFor(colId);
15459
+ this.display=()=>this.#fullDisplay();
15460
+ this.grandTotalRow=()=>this.#fullGrandTotalRow();
15461
+ this.unfilteredRows=()=>this.#fullUnfilteredRows();
15462
+ this.facetIndices=(colId)=>this.#fullFacetIndices(colId);
15463
+ }
14908
15464
  this.#bounds={
14909
15465
  pageSize:this.#config.pageSize||DEFAULT_PAGE_SIZE,
14910
15466
  maxCachedPages:this.#config.maxCachedPages||DEFAULT_MAX_CACHED_PAGES,
14911
15467
  };
14912
15468
  this.#factory=createRowFactory((this.#ctx));
14913
15469
  this.#rows=new Lru(this.#bounds.pageSize*4);
15470
+ this.#settledFetch=settleDebounce(
15471
+ (start,end)=>this.#fetchWindow(start,end),
15472
+ HINT_SETTLE_MS,
15473
+ );
14914
15474
  this.#root=new GroupNode([],0,this.#bounds);
14915
15475
  this.#nodes.set(this.#root.key,this.#root);
14916
15476
  this.#signature=this.#querySignature();
@@ -14920,10 +15480,14 @@ warnOnce('source.remote.fetch','source.mode "remote" requires a fetch function;
14920
15480
  this.#warnHostFilter();
14921
15481
  }
14922
15482
  count(){
15483
+ const memory=this.#memory();
15484
+ if(memory)return memory.count();
14923
15485
  this.#restartIfQueryChanged();
14924
15486
  return this.#sizeOf(this.#root);
14925
15487
  }
14926
15488
  at(index){
15489
+ const memory=this.#memory();
15490
+ if(memory)return memory.at(index);
14927
15491
  this.#restartIfQueryChanged();
14928
15492
  if(index<0||index>=this.count())return undefined;
14929
15493
  const found=this.#locate(this.#root,index);
@@ -14933,6 +15497,8 @@ if(row)row.index=index;
14933
15497
  return row||this.#factory.skeleton(index,found.node.level);
14934
15498
  }
14935
15499
  byKey(key){
15500
+ const memory=this.#memory();
15501
+ if(memory)return memory.byKey(key);
14936
15502
  const slot=this.#keys.get(key);
14937
15503
  if(!slot)return undefined;
14938
15504
  const sep=slot.lastIndexOf(':');
@@ -14940,15 +15506,25 @@ const node=this.#nodes.get(slot.slice(0,sep));
14940
15506
  return node?this.#rowAt(node,Number(slot.slice(sep+1)))||undefined:undefined;
14941
15507
  }
14942
15508
  loaded(index){
15509
+ const memory=this.#memory();
15510
+ if(memory)return memory.loaded(index);
14943
15511
  if(index<0||index>=this.count())return false;
14944
15512
  const found=this.#locate(this.#root,index);
14945
15513
  return!!found&&found.node.cache.rowLoaded(found.local);
14946
15514
  }
14947
15515
  hint(start,end){
14948
15516
  if(this.#destroyed)return;
14949
- this.#restartIfQueryChanged();
15517
+ const queryChanged=this.#restartIfQueryChanged();
14950
15518
  const from=Math.max(0,Math.floor(start));
14951
15519
  const to=Math.max(from,Math.floor(end));
15520
+ for(const[node,span]of this.#spans(from,to)){
15521
+ node.cache.protect(span.min,span.max);
15522
+ for(const id of node.cache.evict())this.#forgetBlock(node,id);
15523
+ }
15524
+ this.#settledFetch(from,to);
15525
+ if(queryChanged)this.#settledFetch.flush();
15526
+ }
15527
+ #spans(from,to){
14952
15528
  const total=this.count();
14953
15529
  const perNode=new Map();
14954
15530
  for(let i=from;i<=to&&i<total;i++){
@@ -14959,7 +15535,11 @@ if(!span)perNode.set(found.node,{min:found.local,max:found.local});
14959
15535
  else{span.min=Math.min(span.min,found.local);span.max=Math.max(span.max,found.local);}
14960
15536
  }
14961
15537
  if(!perNode.size)perNode.set(this.#root,{min:from,max:from});
14962
- for(const[node,span]of perNode){
15538
+ return perNode;
15539
+ }
15540
+ #fetchWindow(from,to){
15541
+ if(this.#destroyed)return;
15542
+ for(const[node,span]of this.#spans(from,to)){
14963
15543
  node.cache.protect(span.min,span.max);
14964
15544
  const firstBlock=node.cache.blockOf(span.min);
14965
15545
  const lastBlock=node.cache.blockOf(span.max);
@@ -14968,7 +15548,6 @@ if(node.count!==null&&id*node.cache.pageSize>=node.count)break;
14968
15548
  if(node.cache.has(id))continue;
14969
15549
  this.#fetchBlock(node,id);
14970
15550
  }
14971
- for(const id of node.cache.evict())this.#forgetBlock(node,id);
14972
15551
  }
14973
15552
  }
14974
15553
  apply(change){
@@ -15004,16 +15583,20 @@ return result;
15004
15583
  }
15005
15584
  reload(opts){
15006
15585
  this.#scope.abortAll('reload');
15586
+ this.#settledFetch.cancel();
15007
15587
  if(opts&&opts.keepExpanded===false)this.#expanded.clear();
15008
15588
  this.#dropCaches();
15009
15589
  this.#emit('model:changed',{reason:'reload'});
15010
15590
  }
15011
15591
  destroy(){
15012
15592
  this.#destroyed=true;
15593
+ this.#settledFetch.cancel();
15013
15594
  this.#scope.abortAll('destroyed');
15014
15595
  this.#dropCaches();
15015
15596
  this.#nodes.clear();
15016
15597
  this.#expanded.clear();
15598
+ if(this.#fullMemory&&isFunction(this.#fullMemory.destroy))this.#fullMemory.destroy();
15599
+ this.#fullMemory=null;
15017
15600
  }
15018
15601
  expand(key){
15019
15602
  if(this.#expanded.has(key))return;
@@ -15028,6 +15611,65 @@ this.#emit('model:changed',{reason:'collapse',key});
15028
15611
  }
15029
15612
  expandedKeys(){return[...this.#expanded];}
15030
15613
  pivotFields(){return this.#pivotFields;}
15614
+ #fullFrame(){
15615
+ const fn=(this.#config).fullFrame;
15616
+ return isFunction(fn)?fn():null;
15617
+ }
15618
+ #memory(){
15619
+ const frame=this.#fullFrame();
15620
+ if(!frame)return null;
15621
+ if(!this.#fullMemory){
15622
+ this.#fullMemory=new MemorySource({mode:'memory'},this.#delegateCtx());
15623
+ }
15624
+ if(frame.version!==this.#fullFrameVersion){
15625
+ this.#fullMemory.setRows(frame.rows);
15626
+ this.#fullFrameVersion=frame.version;
15627
+ }
15628
+ return this.#fullMemory;
15629
+ }
15630
+ #delegateCtx(){
15631
+ const base=this.#ctx;
15632
+ const state=(base.state)||{};
15633
+ return{
15634
+ ...base,
15635
+ state:{...state,page:()=>0,pageSize:()=>0},
15636
+ };
15637
+ }
15638
+ #fullFilteredIndices(){
15639
+ const memory=this.#memory();
15640
+ return memory?memory.filteredIndices():new Uint32Array(0);
15641
+ }
15642
+ #fullUnfilteredIndices(){
15643
+ const memory=this.#memory();
15644
+ return memory?memory.unfilteredIndices():new Uint32Array(0);
15645
+ }
15646
+ #fullHandleFor(colId){
15647
+ const memory=this.#memory();
15648
+ return memory?memory.handleFor(colId):undefined;
15649
+ }
15650
+ #fullDisplay(){
15651
+ const memory=this.#memory();
15652
+ return memory?memory.display():[];
15653
+ }
15654
+ #fullFacetIndices(colId){
15655
+ const memory=this.#memory();
15656
+ return memory&&isFunction(memory.facetIndices)?memory.facetIndices(colId):new Uint32Array(0);
15657
+ }
15658
+ #fullGrandTotalRow(){
15659
+ const memory=this.#memory();
15660
+ return memory&&isFunction(memory.grandTotalRow)?memory.grandTotalRow():null;
15661
+ }
15662
+ #fullUnfilteredRows(){
15663
+ const memory=this.#memory();
15664
+ if(memory&&isFunction(memory.unfilteredRows))return memory.unfilteredRows();
15665
+ const out=[];
15666
+ const n=this.count();
15667
+ for(let i=0;i<n;i++){
15668
+ const row=this.at(i);
15669
+ if(row)out.push(row);
15670
+ }
15671
+ return out;
15672
+ }
15031
15673
  #buildRequest(node,id,signal){
15032
15674
  const{start,end}=node.cache.rangeOf(id);
15033
15675
  const groupBy=this.#state('groupBy',[]);
@@ -15176,11 +15818,12 @@ this.#rows.delete(slot);
15176
15818
  }
15177
15819
  #restartIfQueryChanged(){
15178
15820
  const signature=this.#querySignature();
15179
- if(signature===this.#signature)return;
15821
+ if(signature===this.#signature)return false;
15180
15822
  this.#signature=signature;
15181
15823
  this.#scope.abortAll('query');
15182
15824
  this.#dropCaches();
15183
15825
  this.#emit('model:changed',{reason:'query'});
15826
+ return true;
15184
15827
  }
15185
15828
  #dropCaches(){
15186
15829
  for(const node of this.#nodes.values()){
@@ -17158,6 +17801,205 @@ function createDerivedSource(config,ctx){
17158
17801
  return new DerivedSource(config,ctx);
17159
17802
  }
17160
17803
  });
17804
+ __def("packages/core/src/source/aggregates.js",function(__exports,__req){
17805
+ 'use strict';
17806
+ Object.defineProperty(__exports,"STAT_PUSHDOWN",{enumerable:true,get:function(){return STAT_PUSHDOWN;}});
17807
+ Object.defineProperty(__exports,"pushableAggregates",{enumerable:true,get:function(){return pushableAggregates;}});
17808
+ Object.defineProperty(__exports,"fillAggregateSql",{enumerable:true,get:function(){return fillAggregateSql;}});
17809
+ Object.defineProperty(__exports,"resolveAggregatesConfig",{enumerable:true,get:function(){return resolveAggregatesConfig;}});
17810
+ Object.defineProperty(__exports,"routeAggregate",{enumerable:true,get:function(){return routeAggregate;}});
17811
+ Object.defineProperty(__exports,"resolveAggregatePlan",{enumerable:true,get:function(){return resolveAggregatePlan;}});
17812
+ Object.defineProperty(__exports,"groupKeysPushable",{enumerable:true,get:function(){return groupKeysPushable;}});
17813
+ Object.defineProperty(__exports,"pushdownDocRows",{enumerable:true,get:function(){return pushdownDocRows;}});
17814
+ const STAT_PUSHDOWN=Object.freeze({
17815
+ sum:{pushable:true,class:'identical',sql:'sum(%c)'},
17816
+ avg:{pushable:true,class:'identical',sql:'avg(%c)'},
17817
+ min:{pushable:true,class:'identical',sql:'min(%c)'},
17818
+ max:{pushable:true,class:'identical',sql:'max(%c)'},
17819
+ count:{pushable:true,class:'identical',sql:'count(*)'},
17820
+ countValues:{pushable:true,class:'identical',sql:'count(%c)',blankAware:true},
17821
+ range:{pushable:true,class:'identical',sql:'(max(%c) - min(%c))'},
17822
+ variance:{pushable:true,class:'identical',sql:'var_samp(%c)'},
17823
+ varianceP:{pushable:true,class:'identical',sql:'var_pop(%c)'},
17824
+ stddev:{pushable:true,class:'identical',sql:'stddev_samp(%c)'},
17825
+ stddevP:{pushable:true,class:'identical',sql:'stddev_pop(%c)'},
17826
+ sumSquares:{pushable:true,class:'identical',sql:'sum(%c * %c)'},
17827
+ median:{pushable:true,class:'identical',sql:'median(%c)'},
17828
+ p25:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.25)'},
17829
+ p75:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.75)'},
17830
+ p90:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.9)'},
17831
+ p95:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.95)'},
17832
+ p99:{pushable:true,class:'identical',sql:'quantile_cont(%c, 0.99)'},
17833
+ iqr:{
17834
+ pushable:true,class:'identical',
17835
+ sql:'(quantile_cont(%c, 0.75) - quantile_cont(%c, 0.25))',
17836
+ },
17837
+ mad:{pushable:true,class:'identical',sql:'mad(%c)'},
17838
+ distinct:{pushable:true,class:'identical',sql:'count(DISTINCT %c)',blankAware:true},
17839
+ skewness:{pushable:true,class:'identical',sql:'skewness(%c)'},
17840
+ kurtosis:{pushable:true,class:'identical',sql:'kurtosis(%c)'},
17841
+ geomean:{pushable:true,class:'identical',sql:'exp(avg(ln(%c)))'},
17842
+ harmean:{pushable:true,class:'identical',sql:'(count(%c) / sum(1.0 / %c))'},
17843
+ entropy:{pushable:true,class:'identical',sql:'entropy(%c)',blankAware:true},
17844
+ correlation:{
17845
+ pushable:true,class:'identical',sql:'corr(%w, %c)',twoColumn:true,
17846
+ },
17847
+ hhi:{
17848
+ pushable:true,class:'identical',blankAware:true,
17849
+ sql:'CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_transform('
17850
+ +'map_values(histogram(%c)), lambda v: (v::DOUBLE/count(%c))*(v::DOUBLE/count(%c)))) END',
17851
+ },
17852
+ evenness:{
17853
+ pushable:true,class:'identical',blankAware:true,
17854
+ sql:'CASE WHEN count(%c)=0 THEN NULL WHEN count(DISTINCT %c)<2 THEN 1.0 '
17855
+ +'ELSE entropy(%c)/log2(count(DISTINCT %c)) END',
17856
+ },
17857
+ top3Share:{
17858
+ pushable:true,class:'identical',blankAware:true,
17859
+ sql:'CASE WHEN count(%c)=0 THEN NULL ELSE '
17860
+ +"list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,3))::DOUBLE/count(%c) END",
17861
+ },
17862
+ top10Share:{
17863
+ pushable:true,class:'identical',blankAware:true,
17864
+ sql:'CASE WHEN count(%c)=0 THEN NULL ELSE '
17865
+ +"list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,10))::DOUBLE/count(%c) END",
17866
+ },
17867
+ gini:{
17868
+ pushable:true,class:'identical',
17869
+ sql:'CASE WHEN list_min(list(%c) FILTER (WHERE isfinite(%c)))<0 THEN NULL '
17870
+ +'WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL '
17871
+ +'WHEN list_sum(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN 0 ELSE '
17872
+ +'2.0*list_sum(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v, i: i*v))'
17873
+ +'/(len(list(%c) FILTER (WHERE isfinite(%c)))*list_sum(list(%c) FILTER (WHERE isfinite(%c))))'
17874
+ +'-(len(list(%c) FILTER (WHERE isfinite(%c)))+1.0)/len(list(%c) FILTER (WHERE isfinite(%c))) END',
17875
+ },
17876
+ trimmedMean:{
17877
+ pushable:true,class:'identical',
17878
+ sql:'CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE '
17879
+ +'list_avg(list_slice(list_sort(list(%c) FILTER (WHERE isfinite(%c))), '
17880
+ +'floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1, '
17881
+ +'len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT)) END',
17882
+ },
17883
+ winsorizedMean:{
17884
+ pushable:true,class:'identical',
17885
+ sql:'CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE '
17886
+ +'list_avg(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v: '
17887
+ +'least(list_sort(list(%c) FILTER (WHERE isfinite(%c)))'
17888
+ +'[len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT], '
17889
+ +'greatest(list_sort(list(%c) FILTER (WHERE isfinite(%c)))'
17890
+ +'[floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1], v)))) END',
17891
+ },
17892
+ robustOutliers:{
17893
+ pushable:true,class:'identical',
17894
+ sql:'(SELECT CASE WHEN len(d.a)=0 THEN NULL WHEN d.mad=0 THEN NULL ELSE '
17895
+ +'len(list_filter(d.a, lambda v: abs(0.6745*(v-d.med)/d.mad)>3.5)) END FROM '
17896
+ +'(SELECT xs AS a, list_median(xs) AS med, '
17897
+ +'list_median(list_transform(xs, lambda w: abs(w-list_median(xs)))) AS mad '
17898
+ +'FROM (SELECT list(%c) FILTER (WHERE isfinite(%c)) AS xs)) d)',
17899
+ },
17900
+ jarqueBera:{
17901
+ pushable:true,class:'identical',
17902
+ sql:'CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))<8 THEN NULL '
17903
+ +'WHEN list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), '
17904
+ +'lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2)))=0 THEN NULL ELSE '
17905
+ +'(len(list(%c) FILTER (WHERE isfinite(%c)))/6.0)*('
17906
+ +'power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),3)))'
17907
+ +'/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),1.5),2)'
17908
+ +'+power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),4)))'
17909
+ +'/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),2)-3,2)/4.0) END',
17910
+ },
17911
+ weightedAvg:{
17912
+ pushable:true,class:'identical',twoColumn:true,
17913
+ sql:'sum(%c*%w) FILTER (WHERE isfinite(%c) AND isfinite(%w))'
17914
+ +'/nullif(sum(%w) FILTER (WHERE isfinite(%c) AND isfinite(%w)),0)',
17915
+ },
17916
+ mode:{
17917
+ pushable:true,class:'may-differ',sql:'mode(%c)',
17918
+ note:'DuckDB returns a modal value even for an all-distinct column; the grid '
17919
+ +'returns null. Tie-breaking can also differ, and on a text column an empty '
17920
+ +'string counts as a value. Under pushdown you will see a value.',
17921
+ },
17922
+ weightedQuantile:{
17923
+ pushable:false,class:'fallback',
17924
+ note:'No SQL equivalent for the grid\'s weighted-quantile midpoint convention; '
17925
+ +'always computed client-side (needs a full-dataset pull for a correct figure '
17926
+ +'over a remote source).',
17927
+ },
17928
+ });
17929
+ function pushableAggregates(){
17930
+ const set=new Set();
17931
+ for(const[name,spec]of Object.entries(STAT_PUSHDOWN))if(spec.pushable)set.add(name);
17932
+ return set;
17933
+ }
17934
+ function fillAggregateSql(template,colExpr,weightExpr){
17935
+ let out=template.split('%c').join(colExpr);
17936
+ if(weightExpr!==undefined)out=out.split('%w').join(weightExpr);
17937
+ return out;
17938
+ }
17939
+ function resolveAggregatesConfig(declared){
17940
+ const cfg=declared||{};
17941
+ const def=cfg.default==='engine'||cfg.default==='engine-if-identical'
17942
+ ?cfg.default:'client';
17943
+ const overrides={};
17944
+ if(cfg.overrides&&typeof cfg.overrides==='object'){
17945
+ for(const[name,mode]of Object.entries(cfg.overrides)){
17946
+ if(mode==='engine'||mode==='client')overrides[name]=mode;
17947
+ }
17948
+ }
17949
+ return{default:def,overrides};
17950
+ }
17951
+ function routeAggregate(fn,config){
17952
+ const spec=STAT_PUSHDOWN[fn];
17953
+ if(!spec||!spec.pushable)return'client';
17954
+ const override=config.overrides[fn];
17955
+ if(override==='engine'||override==='client')return override;
17956
+ if(config.default==='client')return'client';
17957
+ if(config.default==='engine-if-identical'){
17958
+ return spec.class==='identical'?'engine':'client';
17959
+ }
17960
+ return'engine';
17961
+ }
17962
+ function resolveAggregatePlan(requested,declared){
17963
+ const config=resolveAggregatesConfig(declared);
17964
+ const engine=[];
17965
+ const client=[];
17966
+ for(const agg of requested||[]){
17967
+ const spec=STAT_PUSHDOWN[agg.fn];
17968
+ const where=routeAggregate(agg.fn,config);
17969
+ const record={
17970
+ id:agg.id,
17971
+ col:agg.col,
17972
+ fn:agg.fn,
17973
+ class:spec?spec.class:'fallback',
17974
+ };
17975
+ if(agg.weight!==undefined)record.weight=agg.weight;
17976
+ if(agg.params!==undefined)record.params=agg.params;
17977
+ if(where==='engine'){
17978
+ engine.push(record);
17979
+ }else{
17980
+ record.reason=spec&&!spec.pushable
17981
+ ?(spec.note||'the engine cannot express this stat')
17982
+ :'client by config';
17983
+ client.push(record);
17984
+ }
17985
+ }
17986
+ return{engine,client,config};
17987
+ }
17988
+ const PLAIN_IDENTIFIER=/^[A-Za-z_][A-Za-z0-9_$]*$/;
17989
+ function groupKeysPushable(groupBy){
17990
+ const keys=groupBy||[];
17991
+ return keys.every((key)=>typeof key==='string'&&PLAIN_IDENTIFIER.test(key));
17992
+ }
17993
+ function pushdownDocRows(){
17994
+ return Object.entries(STAT_PUSHDOWN).map(([stat,spec])=>({
17995
+ stat,
17996
+ class:spec.class,
17997
+ sql:spec.sql?fillAggregateSql(spec.sql,'col',spec.twoColumn?'weight':undefined):'',
17998
+ note:spec.note||(spec.class==='identical'
17999
+ ?'Pushes to DuckDB with the same result.':''),
18000
+ }));
18001
+ }
18002
+ });
17161
18003
  __def("packages/core/src/source/pushdown.js",function(__exports,__req){
17162
18004
  'use strict';
17163
18005
  Object.defineProperty(__exports,"NO_CAPABILITIES",{enumerable:true,get:function(){return NO_CAPABILITIES;}});
@@ -17171,6 +18013,9 @@ const isFunction=__m0["isFunction"];
17171
18013
  const warnOnce=__m0["warnOnce"];
17172
18014
  const __m1=__req("packages/core/src/source/filterwire.js");
17173
18015
  const isGroup=__m1["isGroup"];
18016
+ const __m2=__req("packages/core/src/source/aggregates.js");
18017
+ const resolveAggregatePlan=__m2["resolveAggregatePlan"];
18018
+ const groupKeysPushable=__m2["groupKeysPushable"];
17174
18019
  const NO_CAPABILITIES=Object.freeze({
17175
18020
  filter:false,
17176
18021
  operators:Object.freeze([]),
@@ -17245,7 +18090,7 @@ const group=(list)=>(list.length===0?null
17245
18090
  :(list.length===1?list[0]:{op:'and',conditions:list}));
17246
18091
  return{pushed:group(pushed),residual:group(residual)};
17247
18092
  }
17248
- function planQuery(request,caps){
18093
+ function planQuery(request,caps,fullDataset=false){
17249
18094
  const filters=splitFilters(request.filters||null,caps);
17250
18095
  const unpushed=[];
17251
18096
  if(filters.residual)unpushed.push('filter');
@@ -17262,7 +18107,8 @@ filters:filters.residual,
17262
18107
  sort:sortPushable?null:wanted,
17263
18108
  quick:quickPushable?'':quick,
17264
18109
  };
17265
- const needsAll=!!(residual.filters||residual.sort||residual.quick)||!caps.range;
18110
+ const full=!!fullDataset;
18111
+ const needsAll=full||!!(residual.filters||residual.sort||residual.quick)||!caps.range;
17266
18112
  const pushed={
17267
18113
  ...request,
17268
18114
  filters:filters.pushed,
@@ -17270,7 +18116,7 @@ sort:sortPushable?wanted:[],
17270
18116
  quick:quickPushable?quick:'',
17271
18117
  range:needsAll?null:request.range,
17272
18118
  };
17273
- return{pushed,residual,needsAll,unpushed};
18119
+ return{pushed,residual,needsAll,unpushed,full};
17274
18120
  }
17275
18121
  function applyResidual(rows,residual,compute){
17276
18122
  if(!residual)return rows;
@@ -17320,6 +18166,21 @@ groupPath:pushed.groupPath||[],
17320
18166
  context:pushed.context??null,
17321
18167
  });
17322
18168
  }
18169
+ function estimateRowBytes(row){
18170
+ if(!row||typeof row!=='object')return 16;
18171
+ let text='';
18172
+ try{text=JSON.stringify(row);}catch{return 200;}
18173
+ return text.length*2+64;
18174
+ }
18175
+ function resolveFullDataset(declared){
18176
+ const cfg=declared||{};
18177
+ return{
18178
+ enabled:!!cfg.enabled,
18179
+ maxRows:Number.isFinite(cfg.maxRows)?cfg.maxRows:1_000_000,
18180
+ maxBytesEstimate:Number.isFinite(cfg.maxBytesEstimate)
18181
+ ?cfg.maxBytesEstimate:512*1024*1024,
18182
+ };
18183
+ }
17323
18184
  function createPushdownSource(config={}){
17324
18185
  const adapter=config.adapter;
17325
18186
  if(!adapter||!isFunction(adapter.execute)){
@@ -17329,10 +18190,24 @@ return{...config,mode:'remote',fetch:async()=>({rows:[],total:0})};
17329
18190
  }
17330
18191
  const caps=capabilitiesOf(adapter.capabilities);
17331
18192
  const name=adapter.name||'adapter';
18193
+ const full=resolveFullDataset(config.fullDataset);
18194
+ const allowPartialResults=!!config.allowPartialResults;
18195
+ const aggregatesConfig=config.aggregates;
17332
18196
  let held=null;
17333
18197
  let lastPlan=null;
18198
+ let lastAggregates=null;
18199
+ let heldVersion=0;
18200
+ let heldVersionKey=null;
18201
+ const fullFrame=()=>{
18202
+ if(!full.enabled||!held)return null;
18203
+ if(heldVersionKey!==held.key){
18204
+ heldVersion++;
18205
+ heldVersionKey=held.key;
18206
+ }
18207
+ return{rows:held.rows,version:heldVersion};
18208
+ };
17334
18209
  const fetch=async(request)=>{
17335
- const plan=planQuery(request,caps);
18210
+ const plan=planQuery(request,caps,full.enabled);
17336
18211
  lastPlan=plan;
17337
18212
  if(!plan.needsAll){
17338
18213
  const result=await adapter.execute(plan.pushed,request);
@@ -17348,21 +18223,51 @@ const key=planKey(plan.pushed);
17348
18223
  if(!held||held.key!==key){
17349
18224
  const result=await adapter.execute(plan.pushed,request);
17350
18225
  const rows=result.rows||[];
18226
+ if(plan.full){
18227
+ const matching=typeof result.total==='number'
18228
+ ?Math.max(result.total,rows.length):rows.length;
18229
+ if(matching>full.maxRows){
18230
+ throw new Error(
18231
+ `[lattice] fullDataset refused: the ${name} adapter's matching set is `
18232
+ +`${matching.toLocaleString()} rows, past the configured maxRows of `
18233
+ +`${full.maxRows.toLocaleString()}. The whole set cannot be held client-side, so it `
18234
+ +'is refused rather than truncated — a fraction shown as the whole would make every '
18235
+ +'total and statistic silently wrong. Narrow the filter or raise maxRows.');
18236
+ }
18237
+ const bytes=rows.length*estimateRowBytes(rows[0]);
18238
+ if(bytes>full.maxBytesEstimate){
18239
+ throw new Error(
18240
+ `[lattice] fullDataset refused: the ${name} adapter's matching set is an estimated `
18241
+ +`${Math.round(bytes/(1024*1024)).toLocaleString()} MB across `
18242
+ +`${rows.length.toLocaleString()} rows, past the configured maxBytesEstimate of `
18243
+ +`${Math.round(full.maxBytesEstimate/(1024*1024)).toLocaleString()} MB. The whole `
18244
+ +'set cannot be held client-side, so it is refused rather than truncated. Narrow the '
18245
+ +'filter or raise maxBytesEstimate.');
18246
+ }
18247
+ }
17351
18248
  if(typeof result.total==='number'&&rows.length<result.total){
17352
18249
  const hasResidual=!!(plan.residual.filters||plan.residual.quick
17353
18250
  ||(plan.residual.sort&&plan.residual.sort.length));
17354
- if(hasResidual){
18251
+ if(hasResidual&&!allowPartialResults){
17355
18252
  throw new Error(
17356
18253
  `[lattice] the ${name} adapter returned ${rows.length} of ${result.total} matching `
17357
18254
  +'rows when asked for the whole result, and the query has residual '
17358
18255
  +`${plan.unpushed.join(' and ')||'work'} to finish in the browser. Filtering or `
17359
18256
  +'sorting a fraction of the result would return wrong rows, so the result is refused. '
17360
- +'The adapter must follow the engine\'s own paging before returning.');
17361
- }
18257
+ +'Fix the adapter to follow the engine\'s own paging before returning, hold the data in '
18258
+ +'memory, or set `allowPartialResults: true` on the source config to accept this knowingly.');
18259
+ }else if(hasResidual){
18260
+ warnOnce(`source.pushdown.partial.residual.${name}`,
18261
+ `the ${name} adapter returned ${rows.length} of ${result.total} matching rows when asked `
18262
+ +'for the whole result, and residual work will run over that fraction. '
18263
+ +'allowPartialResults is set, so the result is used as-is — it may be wrong. '
18264
+ +'The adapter must follow the engine\'s own paging to be correct.');
18265
+ }else{
17362
18266
  warnOnce(`source.pushdown.partial.${name}`,
17363
18267
  `the ${name} adapter returned ${rows.length} of ${result.total} matching rows when asked `
17364
18268
  +'for the whole result. The adapter must follow the engine\'s own paging before returning.');
17365
18269
  }
18270
+ }
17366
18271
  held={key,rows};
17367
18272
  }
17368
18273
  const rows=applyResidual(held.rows,plan.residual,config.compute||{});
@@ -17370,11 +18275,56 @@ const start=request.range?request.range.start:0;
17370
18275
  const end=request.range?request.range.end:rows.length;
17371
18276
  return{rows:rows.slice(start,end),total:rows.length};
17372
18277
  };
18278
+ const aggregate=async(request,requested)=>{
18279
+ const plan=planQuery(request,caps,full.enabled);
18280
+ lastPlan=plan;
18281
+ const split=resolveAggregatePlan(requested,aggregatesConfig);
18282
+ const groupBy=Array.isArray(request.groupBy)?request.groupBy:[];
18283
+ const grouped=groupBy.length>0;
18284
+ const filterFullyPushed=!plan.residual.filters;
18285
+ const groupingPushable=!grouped||groupKeysPushable(groupBy);
18286
+ let engine=split.engine;
18287
+ let client=split.client;
18288
+ const fallAllToClient=(reason)=>{
18289
+ client=[...engine.map((agg)=>({...agg,reason})),...client];
18290
+ engine=[];
18291
+ };
18292
+ if(engine.length&&!filterFullyPushed){
18293
+ fallAllToClient('residual filter forces all-client (no mixed provenance)');
18294
+ }else if(engine.length&&!groupingPushable){
18295
+ fallAllToClient('a grouping key the engine cannot form forces all-client (no mixed provenance)');
18296
+ }
18297
+ let values={};
18298
+ let groups;
18299
+ if(engine.length){
18300
+ const canCompute=grouped
18301
+ ?isFunction(adapter.executeGroupedAggregates)
18302
+ :isFunction(adapter.executeAggregates);
18303
+ if(!canCompute){
18304
+ warnOnce(`source.pushdown.aggregates.${name}${grouped?'.grouped':''}`,
18305
+ `the ${name} adapter cannot compute ${grouped?'grouped ':''}aggregates, so every `
18306
+ +'requested statistic is computed client-side. Correct, and slower than it needs to be.');
18307
+ fallAllToClient(`adapter cannot compute ${grouped?'grouped ':''}aggregates`);
18308
+ }else if(grouped){
18309
+ groups=await adapter.executeGroupedAggregates(plan.pushed,groupBy,engine)||[];
18310
+ }else{
18311
+ values=await adapter.executeAggregates(plan.pushed,engine)||{};
18312
+ }
18313
+ }
18314
+ lastAggregates={engine,client,...(grouped?{groupBy}:{})};
18315
+ return{
18316
+ values,engine,client,...(groups!==undefined?{groups}:{}),
18317
+ };
18318
+ };
17373
18319
  return{
17374
18320
  ...config,
17375
18321
  mode:'remote',
17376
18322
  fetch,
17377
- lastPlan:()=>lastPlan,
18323
+ aggregate,
18324
+ lastPlan:()=>(lastPlan
18325
+ ?{...lastPlan,...(lastAggregates?{aggregates:lastAggregates}:{})}
18326
+ :null),
18327
+ fullFrame,
17378
18328
  };
17379
18329
  }
17380
18330
  });
@@ -17625,6 +18575,11 @@ const isFunction=__m0["isFunction"];
17625
18575
  const warnOnce=__m0["warnOnce"];
17626
18576
  const __m1=__req("packages/core/src/source/filterwire.js");
17627
18577
  const isGroup=__m1["isGroup"];
18578
+ const __m2=__req("packages/core/src/source/aggregates.js");
18579
+ const STAT_PUSHDOWN=__m2["STAT_PUSHDOWN"];
18580
+ const fillAggregateSql=__m2["fillAggregateSql"];
18581
+ const pushableAggregates=__m2["pushableAggregates"];
18582
+ const groupKeysPushable=__m2["groupKeysPushable"];
17628
18583
  const OPERATORS=Object.freeze([
17629
18584
  'eq','ne','gt','gte','lt','lte','contains','startsWith','endsWith',
17630
18585
  'blank','notBlank','in',
@@ -17686,6 +18641,7 @@ sort:'multi',
17686
18641
  quick:false,
17687
18642
  range:true,
17688
18643
  total:true,
18644
+ aggregates:pushableAggregates(),
17689
18645
  },
17690
18646
  sqlFor(query){
17691
18647
  const params=[];
@@ -17735,8 +18691,120 @@ return plain;
17735
18691
  });
17736
18692
  return{rows,total:total===null?rows.length:total};
17737
18693
  },
18694
+ aggregateSqlFor(query,aggregates){
18695
+ const params=[];
18696
+ const where=filtersToSql(query.filters,params);
18697
+ const exprs=aggregateExprs(aggregates);
18698
+ let sql=`SELECT ${exprs.join(', ')} FROM ${from}`;
18699
+ if(where)sql+=` WHERE ${where}`;
18700
+ return{sql,params};
18701
+ },
18702
+ groupedAggregateSqlFor(query,groupBy,aggregates){
18703
+ const keys=Array.isArray(groupBy)?groupBy:[];
18704
+ if(!keys.length)throw new Error('duckdbAdapter: grouped aggregate needs a grouping key');
18705
+ if(!groupKeysPushable(keys)){
18706
+ throw new Error('duckdbAdapter: a grouping key is not a plain column the engine can group by');
18707
+ }
18708
+ const params=[];
18709
+ const where=filtersToSql(query.filters,params);
18710
+ const keyCols=keys.map((unused,i)=>`__lattice_k${i}`);
18711
+ const groupingCols=keys.map((unused,i)=>`__lattice_g${i}`);
18712
+ const keySelect=keys.map((key,i)=>`${ident(key)} AS ${ident(keyCols[i])}`);
18713
+ const groupingSelect=keys
18714
+ .map((key,i)=>`GROUPING(${ident(key)}) AS ${ident(groupingCols[i])}`);
18715
+ const aggExprs=aggregateExprs(aggregates);
18716
+ const rollup=`ROLLUP(${keys.map((key)=>ident(key)).join(', ')})`;
18717
+ let sql=`SELECT ${[...keySelect,...groupingSelect,...aggExprs].join(', ')} FROM ${from}`;
18718
+ if(where)sql+=` WHERE ${where}`;
18719
+ sql+=` GROUP BY ${rollup}`;
18720
+ return{sql,params,keyCols,groupingCols};
18721
+ },
18722
+ async executeGroupedAggregates(query,groupBy,aggregates){
18723
+ if(!connection||!isFunction(connection.query)){
18724
+ throw new Error('duckdbAdapter needs a connection with a query function');
18725
+ }
18726
+ const{
18727
+ sql,params,keyCols,groupingCols,
18728
+ }=this.groupedAggregateSqlFor(query,groupBy,aggregates);
18729
+ let result;
18730
+ if(params.length&&isFunction(connection.prepare)){
18731
+ const statement=await connection.prepare(sql);
18732
+ try{
18733
+ result=await statement.query(...params);
18734
+ }finally{
18735
+ if(isFunction(statement.close))await statement.close();
18736
+ }
18737
+ }else{
18738
+ if(params.length){
18739
+ warnOnce('source.duckdb.unprepared.grouped',
18740
+ 'this DuckDB connection has no prepare(), so filter values cannot be bound. '
18741
+ +'Grouped aggregates are not pushed rather than being interpolated into SQL.');
18742
+ return[];
18743
+ }
18744
+ result=await connection.query(sql);
18745
+ }
18746
+ const raw=isFunction(result.toArray)?result.toArray():Array.from(result||[]);
18747
+ return raw.map((row)=>{
18748
+ const plain=isFunction(row.toJSON)?row.toJSON():{...row};
18749
+ const grouping=groupingCols.map((c)=>Number(normalise(plain[c])));
18750
+ const keys=keyCols.map((c)=>normalise(plain[c]));
18751
+ const level=grouping.reduce((acc,flag)=>acc+(flag?0:1),0);
18752
+ const values={};
18753
+ for(const key of Object.keys(plain)){
18754
+ if(keyCols.includes(key)||groupingCols.includes(key))continue;
18755
+ values[key]=normalise(plain[key]);
18756
+ }
18757
+ return{keys,grouping,level,values};
18758
+ });
18759
+ },
18760
+ async executeAggregates(query,aggregates){
18761
+ if(!connection||!isFunction(connection.query)){
18762
+ throw new Error('duckdbAdapter needs a connection with a query function');
18763
+ }
18764
+ const{sql,params}=this.aggregateSqlFor(query,aggregates);
18765
+ let result;
18766
+ if(params.length&&isFunction(connection.prepare)){
18767
+ const statement=await connection.prepare(sql);
18768
+ try{
18769
+ result=await statement.query(...params);
18770
+ }finally{
18771
+ if(isFunction(statement.close))await statement.close();
18772
+ }
18773
+ }else{
18774
+ if(params.length){
18775
+ warnOnce('source.duckdb.unprepared.aggregates',
18776
+ 'this DuckDB connection has no prepare(), so filter values cannot be bound. '
18777
+ +'Aggregates are not pushed rather than being interpolated into SQL.');
18778
+ return{};
18779
+ }
18780
+ result=await connection.query(sql);
18781
+ }
18782
+ const raw=isFunction(result.toArray)?result.toArray():Array.from(result||[]);
18783
+ const first=raw[0];
18784
+ if(!first)return{};
18785
+ const plain=isFunction(first.toJSON)?first.toJSON():{...first};
18786
+ const out={};
18787
+ for(const key of Object.keys(plain))out[key]=normalise(plain[key]);
18788
+ return out;
18789
+ },
17738
18790
  };
17739
18791
  }
18792
+ function aggregateExprs(aggregates){
18793
+ const exprs=(aggregates||[]).map((agg)=>{
18794
+ const spec=STAT_PUSHDOWN[agg.fn];
18795
+ if(!spec||!spec.pushable||!spec.sql){
18796
+ throw new Error(`duckdbAdapter: cannot push aggregate "${agg.fn}"`);
18797
+ }
18798
+ const wrap=(colName)=>(spec.blankAware
18799
+ ?`nullif(CAST(${ident(colName)} AS VARCHAR), '')`:ident(colName));
18800
+ const col=wrap(agg.col);
18801
+ const weight=agg.weight!==undefined?wrap(agg.weight):undefined;
18802
+ const body=fillAggregateSql(spec.sql,col,weight);
18803
+ return`${body} AS ${ident(agg.id)}`;
18804
+ });
18805
+ if(!exprs.length)throw new Error('duckdbAdapter: no aggregates to compute');
18806
+ return exprs;
18807
+ }
17740
18808
  });
17741
18809
  __def("packages/core/src/source/index.js",function(__exports,__req){
17742
18810
  'use strict';
@@ -17800,51 +18868,60 @@ Object.defineProperty(__exports,"dfqlAdapter",{enumerable:true,get:function(){re
17800
18868
  const __m10=__req("packages/core/src/source/adapters/duckdb.js");
17801
18869
  Object.defineProperty(__exports,"duckdbAdapter",{enumerable:true,get:function(){return __m10["duckdbAdapter"];}});
17802
18870
  Object.defineProperty(__exports,"filtersToSql",{enumerable:true,get:function(){return __m10["filtersToSql"];}});
17803
- const __m11=__req("packages/core/src/source/derive.js");
17804
- Object.defineProperty(__exports,"derive",{enumerable:true,get:function(){return __m11["derive"];}});
17805
- Object.defineProperty(__exports,"unnest",{enumerable:true,get:function(){return __m11["unnest"];}});
17806
- Object.defineProperty(__exports,"readPath",{enumerable:true,get:function(){return __m11["readPath"];}});
17807
- Object.defineProperty(__exports,"bucketOf",{enumerable:true,get:function(){return __m11["bucketOf"];}});
17808
- Object.defineProperty(__exports,"applyLimit",{enumerable:true,get:function(){return __m11["applyLimit"];}});
17809
- Object.defineProperty(__exports,"applyCumulative",{enumerable:true,get:function(){return __m11["applyCumulative"];}});
17810
- Object.defineProperty(__exports,"reduceValues",{enumerable:true,get:function(){return __m11["reduceValues"];}});
17811
- Object.defineProperty(__exports,"FOLLOW_MODES",{enumerable:true,get:function(){return __m11["FOLLOW_MODES"];}});
17812
- Object.defineProperty(__exports,"BUCKETS",{enumerable:true,get:function(){return __m11["BUCKETS"];}});
17813
- Object.defineProperty(__exports,"DERIVED_ROW_KEY",{enumerable:true,get:function(){return __m11["DERIVED_ROW_KEY"];}});
17814
- const __m12=__req("packages/core/src/source/abort.js");
17815
- Object.defineProperty(__exports,"AbortScope",{enumerable:true,get:function(){return __m12["AbortScope"];}});
17816
- Object.defineProperty(__exports,"RequestToken",{enumerable:true,get:function(){return __m12["RequestToken"];}});
17817
- Object.defineProperty(__exports,"SupersededError",{enumerable:true,get:function(){return __m12["SupersededError"];}});
17818
- Object.defineProperty(__exports,"createAbortScope",{enumerable:true,get:function(){return __m12["createAbortScope"];}});
17819
- Object.defineProperty(__exports,"isAbortError",{enumerable:true,get:function(){return __m12["isAbortError"];}});
17820
- const __m13=__req("packages/core/src/source/filterwire.js");
17821
- Object.defineProperty(__exports,"RELATIVE_TOKENS",{enumerable:true,get:function(){return __m13["RELATIVE_TOKENS"];}});
17822
- Object.defineProperty(__exports,"parseRelativeToken",{enumerable:true,get:function(){return __m13["parseRelativeToken"];}});
17823
- Object.defineProperty(__exports,"resolveRelativeRange",{enumerable:true,get:function(){return __m13["resolveRelativeRange"];}});
17824
- Object.defineProperty(__exports,"resolveRelativeCondition",{enumerable:true,get:function(){return __m13["resolveRelativeCondition"];}});
17825
- Object.defineProperty(__exports,"relativeTokenOf",{enumerable:true,get:function(){return __m13["relativeTokenOf"];}});
17826
- Object.defineProperty(__exports,"buildFilterSet",{enumerable:true,get:function(){return __m13["buildFilterSet"];}});
17827
- Object.defineProperty(__exports,"normaliseFilterSet",{enumerable:true,get:function(){return __m13["normaliseFilterSet"];}});
17828
- Object.defineProperty(__exports,"wireFilters",{enumerable:true,get:function(){return __m13["wireFilters"];}});
17829
- Object.defineProperty(__exports,"querySignature",{enumerable:true,get:function(){return __m13["querySignature"];}});
17830
- Object.defineProperty(__exports,"mapConditions",{enumerable:true,get:function(){return __m13["mapConditions"];}});
17831
- Object.defineProperty(__exports,"forEachCondition",{enumerable:true,get:function(){return __m13["forEachCondition"];}});
17832
- Object.defineProperty(__exports,"isGroup",{enumerable:true,get:function(){return __m13["isGroup"];}});
17833
- const __m14=__req("packages/core/src/source/blockcache.js");
17834
- Object.defineProperty(__exports,"BlockCache",{enumerable:true,get:function(){return __m14["BlockCache"];}});
17835
- Object.defineProperty(__exports,"DEFAULT_PAGE_SIZE",{enumerable:true,get:function(){return __m14["DEFAULT_PAGE_SIZE"];}});
17836
- Object.defineProperty(__exports,"DEFAULT_MAX_CACHED_PAGES",{enumerable:true,get:function(){return __m14["DEFAULT_MAX_CACHED_PAGES"];}});
17837
- const __m15=__req("packages/core/src/source/gapbuffer.js");
17838
- Object.defineProperty(__exports,"GapBuffer",{enumerable:true,get:function(){return __m15["GapBuffer"];}});
17839
- const __m16=__req("packages/core/src/source/rows.js");
17840
- Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return __m16["RowFactory"];}});
17841
- Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function(){return __m16["createRowFactory"];}});
17842
- Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return __m16["groupKey"];}});
17843
- Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return __m16["lazyRowView"];}});
17844
- Object.defineProperty(__exports,"DEFAULT_ROW_HEIGHT",{enumerable:true,get:function(){return __m16["DEFAULT_ROW_HEIGHT"];}});
17845
- const __m17=__req("packages/core/src/source/handles.js");
17846
- Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function(){return __m17["HandleProvider"];}});
17847
- Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return __m17["createHandleProvider"];}});
18871
+ const __m11=__req("packages/core/src/source/aggregates.js");
18872
+ Object.defineProperty(__exports,"STAT_PUSHDOWN",{enumerable:true,get:function(){return __m11["STAT_PUSHDOWN"];}});
18873
+ Object.defineProperty(__exports,"pushableAggregates",{enumerable:true,get:function(){return __m11["pushableAggregates"];}});
18874
+ Object.defineProperty(__exports,"resolveAggregatePlan",{enumerable:true,get:function(){return __m11["resolveAggregatePlan"];}});
18875
+ Object.defineProperty(__exports,"resolveAggregatesConfig",{enumerable:true,get:function(){return __m11["resolveAggregatesConfig"];}});
18876
+ Object.defineProperty(__exports,"routeAggregate",{enumerable:true,get:function(){return __m11["routeAggregate"];}});
18877
+ Object.defineProperty(__exports,"fillAggregateSql",{enumerable:true,get:function(){return __m11["fillAggregateSql"];}});
18878
+ Object.defineProperty(__exports,"pushdownDocRows",{enumerable:true,get:function(){return __m11["pushdownDocRows"];}});
18879
+ Object.defineProperty(__exports,"groupKeysPushable",{enumerable:true,get:function(){return __m11["groupKeysPushable"];}});
18880
+ const __m12=__req("packages/core/src/source/derive.js");
18881
+ Object.defineProperty(__exports,"derive",{enumerable:true,get:function(){return __m12["derive"];}});
18882
+ Object.defineProperty(__exports,"unnest",{enumerable:true,get:function(){return __m12["unnest"];}});
18883
+ Object.defineProperty(__exports,"readPath",{enumerable:true,get:function(){return __m12["readPath"];}});
18884
+ Object.defineProperty(__exports,"bucketOf",{enumerable:true,get:function(){return __m12["bucketOf"];}});
18885
+ Object.defineProperty(__exports,"applyLimit",{enumerable:true,get:function(){return __m12["applyLimit"];}});
18886
+ Object.defineProperty(__exports,"applyCumulative",{enumerable:true,get:function(){return __m12["applyCumulative"];}});
18887
+ Object.defineProperty(__exports,"reduceValues",{enumerable:true,get:function(){return __m12["reduceValues"];}});
18888
+ Object.defineProperty(__exports,"FOLLOW_MODES",{enumerable:true,get:function(){return __m12["FOLLOW_MODES"];}});
18889
+ Object.defineProperty(__exports,"BUCKETS",{enumerable:true,get:function(){return __m12["BUCKETS"];}});
18890
+ Object.defineProperty(__exports,"DERIVED_ROW_KEY",{enumerable:true,get:function(){return __m12["DERIVED_ROW_KEY"];}});
18891
+ const __m13=__req("packages/core/src/source/abort.js");
18892
+ Object.defineProperty(__exports,"AbortScope",{enumerable:true,get:function(){return __m13["AbortScope"];}});
18893
+ Object.defineProperty(__exports,"RequestToken",{enumerable:true,get:function(){return __m13["RequestToken"];}});
18894
+ Object.defineProperty(__exports,"SupersededError",{enumerable:true,get:function(){return __m13["SupersededError"];}});
18895
+ Object.defineProperty(__exports,"createAbortScope",{enumerable:true,get:function(){return __m13["createAbortScope"];}});
18896
+ Object.defineProperty(__exports,"isAbortError",{enumerable:true,get:function(){return __m13["isAbortError"];}});
18897
+ const __m14=__req("packages/core/src/source/filterwire.js");
18898
+ Object.defineProperty(__exports,"RELATIVE_TOKENS",{enumerable:true,get:function(){return __m14["RELATIVE_TOKENS"];}});
18899
+ Object.defineProperty(__exports,"parseRelativeToken",{enumerable:true,get:function(){return __m14["parseRelativeToken"];}});
18900
+ Object.defineProperty(__exports,"resolveRelativeRange",{enumerable:true,get:function(){return __m14["resolveRelativeRange"];}});
18901
+ Object.defineProperty(__exports,"resolveRelativeCondition",{enumerable:true,get:function(){return __m14["resolveRelativeCondition"];}});
18902
+ Object.defineProperty(__exports,"relativeTokenOf",{enumerable:true,get:function(){return __m14["relativeTokenOf"];}});
18903
+ Object.defineProperty(__exports,"buildFilterSet",{enumerable:true,get:function(){return __m14["buildFilterSet"];}});
18904
+ Object.defineProperty(__exports,"normaliseFilterSet",{enumerable:true,get:function(){return __m14["normaliseFilterSet"];}});
18905
+ Object.defineProperty(__exports,"wireFilters",{enumerable:true,get:function(){return __m14["wireFilters"];}});
18906
+ Object.defineProperty(__exports,"querySignature",{enumerable:true,get:function(){return __m14["querySignature"];}});
18907
+ Object.defineProperty(__exports,"mapConditions",{enumerable:true,get:function(){return __m14["mapConditions"];}});
18908
+ Object.defineProperty(__exports,"forEachCondition",{enumerable:true,get:function(){return __m14["forEachCondition"];}});
18909
+ Object.defineProperty(__exports,"isGroup",{enumerable:true,get:function(){return __m14["isGroup"];}});
18910
+ const __m15=__req("packages/core/src/source/blockcache.js");
18911
+ Object.defineProperty(__exports,"BlockCache",{enumerable:true,get:function(){return __m15["BlockCache"];}});
18912
+ Object.defineProperty(__exports,"DEFAULT_PAGE_SIZE",{enumerable:true,get:function(){return __m15["DEFAULT_PAGE_SIZE"];}});
18913
+ Object.defineProperty(__exports,"DEFAULT_MAX_CACHED_PAGES",{enumerable:true,get:function(){return __m15["DEFAULT_MAX_CACHED_PAGES"];}});
18914
+ const __m16=__req("packages/core/src/source/gapbuffer.js");
18915
+ Object.defineProperty(__exports,"GapBuffer",{enumerable:true,get:function(){return __m16["GapBuffer"];}});
18916
+ const __m17=__req("packages/core/src/source/rows.js");
18917
+ Object.defineProperty(__exports,"RowFactory",{enumerable:true,get:function(){return __m17["RowFactory"];}});
18918
+ Object.defineProperty(__exports,"createRowFactory",{enumerable:true,get:function(){return __m17["createRowFactory"];}});
18919
+ Object.defineProperty(__exports,"groupKey",{enumerable:true,get:function(){return __m17["groupKey"];}});
18920
+ Object.defineProperty(__exports,"lazyRowView",{enumerable:true,get:function(){return __m17["lazyRowView"];}});
18921
+ Object.defineProperty(__exports,"DEFAULT_ROW_HEIGHT",{enumerable:true,get:function(){return __m17["DEFAULT_ROW_HEIGHT"];}});
18922
+ const __m18=__req("packages/core/src/source/handles.js");
18923
+ Object.defineProperty(__exports,"HandleProvider",{enumerable:true,get:function(){return __m18["HandleProvider"];}});
18924
+ Object.defineProperty(__exports,"createHandleProvider",{enumerable:true,get:function(){return __m18["createHandleProvider"];}});
17848
18925
  const MODES=Object.freeze(['memory','paged','remote','stream','derived']);
17849
18926
  function createSource(config,ctx){
17850
18927
  if(!ctx)fail('createSource requires a SourceContext');
@@ -20575,6 +21652,12 @@ if(pinFrom!==pinTo)pinned.push({id,from:pinFrom,to:pinTo});
20575
21652
  const totalFrom=source.total??null;
20576
21653
  const totalTo=target.total??null;
20577
21654
  if(totalFrom!==totalTo)totals.push({id,from:totalFrom,to:totalTo});
21655
+ const groupFrom=source.groupTotal??null;
21656
+ const groupTo=target.groupTotal??null;
21657
+ if(groupFrom!==groupTo)totals.push({id,scope:'group',from:groupFrom,to:groupTo});
21658
+ const grandFrom=source.grandTotal??null;
21659
+ const grandTo=target.grandTotal??null;
21660
+ if(grandFrom!==grandTo)totals.push({id,scope:'grand',from:grandFrom,to:grandTo});
20578
21661
  }
20579
21662
  const missing=[...from.keys()].filter((id)=>!to.has(id));
20580
21663
  const extra=[...to.keys()].filter((id)=>!from.has(id));
@@ -27952,6 +29035,7 @@ const cancelFrame=__m0["cancelFrame"];
27952
29035
  const whenIdle=__m0["whenIdle"];
27953
29036
  const now=__m0["now"];
27954
29037
  const getPath=__m0["getPath"];
29038
+ const DEV=__m0["DEV"];
27955
29039
  const __m1=__req("packages/core/src/events/bus.js");
27956
29040
  const EventBus=__m1["EventBus"];
27957
29041
  const __m2=__req("packages/core/src/registry/registry.js");
@@ -28192,6 +29276,7 @@ quickFilterText:'string',
28192
29276
  sampleSize:'number',
28193
29277
  sharedMemory:'boolean',
28194
29278
  shortcuts:'boolean',
29279
+ stripedRows:'boolean',
28195
29280
  showColumnFunctions:'boolean',
28196
29281
  showHeader:'boolean',
28197
29282
  showTotalInHeader:'boolean',
@@ -28285,7 +29370,7 @@ const KNOWN_CONFIG_KEYS=new Set([
28285
29370
  'quickFilterText','rangeChart','responsive','rowClass','rowForm','rowHeight','rowKey',
28286
29371
  'rowReorder','rowStyle','rowTemplate','rowTransfer','rows','sampleSize',
28287
29372
  'selection','sharedMemory','shortcuts','showColumnFunctions','showHeader',
28288
- 'showTotalInHeader','source','state','statusBar','stickyGroupHeaders',
29373
+ 'showTotalInHeader','source','state','statusBar','stickyGroupHeaders','stripedRows',
28289
29374
  'targetSize','theme','timeZone','title','toolPanel','totalFilteredOnly',
28290
29375
  'totalFns','totalOnlyChangedColumns','tree','typeOptions','updates','useWorker',
28291
29376
  'variants','views','workerThreshold','workerUrl',
@@ -28297,7 +29382,7 @@ direction:undefined,
28297
29382
  theme:'light',
28298
29383
  density:'compact',
28299
29384
  rowHeight:null,
28300
- headerHeight:32,
29385
+ headerHeight:null,
28301
29386
  overscan:4,
28302
29387
  columnVirtualisationAbove:30,
28303
29388
  workerThreshold:50_000,
@@ -28318,6 +29403,8 @@ class Grid{
28318
29403
  #store=null;
28319
29404
  #pool;
28320
29405
  #source;
29406
+ #sourceIdCache=null;
29407
+ static#nextSourceId=1;
28321
29408
  #rowModel;
28322
29409
  #selection;
28323
29410
  #ranges;
@@ -28906,7 +29993,7 @@ this.#inferTypes(config.rows);
28906
29993
  if(sourceConfig.mode==='memory'||sourceConfig.mode==='stream'){
28907
29994
  this.#store=new ColumnStore(this.#columns.storeSchema(),{
28908
29995
  columnarBelow:sourceConfig.columnarBelow,
28909
- retainSource:this.#config.ingest?this.#config.ingest.retainSource:undefined,
29996
+ retainSource:this.#storeRetainSource(),
28910
29997
  });
28911
29998
  }
28912
29999
  this.#facets?.invalidate();
@@ -28933,7 +30020,7 @@ groupBy:()=>this.#query.groupBy,
28933
30020
  pivotBy:()=>this.#query.pivotBy,
28934
30021
  pivotMode:()=>this.#query.pivotMode,
28935
30022
  totals:()=>this.#permissions.readableColumns(this.#columns.all())
28936
- .filter((c)=>c.total).map((c)=>c.id),
30023
+ .filter((c)=>c.total||c.groupTotal||c.grandTotal).map((c)=>c.id),
28937
30024
  expanded:()=>this.#expandedView(),
28938
30025
  detail:()=>this.#detailView(),
28939
30026
  page:()=>this.#query.page,
@@ -28949,6 +30036,7 @@ cancel:(handle)=>cancelFrame(handle),
28949
30036
  if(this.#store){
28950
30037
  this.#ingest(config.rows||[]);
28951
30038
  this.#interceptApply();
30039
+ this.#dropSourceRows();
28952
30040
  }
28953
30041
  }
28954
30042
  #inferTypes(rows){
@@ -28989,6 +30077,24 @@ if(!store||!change)return inner(change);
28989
30077
  const insertsMidway=change.add&&change.add.length
28990
30078
  &&typeof change.at==='number'&&change.at<store.physical;
28991
30079
  if(insertsMidway){
30080
+ if(this.#sourceDropped()){
30081
+ const{kept,rejected}=this.#screenAdds(change.add,source);
30082
+ const live=this.#reconstructRowsForRebuild().filter((r)=>r!==undefined);
30083
+ const at=this.#liveBefore(change.at);
30084
+ live.splice(Math.max(0,Math.min(live.length,at)),0,...kept);
30085
+ this.#store.destroy();
30086
+ this.#store=new ColumnStore(this.#columns.storeSchema(),{
30087
+ retainSource:this.#storeRetainSource(),
30088
+ });
30089
+ this.#ingest(live);
30090
+ this.#dropSourceRows();
30091
+ if(isFunction(source.invalidateRows))source.invalidateRows();
30092
+ this.#facets?.invalidate();
30093
+ this.#facetCache.clear();
30094
+ const result=inner({...change,add:kept});
30095
+ if(rejected.length)result.rejected=[...(result.rejected||[]),...rejected];
30096
+ return result;
30097
+ }
28992
30098
  const result=inner(change);
28993
30099
  this.#rebuildStore();
28994
30100
  return result;
@@ -29006,17 +30112,20 @@ return result;
29006
30112
  }
29007
30113
  if(change.update&&change.update.length){
29008
30114
  const merged=[];
30115
+ const priorRows=this.#sourceDropped()?new Map():null;
29009
30116
  for(const next of change.update){
29010
30117
  const key=this.#rowKey(next);
29011
30118
  const row=source.byKey(key);
29012
30119
  const physical=row&&row.physical;
29013
30120
  if(physical==null){merged.push(next);continue;}
29014
30121
  const previous=isFunction(store.source)?store.source(physical):row.data;
30122
+ if(priorRows)priorRows.set(physical,previous);
29015
30123
  const next2=mergeRow(previous,next);
29016
30124
  merged.push(next2);
29017
30125
  store.setSource(physical,next2);
29018
30126
  this.#writeRowToStore(store,physical,next2,row);
29019
30127
  }
30128
+ if(priorRows&&isFunction(source.notePriorRows))source.notePriorRows(priorRows);
29020
30129
  let adds=change.add||[];
29021
30130
  let addRejects=[];
29022
30131
  if(adds.length){
@@ -29042,15 +30151,48 @@ return inner(change);
29042
30151
  }
29043
30152
  #rebuildStore(){
29044
30153
  if(!this.#store)return;
30154
+ const snapshot=this.#sourceDropped()
30155
+ ?this.#reconstructRowsForRebuild().filter((r)=>r!==undefined)
30156
+ :null;
29045
30157
  this.#store.destroy();
29046
30158
  this.#store=new ColumnStore(this.#columns.storeSchema(),{
29047
- retainSource:this.#config.ingest?this.#config.ingest.retainSource:undefined,
30159
+ retainSource:this.#storeRetainSource(),
29048
30160
  });
29049
- this.#ingest(this.#source.rows?this.#source.rows():this.rows.data());
30161
+ this.#ingest(snapshot||(this.#source.rows?this.#source.rows():this.rows.data()));
30162
+ this.#dropSourceRows();
29050
30163
  if(isFunction(this.#source.invalidateRows))this.#source.invalidateRows();
29051
30164
  this.#facets?.invalidate();
29052
30165
  this.#facetCache.clear();
29053
30166
  }
30167
+ #sourceDropped(){
30168
+ const ingest=this.#config.ingest;
30169
+ return!!(ingest&&ingest.dropSourceRows===true);
30170
+ }
30171
+ #storeRetainSource(){
30172
+ if(this.#sourceDropped())return false;
30173
+ return this.#config.ingest?this.#config.ingest.retainSource:undefined;
30174
+ }
30175
+ #dropSourceRows(){
30176
+ if(!this.#sourceDropped())return;
30177
+ if(isFunction(this.#source.releaseSource))this.#source.releaseSource();
30178
+ this.#config.rows=undefined;
30179
+ this.#suppliedConfig.rows=undefined;
30180
+ }
30181
+ #reconstructRowsForRebuild(){
30182
+ const store=this.#store;
30183
+ const out=new Array(store.physical);
30184
+ for(let p=0;p<store.physical;p++){
30185
+ out[p]=store.live(p)?store.source(p):undefined;
30186
+ }
30187
+ return out;
30188
+ }
30189
+ #liveBefore(physical){
30190
+ const store=this.#store;
30191
+ const limit=Math.max(0,Math.min(store.physical,physical|0));
30192
+ let live=0;
30193
+ for(let p=0;p<limit;p++)if(store.live(p))live++;
30194
+ return live;
30195
+ }
29054
30196
  #expandedView(){
29055
30197
  const collapsed=this.#collapsed;
29056
30198
  return{
@@ -29173,6 +30315,9 @@ locale:'model:changed',
29173
30315
  lookup:'model:changed',
29174
30316
  state:'model:changed',
29175
30317
  };
30318
+ if(kind==='state'){
30319
+ for(const stage of['sort','group','total','pivot'])this.#source.invalidate?.(stage);
30320
+ }
29176
30321
  this.#bus.emit(map[kind]||'model:changed',payload||{},'api');
29177
30322
  this.#renderer?.invalidate('columns');
29178
30323
  }
@@ -29240,7 +30385,10 @@ return this.#store?this.#store.column(colId):undefined;
29240
30385
  }
29241
30386
  #columnValues(colId){
29242
30387
  const handle=this.#handleFor(colId);
29243
- return handle?statNumbers(handle,this.#statIndices()):new Float64Array(0);
30388
+ if(!handle)return new Float64Array(0);
30389
+ const indices=this.#statIndices();
30390
+ this.#warnWindowedStat('format',colId,indices.length);
30391
+ return statNumbers(handle,indices);
29244
30392
  }
29245
30393
  #filteredKeys(){
29246
30394
  const indices=this.#statIndices();
@@ -29249,8 +30397,11 @@ return this.#filteredKeyCache.keys;
29249
30397
  }
29250
30398
  const keys=new Set();
29251
30399
  const all=isFunction(this.#source.rows)?this.#source.rows():null;
30400
+ const dropped=this.#sourceDropped()&&this.#store&&isFunction(this.#store.source);
29252
30401
  for(let i=0;i<indices.length;i++){
29253
- const data=all?all[indices[i]]:null;
30402
+ const data=dropped
30403
+ ?this.#store.source(indices[i])
30404
+ :(all?all[indices[i]]:null);
29254
30405
  const key=data==null?null:this.#rowKey(data);
29255
30406
  if(key!==null&&key!==undefined)keys.add(String(key));
29256
30407
  }
@@ -29295,6 +30446,7 @@ return values;
29295
30446
  const values=this.#handleFor(colId);
29296
30447
  if(!values)return null;
29297
30448
  const indices=this.#statIndices();
30449
+ this.#warnWindowedStat('series',colId,indices.length);
29298
30450
  const readValue=statValueReader(values);
29299
30451
  if(!by){
29300
30452
  const out=[];
@@ -29325,6 +30477,39 @@ const source=this.#source;
29325
30477
  if(isFunction(source.filteredIndices))return source.filteredIndices();
29326
30478
  return this.#store?this.#store.liveIndices():[];
29327
30479
  }
30480
+ #statCoverage(covered){
30481
+ const source=this.#source;
30482
+ if(isFunction(source.filteredIndices)){
30483
+ return{covered,total:covered,windowed:false};
30484
+ }
30485
+ let total=isFunction(source.matchCount)?source.matchCount()
30486
+ :(isFunction(source.count)?source.count():covered);
30487
+ if(isFunction(source.progress)){
30488
+ const p=source.progress();
30489
+ if(p&&Number.isFinite(p.loaded))total=Math.max(total,p.loaded);
30490
+ }
30491
+ if(!Number.isFinite(total))total=covered;
30492
+ return{covered,total:Math.max(total,covered),windowed:true};
30493
+ }
30494
+ #warnWindowedStat(stat,colId,covered){
30495
+ const coverage=this.#statCoverage(covered);
30496
+ if(!DEV||!coverage.windowed||coverage.covered>=coverage.total)return coverage;
30497
+ warnOnce(
30498
+ `stat.windowed:${stat}:${colId}:${this.#sourceId()}`,
30499
+ `\`${stat}\` on \`${colId}\` computed over ${coverage.covered.toLocaleString()} of `
30500
+ +`${coverage.total.toLocaleString()} matching rows (windowed source); hold the data in a `
30501
+ +'memory source for whole-dataset statistics.',
30502
+ );
30503
+ return coverage;
30504
+ }
30505
+ #sourceId(){
30506
+ if(this.#sourceIdCache&&this.#sourceIdCache.source===this.#source){
30507
+ return this.#sourceIdCache.id;
30508
+ }
30509
+ const id=Grid.#nextSourceId++;
30510
+ this.#sourceIdCache={source:this.#source,id};
30511
+ return id;
30512
+ }
29328
30513
  #displayRows(){
29329
30514
  return this.#source.display?this.#source.display():[];
29330
30515
  }
@@ -30289,7 +31474,7 @@ grid.#renderer?.invalidate('columns');
30289
31474
  grid.#refresh('rows');
30290
31475
  },{target:undefined});
30291
31476
  },
30292
- setTotal(id,fn){
31477
+ setTotal(id,fn,opts){
30293
31478
  const column=model.get(id);
30294
31479
  if(!column)return;
30295
31480
  if(typeof fn==='string'&&!aggregateAllowed(column,fn)){
@@ -30301,7 +31486,16 @@ warnOnce(
30301
31486
  );
30302
31487
  return;
30303
31488
  }
31489
+ const scope=opts&&opts.scope;
31490
+ if(scope==='group'){
31491
+ column.groupTotal=fn||null;
31492
+ }else if(scope==='grand'){
31493
+ column.grandTotal=fn||null;
31494
+ }else{
30304
31495
  column.total=fn||null;
31496
+ column.groupTotal=null;
31497
+ column.grandTotal=null;
31498
+ }
30305
31499
  grid.#source.invalidate?.('total');
30306
31500
  grid.#bus.emit('column:grouped',{columns:grid.#query.groupBy},'api');
30307
31501
  grid.#refresh('rows');
@@ -31279,12 +32473,15 @@ return{columns:[...grid.#shadows.keys()],rows,forgotten};
31279
32473
  reduce(colId,fn){
31280
32474
  const handle=grid.#handleFor(colId);
31281
32475
  if(!handle)return null;
31282
- return total(handle,grid.#statIndices(),fn,{grid,locale:grid.#config.locale});
32476
+ const indices=grid.#statIndices();
32477
+ grid.#warnWindowedStat(typeof fn==='string'?fn:'reduce',colId,indices.length);
32478
+ return total(handle,indices,fn,{grid,locale:grid.#config.locale});
31283
32479
  },
31284
32480
  profile(colId){
31285
32481
  const handle=grid.#handleFor(colId);
31286
32482
  if(!handle)return null;
31287
32483
  const indices=grid.#statIndices();
32484
+ const coverage=grid.#warnWindowedStat('profile',colId,indices.length);
31288
32485
  const values=statNumbers(handle,indices);
31289
32486
  const{n,mean,m2}=statMoments(values);
31290
32487
  const sorted=values.slice().sort();
@@ -31299,6 +32496,7 @@ if(v===null||v===undefined||v==='')absent++;
31299
32496
  return{
31300
32497
  column:colId,
31301
32498
  rows:indices.length,
32499
+ ...(coverage.windowed?{coverage:{covered:coverage.covered,total:coverage.total}}:{}),
31302
32500
  present:indices.length-absent,
31303
32501
  missing:absent,
31304
32502
  numeric:n,
@@ -31319,37 +32517,48 @@ correlation(a,b){
31319
32517
  const first=grid.#handleFor(a);
31320
32518
  const second=grid.#handleFor(b);
31321
32519
  if(!first||!second)return null;
31322
- return statCorrelation(first,second,grid.#statIndices());
32520
+ const indices=grid.#statIndices();
32521
+ grid.#warnWindowedStat('correlation',`${a},${b}`,indices.length);
32522
+ return statCorrelation(first,second,indices);
31323
32523
  },
31324
32524
  covariance(a,b,opts={}){
31325
32525
  const first=grid.#handleFor(a);
31326
32526
  const second=grid.#handleFor(b);
31327
32527
  if(!first||!second)return null;
31328
- return statCovariance(first,second,grid.#statIndices(),opts.population===true);
32528
+ const indices=grid.#statIndices();
32529
+ grid.#warnWindowedStat('covariance',`${a},${b}`,indices.length);
32530
+ return statCovariance(first,second,indices,opts.population===true);
31329
32531
  },
31330
32532
  regression(a,b){
31331
32533
  const first=grid.#handleFor(a);
31332
32534
  const second=grid.#handleFor(b);
31333
32535
  if(!first||!second)return null;
31334
- return statRegression(first,second,grid.#statIndices());
32536
+ const indices=grid.#statIndices();
32537
+ grid.#warnWindowedStat('regression',`${a},${b}`,indices.length);
32538
+ return statRegression(first,second,indices);
31335
32539
  },
31336
32540
  spearman(a,b){
31337
32541
  const first=grid.#handleFor(a);
31338
32542
  const second=grid.#handleFor(b);
31339
32543
  if(!first||!second)return null;
31340
- return statSpearman(first,second,grid.#statIndices());
32544
+ const indices=grid.#statIndices();
32545
+ grid.#warnWindowedStat('spearman',`${a},${b}`,indices.length);
32546
+ return statSpearman(first,second,indices);
31341
32547
  },
31342
32548
  kendall(a,b){
31343
32549
  const first=grid.#handleFor(a);
31344
32550
  const second=grid.#handleFor(b);
31345
32551
  if(!first||!second)return null;
31346
- return statKendall(first,second,grid.#statIndices());
32552
+ const indices=grid.#statIndices();
32553
+ grid.#warnWindowedStat('kendall',`${a},${b}`,indices.length);
32554
+ return statKendall(first,second,indices);
31347
32555
  },
31348
32556
  weightedQuantile(colId,weightId,p=0.5){
31349
32557
  const values=grid.#handleFor(colId);
31350
32558
  const weights=grid.#handleFor(weightId);
31351
32559
  if(!values||!weights)return null;
31352
32560
  const indices=grid.#statIndices();
32561
+ grid.#warnWindowedStat('weightedQuantile',`${colId},${weightId}`,indices.length);
31353
32562
  const readV=statValueReader(values);
31354
32563
  const readW=statValueReader(weights);
31355
32564
  const vs=[];
@@ -31429,7 +32638,9 @@ weightedAverage(colId,weightId){
31429
32638
  const values=grid.#handleFor(colId);
31430
32639
  const weights=grid.#handleFor(weightId);
31431
32640
  if(!values||!weights)return null;
31432
- return statWeightedAverage(values,weights,grid.#statIndices());
32641
+ const indices=grid.#statIndices();
32642
+ grid.#warnWindowedStat('weightedAverage',`${colId},${weightId}`,indices.length);
32643
+ return statWeightedAverage(values,weights,indices);
31433
32644
  },
31434
32645
  keyOf(data){
31435
32646
  if(data==null)return null;
@@ -32084,6 +33295,9 @@ other:'Aperçu du collage : {changes} modifications de cellules, {rejected} reje
32084
33295
  'menu.totalColumn':'Totaliser cette colonne',
32085
33296
  'menu.aggregate':'Agrégat',
32086
33297
  'menu.aggregateNone':'Aucun',
33298
+ 'menu.aggregateGroup':'Sous-totaux de groupe',
33299
+ 'menu.aggregateGrand':'Total général',
33300
+ 'menu.aggregateSame':'Comme le total',
32087
33301
  'menu.redactColumn':'Masquer le contenu de la colonne',
32088
33302
  'menu.stopRedacting':'Ne plus masquer',
32089
33303
  'menu.stopRedactingAll':'Ne plus rien masquer',
@@ -32598,6 +33812,9 @@ other:'Anteprima incolla: {changes} modifiche alle celle, {rejected} rifiutate.
32598
33812
  'menu.totalColumn':'Totalizza questa colonna',
32599
33813
  'menu.aggregate':'Aggregazione',
32600
33814
  'menu.aggregateNone':'Nessuno',
33815
+ 'menu.aggregateGroup':'Subtotali di gruppo',
33816
+ 'menu.aggregateGrand':'Totale generale',
33817
+ 'menu.aggregateSame':'Come il totale',
32601
33818
  'menu.redactColumn':'Oscura la colonna',
32602
33819
  'menu.stopRedacting':'Non oscurare più',
32603
33820
  'menu.stopRedactingAll':'Non oscurare più nulla',
@@ -33097,6 +34314,9 @@ other:'Vista previa del pegado: {changes} cambios de celdas, {rejected} rechazad
33097
34314
  'menu.totalColumn':'Totalizar esta columna',
33098
34315
  'menu.aggregate':'Agregación',
33099
34316
  'menu.aggregateNone':'Ninguno',
34317
+ 'menu.aggregateGroup':'Subtotales de grupo',
34318
+ 'menu.aggregateGrand':'Total general',
34319
+ 'menu.aggregateSame':'Igual que el total',
33100
34320
  'menu.redactColumn':'Ocultar el contenido de la columna',
33101
34321
  'menu.stopRedacting':'Dejar de ocultar',
33102
34322
  'menu.stopRedactingAll':'Dejar de ocultar todo',
@@ -33626,6 +34846,9 @@ other:'Limpar {count} células',
33626
34846
  'menu.totalColumn':'Totalizar esta coluna',
33627
34847
  'menu.aggregate':'Agregação',
33628
34848
  'menu.aggregateNone':'Nenhum',
34849
+ 'menu.aggregateGroup':'Subtotais de grupo',
34850
+ 'menu.aggregateGrand':'Total geral',
34851
+ 'menu.aggregateSame':'Igual ao total',
33629
34852
  'menu.redactColumn':'Ocultar o conteúdo da coluna',
33630
34853
  'menu.stopRedacting':'Parar de ocultar',
33631
34854
  'menu.stopRedactingAll':'Parar de ocultar tudo',
@@ -34152,6 +35375,9 @@ other:'{count} Zellen leeren',
34152
35375
  'menu.totalColumn':'Diese Spalte summieren',
34153
35376
  'menu.aggregate':'Aggregat',
34154
35377
  'menu.aggregateNone':'Keine',
35378
+ 'menu.aggregateGroup':'Gruppenzwischensummen',
35379
+ 'menu.aggregateGrand':'Gesamtsumme',
35380
+ 'menu.aggregateSame':'Wie Gesamtwert',
34155
35381
  'menu.redactColumn':'Spalteninhalt schwärzen',
34156
35382
  'menu.stopRedacting':'Schwärzung aufheben',
34157
35383
  'menu.stopRedactingAll':'Alle Schwärzungen aufheben',
@@ -34678,6 +35904,9 @@ other:'{count} cellen wissen',
34678
35904
  'menu.totalColumn':'Deze kolom totaliseren',
34679
35905
  'menu.aggregate':'Aggregatie',
34680
35906
  'menu.aggregateNone':'Geen',
35907
+ 'menu.aggregateGroup':'Groepssubtotalen',
35908
+ 'menu.aggregateGrand':'Eindtotaal',
35909
+ 'menu.aggregateSame':'Zelfde als totaal',
34681
35910
  'menu.redactColumn':'Kolominhoud afschermen',
34682
35911
  'menu.stopRedacting':'Niet meer afschermen',
34683
35912
  'menu.stopRedactingAll':'Niets meer afschermen',
@@ -35204,6 +36433,9 @@ other:'Rensa {count} celler',
35204
36433
  'menu.totalColumn':'Summera den här kolumnen',
35205
36434
  'menu.aggregate':'Aggregat',
35206
36435
  'menu.aggregateNone':'Ingen',
36436
+ 'menu.aggregateGroup':'Gruppdelsummor',
36437
+ 'menu.aggregateGrand':'Slutsumma',
36438
+ 'menu.aggregateSame':'Samma som total',
35207
36439
  'menu.redactColumn':'Maskera kolumnens innehåll',
35208
36440
  'menu.stopRedacting':'Sluta maskera',
35209
36441
  'menu.stopRedactingAll':'Sluta maskera allt',
@@ -35730,6 +36962,9 @@ other:'Ryd {count} celler',
35730
36962
  'menu.totalColumn':'Summér denne kolonne',
35731
36963
  'menu.aggregate':'Aggregering',
35732
36964
  'menu.aggregateNone':'Ingen',
36965
+ 'menu.aggregateGroup':'Gruppesubtotaler',
36966
+ 'menu.aggregateGrand':'Hovedtotal',
36967
+ 'menu.aggregateSame':'Samme som total',
35733
36968
  'menu.redactColumn':'Skjul kolonnens indhold',
35734
36969
  'menu.stopRedacting':'Stop med at skjule',
35735
36970
  'menu.stopRedactingAll':'Stop med at skjule alt',
@@ -36256,6 +37491,9 @@ other:'Tøm {count} celler',
36256
37491
  'menu.totalColumn':'Summer denne kolonnen',
36257
37492
  'menu.aggregate':'Aggregat',
36258
37493
  'menu.aggregateNone':'Ingen',
37494
+ 'menu.aggregateGroup':'Gruppedelsummer',
37495
+ 'menu.aggregateGrand':'Totalsum',
37496
+ 'menu.aggregateSame':'Samme som total',
36259
37497
  'menu.redactColumn':'Skjul innholdet i kolonnen',
36260
37498
  'menu.stopRedacting':'Slutt å skjule',
36261
37499
  'menu.stopRedactingAll':'Slutt å skjule alt',
@@ -36782,6 +38020,9 @@ other:'Tyhjennä {count} solua',
36782
38020
  'menu.totalColumn':'Summaa tämä sarake',
36783
38021
  'menu.aggregate':'Koonti',
36784
38022
  'menu.aggregateNone':'Ei mitään',
38023
+ 'menu.aggregateGroup':'Ryhmän välisummat',
38024
+ 'menu.aggregateGrand':'Kokonaissumma',
38025
+ 'menu.aggregateSame':'Sama kuin summa',
36785
38026
  'menu.redactColumn':'Peitä sarakkeen sisältö',
36786
38027
  'menu.stopRedacting':'Lopeta peittäminen',
36787
38028
  'menu.stopRedactingAll':'Lopeta kaiken peittäminen',
@@ -37340,6 +38581,9 @@ other:'Wyczyść {count} komórek',
37340
38581
  'menu.totalColumn':'Sumuj tę kolumnę',
37341
38582
  'menu.aggregate':'Agregacja',
37342
38583
  'menu.aggregateNone':'Brak',
38584
+ 'menu.aggregateGroup':'Sumy częściowe grup',
38585
+ 'menu.aggregateGrand':'Suma końcowa',
38586
+ 'menu.aggregateSame':'Tak jak suma',
37343
38587
  'menu.redactColumn':'Ukryj zawartość kolumny',
37344
38588
  'menu.stopRedacting':'Przestań ukrywać',
37345
38589
  'menu.stopRedactingAll':'Przestań ukrywać wszystko',
@@ -37900,6 +39144,9 @@ other:'Vymazat {count} buněk',
37900
39144
  'menu.totalColumn':'Sečíst tento sloupec',
37901
39145
  'menu.aggregate':'Agregace',
37902
39146
  'menu.aggregateNone':'Žádná',
39147
+ 'menu.aggregateGroup':'Mezisoučty skupin',
39148
+ 'menu.aggregateGrand':'Celkový součet',
39149
+ 'menu.aggregateSame':'Stejné jako součet',
37903
39150
  'menu.redactColumn':'Skrýt obsah sloupce',
37904
39151
  'menu.stopRedacting':'Přestat skrývat',
37905
39152
  'menu.stopRedactingAll':'Přestat vše skrývat',
@@ -38428,6 +39675,9 @@ other:'{count} cella törlése',
38428
39675
  'menu.totalColumn':'Ezen oszlop összegzése',
38429
39676
  'menu.aggregate':'Összesítés',
38430
39677
  'menu.aggregateNone':'Nincs',
39678
+ 'menu.aggregateGroup':'Csoport részösszegek',
39679
+ 'menu.aggregateGrand':'Végösszeg',
39680
+ 'menu.aggregateSame':'Ugyanaz mint az összeg',
38431
39681
  'menu.redactColumn':'Oszlop tartalmának kitakarása',
38432
39682
  'menu.stopRedacting':'Kitakarás megszüntetése',
38433
39683
  'menu.stopRedactingAll':'Minden kitakarás megszüntetése',
@@ -38970,6 +40220,9 @@ other:'Golește {count} de celule',
38970
40220
  'menu.totalColumn':'Totalizează această coloană',
38971
40221
  'menu.aggregate':'Agregare',
38972
40222
  'menu.aggregateNone':'Niciunul',
40223
+ 'menu.aggregateGroup':'Subtotaluri de grup',
40224
+ 'menu.aggregateGrand':'Total general',
40225
+ 'menu.aggregateSame':'La fel ca totalul',
38973
40226
  'menu.redactColumn':'Ascunde conținutul coloanei',
38974
40227
  'menu.stopRedacting':'Nu mai ascunde',
38975
40228
  'menu.stopRedactingAll':'Nu mai ascunde nimic',
@@ -39529,6 +40782,9 @@ other:'Очистити {count} комірок',
39529
40782
  'menu.totalColumn':'Підсумувати цей стовпець',
39530
40783
  'menu.aggregate':'Агрегація',
39531
40784
  'menu.aggregateNone':'Немає',
40785
+ 'menu.aggregateGroup':'Проміжні підсумки груп',
40786
+ 'menu.aggregateGrand':'Загальний підсумок',
40787
+ 'menu.aggregateSame':'Як у підсумку',
39532
40788
  'menu.redactColumn':'Приховати вміст стовпця',
39533
40789
  'menu.stopRedacting':'Припинити приховування',
39534
40790
  'menu.stopRedactingAll':'Припинити приховування всього',
@@ -40057,6 +41313,9 @@ other:'Καθαρισμός {count} κελιών',
40057
41313
  'menu.totalColumn':'Άθροισμα αυτής της στήλης',
40058
41314
  'menu.aggregate':'Συνάθροιση',
40059
41315
  'menu.aggregateNone':'Καμία',
41316
+ 'menu.aggregateGroup':'Μερικά σύνολα ομάδας',
41317
+ 'menu.aggregateGrand':'Γενικό σύνολο',
41318
+ 'menu.aggregateSame':'Ίδιο με το σύνολο',
40060
41319
  'menu.redactColumn':'Απόκρυψη περιεχομένου στήλης',
40061
41320
  'menu.stopRedacting':'Διακοπή απόκρυψης',
40062
41321
  'menu.stopRedactingAll':'Διακοπή κάθε απόκρυψης',
@@ -40566,6 +41825,9 @@ other:'{count} セルをクリア',
40566
41825
  'menu.totalColumn':'この列を集計',
40567
41826
  'menu.aggregate':'集計',
40568
41827
  'menu.aggregateNone':'なし',
41828
+ 'menu.aggregateGroup':'グループ小計',
41829
+ 'menu.aggregateGrand':'総計',
41830
+ 'menu.aggregateSame':'合計と同じ',
40569
41831
  'menu.redactColumn':'列の内容を伏せる',
40570
41832
  'menu.stopRedacting':'伏せるのをやめる',
40571
41833
  'menu.stopRedactingAll':'すべて伏せるのをやめる',
@@ -41142,6 +42404,9 @@ other:'مسح {count} خلية',
41142
42404
  'menu.totalColumn':'إجمالي هذا العمود',
41143
42405
  'menu.aggregate':'تجميع',
41144
42406
  'menu.aggregateNone':'بدون',
42407
+ 'menu.aggregateGroup':'المجاميع الفرعية للمجموعة',
42408
+ 'menu.aggregateGrand':'الإجمالي الكلي',
42409
+ 'menu.aggregateSame':'مثل الإجمالي',
41145
42410
  'menu.redactColumn':'إخفاء محتوى العمود',
41146
42411
  'menu.stopRedacting':'إيقاف الإخفاء',
41147
42412
  'menu.stopRedactingAll':'إيقاف الإخفاء بالكامل',
@@ -41510,27 +42775,30 @@ const __m0=__req("packages/core/src/store/bitset.js");
41510
42775
  Object.defineProperty(__exports,"Bitset",{enumerable:true,get:function(){return __m0["Bitset"];}});
41511
42776
  const __m1=__req("packages/core/src/store/dictionary.js");
41512
42777
  Object.defineProperty(__exports,"Dictionary",{enumerable:true,get:function(){return __m1["Dictionary"];}});
41513
- const __m2=__req("packages/core/src/store/multivalue.js");
41514
- Object.defineProperty(__exports,"MultiValue",{enumerable:true,get:function(){return __m2["MultiValue"];}});
41515
- const __m3=__req("packages/core/src/store/pool.js");
41516
- Object.defineProperty(__exports,"MaskPool",{enumerable:true,get:function(){return __m3["MaskPool"];}});
41517
- Object.defineProperty(__exports,"sharedPool",{enumerable:true,get:function(){return __m3["sharedPool"];}});
41518
- const __m4=__req("packages/core/src/store/columnstore.js");
41519
- Object.defineProperty(__exports,"ColumnStore",{enumerable:true,get:function(){return __m4["ColumnStore"];}});
41520
- Object.defineProperty(__exports,"ColumnHandle",{enumerable:true,get:function(){return __m4["ColumnHandle"];}});
41521
- Object.defineProperty(__exports,"REMOVED",{enumerable:true,get:function(){return __m4["REMOVED"];}});
41522
- const __m5=__req("packages/core/src/store/ingest.js");
41523
- Object.defineProperty(__exports,"Ingest",{enumerable:true,get:function(){return __m5["Ingest"];}});
41524
- Object.defineProperty(__exports,"ingest",{enumerable:true,get:function(){return __m5["ingest"];}});
41525
- Object.defineProperty(__exports,"ingestSync",{enumerable:true,get:function(){return __m5["ingestSync"];}});
41526
- Object.defineProperty(__exports,"createReaders",{enumerable:true,get:function(){return __m5["createReaders"];}});
41527
- Object.defineProperty(__exports,"inferKind",{enumerable:true,get:function(){return __m5["inferKind"];}});
41528
- Object.defineProperty(__exports,"decideText",{enumerable:true,get:function(){return __m5["decideText"];}});
41529
- Object.defineProperty(__exports,"INGEST_DEFAULTS",{enumerable:true,get:function(){return __m5["INGEST_DEFAULTS"];}});
41530
- const __m6=__req("packages/core/src/store/columnpack.js");
41531
- Object.defineProperty(__exports,"packChunk",{enumerable:true,get:function(){return __m6["packChunk"];}});
41532
- Object.defineProperty(__exports,"packedTransfers",{enumerable:true,get:function(){return __m6["packedTransfers"];}});
41533
- Object.defineProperty(__exports,"isPortableSchema",{enumerable:true,get:function(){return __m6["isPortableSchema"];}});
42778
+ const __m2=__req("packages/core/src/store/stringrank.js");
42779
+ Object.defineProperty(__exports,"StringRankIndex",{enumerable:true,get:function(){return __m2["StringRankIndex"];}});
42780
+ Object.defineProperty(__exports,"DEFAULT_MAX_DISTINCT",{enumerable:true,get:function(){return __m2["DEFAULT_MAX_DISTINCT"];}});
42781
+ const __m3=__req("packages/core/src/store/multivalue.js");
42782
+ Object.defineProperty(__exports,"MultiValue",{enumerable:true,get:function(){return __m3["MultiValue"];}});
42783
+ const __m4=__req("packages/core/src/store/pool.js");
42784
+ Object.defineProperty(__exports,"MaskPool",{enumerable:true,get:function(){return __m4["MaskPool"];}});
42785
+ Object.defineProperty(__exports,"sharedPool",{enumerable:true,get:function(){return __m4["sharedPool"];}});
42786
+ const __m5=__req("packages/core/src/store/columnstore.js");
42787
+ Object.defineProperty(__exports,"ColumnStore",{enumerable:true,get:function(){return __m5["ColumnStore"];}});
42788
+ Object.defineProperty(__exports,"ColumnHandle",{enumerable:true,get:function(){return __m5["ColumnHandle"];}});
42789
+ Object.defineProperty(__exports,"REMOVED",{enumerable:true,get:function(){return __m5["REMOVED"];}});
42790
+ const __m6=__req("packages/core/src/store/ingest.js");
42791
+ Object.defineProperty(__exports,"Ingest",{enumerable:true,get:function(){return __m6["Ingest"];}});
42792
+ Object.defineProperty(__exports,"ingest",{enumerable:true,get:function(){return __m6["ingest"];}});
42793
+ Object.defineProperty(__exports,"ingestSync",{enumerable:true,get:function(){return __m6["ingestSync"];}});
42794
+ Object.defineProperty(__exports,"createReaders",{enumerable:true,get:function(){return __m6["createReaders"];}});
42795
+ Object.defineProperty(__exports,"inferKind",{enumerable:true,get:function(){return __m6["inferKind"];}});
42796
+ Object.defineProperty(__exports,"decideText",{enumerable:true,get:function(){return __m6["decideText"];}});
42797
+ Object.defineProperty(__exports,"INGEST_DEFAULTS",{enumerable:true,get:function(){return __m6["INGEST_DEFAULTS"];}});
42798
+ const __m7=__req("packages/core/src/store/columnpack.js");
42799
+ Object.defineProperty(__exports,"packChunk",{enumerable:true,get:function(){return __m7["packChunk"];}});
42800
+ Object.defineProperty(__exports,"packedTransfers",{enumerable:true,get:function(){return __m7["packedTransfers"];}});
42801
+ Object.defineProperty(__exports,"isPortableSchema",{enumerable:true,get:function(){return __m7["isPortableSchema"];}});
41534
42802
  });
41535
42803
  __def("packages/core/src/model/index.js",function(__exports,__req){
41536
42804
  'use strict';
@@ -41722,6 +42990,7 @@ Object.defineProperty(__exports,"DEFAULT_PARAMS",{enumerable:true,get:function()
41722
42990
  Object.defineProperty(__exports,"dfqlAdapter",{enumerable:true,get:function(){return __m10["dfqlAdapter"];}});
41723
42991
  Object.defineProperty(__exports,"duckdbAdapter",{enumerable:true,get:function(){return __m10["duckdbAdapter"];}});
41724
42992
  Object.defineProperty(__exports,"filtersToSql",{enumerable:true,get:function(){return __m10["filtersToSql"];}});
42993
+ Object.defineProperty(__exports,"STAT_PUSHDOWN",{enumerable:true,get:function(){return __m10["STAT_PUSHDOWN"];}});
41725
42994
  const __m11=__req("packages/core/src/model/index.js");
41726
42995
  Object.defineProperty(__exports,"RowModel",{enumerable:true,get:function(){return __m11["RowModel"];}});
41727
42996
  Object.defineProperty(__exports,"createRowKey",{enumerable:true,get:function(){return __m11["createRowKey"];}});
@@ -42006,6 +43275,7 @@ spanLayer:`${PREFIX}-span-layer`,
42006
43275
  fullWidthLayer:`${PREFIX}-fullwidth-layer`,
42007
43276
  row:`${PREFIX}-row`,
42008
43277
  rowSelected:`${PREFIX}-row--selected`,
43278
+ rowAlternate:`${PREFIX}-row--alternate`,
42009
43279
  rowDetailActive:`${PREFIX}-row--detail-active`,
42010
43280
  rowGroupFooter:`${PREFIX}-row--group-footer`,
42011
43281
  rowGroup:`${PREFIX}-row--group`,
@@ -43346,12 +44616,34 @@ this.#host=opts.host;
43346
44616
  this.#layout=opts.layout;
43347
44617
  this.#a11y=opts.a11y;
43348
44618
  this.#on=opts.on;
43349
- this.#rowHeight=opts.host.config?.headerHeight>0
43350
- ?opts.host.config.headerHeight
43351
- :DEFAULT_HEADER_HEIGHT;
44619
+ this.syncRowHeight();
43352
44620
  this.handlePointerMove=this.handlePointerMove.bind(this);
43353
44621
  this.handlePointerUp=this.handlePointerUp.bind(this);
43354
44622
  }
44623
+ syncRowHeight(){
44624
+ const configured=this.#host.config?.headerHeight;
44625
+ if(configured>0){this.#rowHeight=configured;return;}
44626
+ const px=this.#tokenHeaderHeight();
44627
+ if(Number.isFinite(px)&&px>0)this.#rowHeight=px;
44628
+ else if(!(this.#rowHeight>0))this.#rowHeight=DEFAULT_HEADER_HEIGHT;
44629
+ }
44630
+ #tokenHeaderHeight(){
44631
+ const root=this.#viewport?.root;
44632
+ const doc=root?.ownerDocument;
44633
+ const view=doc?.defaultView;
44634
+ if(!root||!doc||!view||typeof view.getComputedStyle!=='function')return NaN;
44635
+ if(typeof doc.createElement!=='function')return NaN;
44636
+ const probe=doc.createElement('div');
44637
+ if(!probe.style)return NaN;
44638
+ probe.style.position='absolute';
44639
+ probe.style.visibility='hidden';
44640
+ probe.style.pointerEvents='none';
44641
+ probe.style.height='var(--lattice-header-height)';
44642
+ root.appendChild(probe);
44643
+ const px=parseFloat(view.getComputedStyle(probe).height);
44644
+ probe.remove?.();
44645
+ return px;
44646
+ }
43355
44647
  get levels(){return this.#levels;}
43356
44648
  get height(){return this.#levels*this.#rowHeight+this.#bandHeight();}
43357
44649
  #bandHeight(){
@@ -43412,6 +44704,7 @@ for(const node of nodes)walk(node,0);
43412
44704
  return depth;
43413
44705
  }
43414
44706
  build(){
44707
+ this.syncRowHeight();
43415
44708
  const tree=this.#tree();
43416
44709
  this.#levels=this.#depth(tree);
43417
44710
  this.#viewport.root?.style?.setProperty?.('--lattice-facet-height',`${this.#bandHeight()}px`);
@@ -45699,6 +46992,7 @@ __def("packages/dom/src/renderer/renderer.js",function(__exports,__req){
45699
46992
  Object.defineProperty(__exports,"resolveGroupHeadingDepth",{enumerable:true,get:function(){return resolveGroupHeadingDepth;}});
45700
46993
  Object.defineProperty(__exports,"resolveGridLines",{enumerable:true,get:function(){return resolveGridLines;}});
45701
46994
  Object.defineProperty(__exports,"resolveCornerRadius",{enumerable:true,get:function(){return resolveCornerRadius;}});
46995
+ Object.defineProperty(__exports,"resolveStripedRows",{enumerable:true,get:function(){return resolveStripedRows;}});
45702
46996
  Object.defineProperty(__exports,"DEFAULT_OVERSCAN",{enumerable:true,get:function(){return DEFAULT_OVERSCAN;}});
45703
46997
  Object.defineProperty(__exports,"textCellLayer",{enumerable:true,get:function(){return textCellLayer;}});
45704
46998
  Object.defineProperty(__exports,"DomRenderer",{enumerable:true,get:function(){return DomRenderer;}});
@@ -45751,13 +47045,13 @@ const rowAtContent=__m18["rowAtContent"];
45751
47045
  const __m19=__req("packages/dom/src/detailhost.js");
45752
47046
  const insideDetail=__m19["insideDetail"];
45753
47047
  function resolveGroupHeadingDepth(config){
45754
- if(config===false)return 0;
45755
- if(config===true||config===undefined||config===null)return 2;
47048
+ if(config===false||config===undefined||config===null)return 0;
47049
+ if(config===true)return 2;
45756
47050
  if(typeof config==='number')return Number.isInteger(config)&&config>0?config:0;
45757
47051
  if(typeof config==='object'&&typeof config.depth==='number'){
45758
47052
  return Number.isInteger(config.depth)&&config.depth>0?config.depth:0;
45759
47053
  }
45760
- return 2;
47054
+ return 0;
45761
47055
  }
45762
47056
  function resolveGridLines(config){
45763
47057
  if(config===false||config==='none')return'none';
@@ -45772,6 +47066,9 @@ if(typeof config==='number')return Number.isFinite(config)&&config>=0?`${config}
45772
47066
  if(typeof config==='string'&&config.trim())return config.trim();
45773
47067
  return null;
45774
47068
  }
47069
+ function resolveStripedRows(config){
47070
+ return config===true;
47071
+ }
45775
47072
  const EMPTY_LIST=Object.freeze([]);
45776
47073
  const DEFAULT_OVERSCAN=4;
45777
47074
  const ROW_BORDER=1;
@@ -45980,6 +47277,12 @@ this.#heights.setCount(this.#host.rowCount());
45980
47277
  this.#heights.rebuild();
45981
47278
  this.#forceNext=true;
45982
47279
  }
47280
+ if(reason==='theme'||reason==='all'){
47281
+ this.#applyTheme();
47282
+ this.#applyDensity();
47283
+ this.#heights.clearMeasured();
47284
+ this.#forceNext=true;
47285
+ }
45983
47286
  if(reason==='columns'||reason==='all'){
45984
47287
  this.#needsSize=true;
45985
47288
  this.#relayoutColumns();
@@ -45989,12 +47292,6 @@ if(reason==='size'||reason==='all')this.#needsSize=true;
45989
47292
  this.#fullWidth.configure(this.#host.config?.fullWidth);
45990
47293
  this.#configurePresentation();
45991
47294
  this.#stickyGroupDepth=resolveGroupHeadingDepth(this.#host.config?.stickyGroupHeaders);
45992
- if(reason==='theme'||reason==='all'){
45993
- this.#applyTheme();
45994
- this.#applyDensity();
45995
- this.#heights.clearMeasured();
45996
- this.#forceNext=true;
45997
- }
45998
47295
  if(reason==='rowHeight'||reason==='all'){
45999
47296
  const configured=this.#host.config?.rowHeight;
46000
47297
  if(typeof configured==='number')this.#heights.setRowHeight(configured);
@@ -46013,8 +47310,13 @@ if(typeof theme==='string'&&theme)root.setAttribute('data-theme',theme);
46013
47310
  else root.removeAttribute('data-theme');
46014
47311
  this.#applyGridLines(root);
46015
47312
  this.#applyCorners(root);
47313
+ this.#applyStripes(root);
46016
47314
  this.#applyDirection(root);
46017
47315
  }
47316
+ #applyStripes(root){
47317
+ if(resolveStripedRows(this.#host.config?.stripedRows))root.setAttribute('data-striped-rows','');
47318
+ else root.removeAttribute('data-striped-rows');
47319
+ }
46018
47320
  #applyGridLines(root){
46019
47321
  const lines=resolveGridLines(this.#host.config?.gridLines);
46020
47322
  root.setAttribute('data-grid-lines',lines);
@@ -46055,6 +47357,7 @@ else root.removeAttribute('data-density');
46055
47357
  const targetSize=this.#host.config?.targetSize;
46056
47358
  if(typeof targetSize==='string'&&targetSize)root.setAttribute('data-target-size',targetSize);
46057
47359
  else root.removeAttribute('data-target-size');
47360
+ this.#header?.syncRowHeight?.();
46058
47361
  if(this.#host.config?.rowHeight!=null)return;
46059
47362
  const px=this.#tokenRowHeight(root);
46060
47363
  if(Number.isFinite(px)&&px>0){
@@ -46558,6 +47861,8 @@ record.hostStyles=null;
46558
47861
  }
46559
47862
  if(!row)return;
46560
47863
  el.classList.toggle(CLASS.rowSelected,row.selected===true);
47864
+ const structural=row.group===true||row.footer===true||row.grandTotal===true;
47865
+ el.classList.toggle(CLASS.rowAlternate,index%2===1&&!structural);
46561
47866
  el.classList.toggle(CLASS.rowGroupFooter,row.footer===true);
46562
47867
  el.classList.toggle(CLASS.rowGroup,row.group===true&&!row.footer&&!row.grandTotal);
46563
47868
  el.classList.toggle(CLASS.rowGrandTotal,row.grandTotal===true);
@@ -61442,9 +62747,31 @@ name:totalLabel(name),
61442
62747
  checked:current===name,
61443
62748
  action:()=>grid.columns.setTotal(colId,name),
61444
62749
  })),
62750
+ {separator:true},
62751
+ scopeSubmenu(grid,column,t,'group',t('menu.aggregateGroup')),
62752
+ scopeSubmenu(grid,column,t,'grand',t('menu.aggregateGrand')),
61445
62753
  ];
61446
62754
  return{name:t('menu.aggregate'),children};
61447
62755
  }
62756
+ function scopeSubmenu(grid,column,t,scope,name){
62757
+ const colId=column.id;
62758
+ const override=scope==='grand'?column.grandTotal:column.groupTotal;
62759
+ const current=typeof override==='string'?override:null;
62760
+ const children=[
62761
+ {
62762
+ name:t('menu.aggregateSame'),
62763
+ checked:override==null,
62764
+ action:()=>grid.columns.setTotal(colId,null,{scope}),
62765
+ },
62766
+ {separator:true},
62767
+ ...aggregatesFor(column).map((agg)=>({
62768
+ name:totalLabel(agg),
62769
+ checked:current===agg,
62770
+ action:()=>grid.columns.setTotal(colId,agg,{scope}),
62771
+ })),
62772
+ ];
62773
+ return{name,children};
62774
+ }
61448
62775
  function headerMenuItems(grid,colId){
61449
62776
  const t=(key,params)=>(grid&&grid.messages?grid.messages:defaultMessages).t(key,params);
61450
62777
  const column=grid.columns.get(colId);
@@ -67866,7 +69193,7 @@ createLocalViewStorage,
67866
69193
  const __default=LatticeGrid;
67867
69194
  });
67868
69195
  try{
67869
- __req("packages/worker/src/inline.js").setWorkerSource("(function(root){\n'use strict';\nvar __mods=Object.create(null);\nvar __cache=Object.create(null);\nfunction __def(id,fn){__mods[id]=fn;}\nfunction __req(id){\nvar hit=__cache[id];\nif(hit)return hit;\nvar exports=Object.create(null);\n__cache[id]=exports;\nvar fn=__mods[id];\nif(!fn)throw new Error('[lattice] missing module: '+id);\nfn(exports,__req);\nreturn exports;\n}\n__def(\"packages/core/src/internal/util.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"VERSION\",{enumerable:true,get:function(){return VERSION;}});\nObject.defineProperty(__exports,\"reportedWarnings\",{enumerable:true,get:function(){return reportedWarnings;}});\nObject.defineProperty(__exports,\"warnOnce\",{enumerable:true,get:function(){return warnOnce;}});\nObject.defineProperty(__exports,\"infoOnce\",{enumerable:true,get:function(){return infoOnce;}});\nObject.defineProperty(__exports,\"resetWarnings\",{enumerable:true,get:function(){return resetWarnings;}});\nObject.defineProperty(__exports,\"fail\",{enumerable:true,get:function(){return fail;}});\nObject.defineProperty(__exports,\"invariant\",{enumerable:true,get:function(){return invariant;}});\nObject.defineProperty(__exports,\"DEV\",{enumerable:true,get:function(){return DEV;}});\nObject.defineProperty(__exports,\"isObject\",{enumerable:true,get:function(){return isObject;}});\nObject.defineProperty(__exports,\"isFunction\",{enumerable:true,get:function(){return isFunction;}});\nObject.defineProperty(__exports,\"isNil\",{enumerable:true,get:function(){return isNil;}});\nObject.defineProperty(__exports,\"isBlank\",{enumerable:true,get:function(){return isBlank;}});\nObject.defineProperty(__exports,\"isCtor\",{enumerable:true,get:function(){return isCtor;}});\nObject.defineProperty(__exports,\"pathGetter\",{enumerable:true,get:function(){return pathGetter;}});\nObject.defineProperty(__exports,\"pathSetter\",{enumerable:true,get:function(){return pathSetter;}});\nObject.defineProperty(__exports,\"getPath\",{enumerable:true,get:function(){return getPath;}});\nObject.defineProperty(__exports,\"setPath\",{enumerable:true,get:function(){return setPath;}});\nObject.defineProperty(__exports,\"humanise\",{enumerable:true,get:function(){return humanise;}});\nObject.defineProperty(__exports,\"escapeHtml\",{enumerable:true,get:function(){return escapeHtml;}});\nObject.defineProperty(__exports,\"titleCase\",{enumerable:true,get:function(){return titleCase;}});\nObject.defineProperty(__exports,\"expand\",{enumerable:true,get:function(){return expand;}});\nObject.defineProperty(__exports,\"toArray\",{enumerable:true,get:function(){return toArray;}});\nObject.defineProperty(__exports,\"merge\",{enumerable:true,get:function(){return merge;}});\nObject.defineProperty(__exports,\"mergeRow\",{enumerable:true,get:function(){return mergeRow;}});\nObject.defineProperty(__exports,\"Lru\",{enumerable:true,get:function(){return Lru;}});\nObject.defineProperty(__exports,\"collator\",{enumerable:true,get:function(){return collator;}});\nObject.defineProperty(__exports,\"defaultCompare\",{enumerable:true,get:function(){return defaultCompare;}});\nObject.defineProperty(__exports,\"now\",{enumerable:true,get:function(){return now;}});\nObject.defineProperty(__exports,\"nextFrame\",{enumerable:true,get:function(){return nextFrame;}});\nObject.defineProperty(__exports,\"cancelFrame\",{enumerable:true,get:function(){return cancelFrame;}});\nObject.defineProperty(__exports,\"frameBatched\",{enumerable:true,get:function(){return frameBatched;}});\nObject.defineProperty(__exports,\"whenIdle\",{enumerable:true,get:function(){return whenIdle;}});\nObject.defineProperty(__exports,\"uid\",{enumerable:true,get:function(){return uid;}});\nconst STAMPED_VERSION=\"1.16.0\";\nasync function resolveVersion(){\nif(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;\ntry{\nif(typeof process==='undefined'||!process.versions||!process.versions.node){\nreturn STAMPED_VERSION;\n}\nconst mod=await import('node:'+'module');\nconst req=mod.createRequire((typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst fs=req('node:'+'fs');\nconst url=new URL('../../../../package.json',(typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst text=fs.readFileSync(url,'utf8');\nreturn JSON.parse(text).version||STAMPED_VERSION;\n}catch{\nreturn STAMPED_VERSION;\n}\n}\nconst VERSION=\"1.16.0\";\nconst warned=new Set();\nconst reported=[];\nconst REPORT_LIMIT=500;\nfunction record(key,level,message){\nreported.push({\nkey,\nlevel,\nmessage:message.map((m)=>(typeof m==='string'?m:safeString(m))).join(' '),\nat:Date.now(),\n});\nif(reported.length>REPORT_LIMIT)reported.shift();\n}\nfunction safeString(value){\nif(value instanceof Error)return value.message;\ntry{return JSON.stringify(value);}catch{return String(value);}\n}\nfunction reportedWarnings(){return reported.map((r)=>({...r}));}\nfunction warnOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'warn',message);\nconsole.warn('[lattice]',...message);\n}\nfunction infoOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'info',message);\nconsole.info('[lattice]',...message);\n}\nfunction resetWarnings(){\nwarned.clear();\nreported.length=0;\n}\nfunction fail(message,extra){\nconst err=new Error(`[lattice] ${message}`);\nif(extra!==undefined)err.cause=extra;\nthrow err;\n}\nfunction invariant(condition,message){\nif(!condition)fail(message);\n}\nconst DEV=(()=>{\ntry{\nreturn!(typeof process!=='undefined'&&process.env\n&&process.env.NODE_ENV==='production');\n}catch{\nreturn true;\n}\n})();\nfunction isObject(v){\nreturn v!==null&&typeof v==='object'&&!Array.isArray(v);\n}\nfunction isFunction(v){\nreturn typeof v==='function';\n}\nfunction isNil(v){\nreturn v===null||v===undefined;\n}\nfunction isBlank(v){\nreturn v===null||v===undefined||v==='';\n}\nfunction isCtor(v){\nif(typeof v!=='function')return false;\nif(/^class[\\s{]/.test(Function.prototype.toString.call(v)))return true;\nreturn!!(v.prototype&&Object.getOwnPropertyNames(v.prototype).length>1);\n}\nconst pathCache=new Map();\nfunction pathGetter(path){\nlet fn=pathCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o)=>(o==null?undefined:o[path]);\n}else{\nconst parts=path.split('.');\nconst n=parts.length;\nfn=(o)=>{\nlet cur=o;\nfor(let i=0;i<n;i++){\nif(cur==null)return undefined;\ncur=cur[parts[i]];\n}\nreturn cur;\n};\n}\npathCache.set(path,fn);\nreturn fn;\n}\nconst setterCache=new Map();\nfunction pathSetter(path){\nlet fn=setterCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o,v)=>{if(o!=null)o[path]=v;};\n}else{\nconst parts=path.split('.');\nconst last=parts.length-1;\nfn=(o,v)=>{\nlet cur=o;\nfor(let i=0;i<last;i++){\nif(cur==null)return;\nconst k=parts[i];\nif(cur[k]==null)cur[k]={};\ncur=cur[k];\n}\nif(cur!=null)cur[parts[last]]=v;\n};\n}\nsetterCache.set(path,fn);\nreturn fn;\n}\nfunction getPath(obj,path){\nreturn pathGetter(path)(obj);\n}\nfunction setPath(obj,path,value){\npathSetter(path)(obj,value);\n}\nfunction humanise(field){\nif(!field)return'';\nconst leaf=field.includes('.')?field.slice(field.lastIndexOf('.')+1):field;\nreturn leaf\n.replace(/[_-]+/g,' ')\n.replace(/([a-z0-9])([A-Z])/g,'$1 $2')\n.replace(/([A-Z]+)([A-Z][a-z])/g,'$1 $2')\n.replace(/\\s+/g,' ')\n.trim()\n.replace(/^./,(c)=>c.toUpperCase());\n}\nconst ESCAPES={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'};\nfunction escapeHtml(s){\nconst str=s==null?'':String(s);\nreturn/[&<>\"']/.test(str)?str.replace(/[&<>\"']/g,(c)=>ESCAPES[c]):str;\n}\nfunction titleCase(s){\nreturn String(s).replace(/\\w\\S*/g,(t)=>t[0].toUpperCase()+t.slice(1).toLowerCase());\n}\nfunction expand(value,key,whenTrue){\nif(value===undefined)return undefined;\nif(value===true)return{enabled:true,...whenTrue};\nif(value===false)return{enabled:false};\nif(isObject(value))return value;\nreturn{[key]:value,enabled:true};\n}\nfunction toArray(v){\nif(v===undefined||v===null)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction merge(a,b){\nif(!isObject(a))return isObject(b)?{...b}:b;\nif(!isObject(b))return b===undefined?a:b;\nconst out={...a};\nfor(const k of Object.keys(b)){\nconst bv=b[k];\nif(bv===undefined)continue;\nout[k]=isObject(bv)&&isObject(out[k])?merge(out[k],bv):bv;\n}\nreturn out;\n}\nfunction mergeRow(previous,patch){\nif(!isObject(previous)||!isObject(patch)||previous===patch)return patch;\nconst out=Object.create(Object.getPrototypeOf(previous));\nObject.assign(out,previous,patch);\nreturn out;\n}\nclass Lru{\n#max;\n#map=new Map();\n#onEvict;\nconstructor(max=256,onEvict=null){\nthis.#max=max;\nthis.#onEvict=onEvict;\n}\nget size(){\nreturn this.#map.size;\n}\nget max(){\nreturn this.#max;\n}\nset max(v){\nthis.#max=v;\nthis.#trim();\n}\nhas(k){\nreturn this.#map.has(k);\n}\nget(k){\nconst m=this.#map;\nif(!m.has(k))return undefined;\nconst v=m.get(k);\nm.delete(k);\nm.set(k,v);\nreturn v;\n}\npeek(k){\nreturn this.#map.get(k);\n}\nset(k,v){\nconst m=this.#map;\nif(m.has(k))m.delete(k);\nm.set(k,v);\nthis.#trim();\nreturn v;\n}\ndelete(k){\nconst v=this.#map.get(k);\nif(this.#map.delete(k)&&this.#onEvict)this.#onEvict(v,k);\nreturn v;\n}\nclear(){\nif(this.#onEvict)for(const[k,v]of this.#map)this.#onEvict(v,k);\nthis.#map.clear();\n}\nkeys(){\nreturn this.#map.keys();\n}\nvalues(){\nreturn this.#map.values();\n}\n#trim(){\nconst m=this.#map;\nwhile(m.size>this.#max){\nconst oldest=m.keys().next().value;\nconst v=m.get(oldest);\nm.delete(oldest);\nif(this.#onEvict)this.#onEvict(v,oldest);\n}\n}\n}\nconst collators=new Map();\nfunction collator(locale,opts){\nconst key=`${locale||''}|${opts?JSON.stringify(opts):''}`;\nlet c=collators.get(key);\nif(!c){\nc=new Intl.Collator(locale||undefined,{\nnumeric:true,sensitivity:'variant',...opts,\n});\ncollators.set(key,c);\n}\nreturn c;\n}\nfunction defaultCompare(a,b){\nif(a===b)return 0;\nif(a===null||a===undefined)return 1;\nif(b===null||b===undefined)return-1;\nif(typeof a==='number'&&typeof b==='number'){\nif(Number.isNaN(a))return Number.isNaN(b)?0:1;\nif(Number.isNaN(b))return-1;\nreturn a<b?-1:a>b?1:0;\n}\nconst sa=String(a);\nconst sb=String(b);\nreturn sa<sb?-1:sa>sb?1:0;\n}\nfunction now(){\nreturn typeof performance!=='undefined'&&performance.now\n?performance.now()\n:Date.now();\n}\nconst hasRaf=typeof requestAnimationFrame==='function';\nfunction nextFrame(fn){\nif(hasRaf)return requestAnimationFrame(fn);\nreturn setTimeout(()=>fn(now()),16);\n}\nfunction cancelFrame(handle){\nif(handle==null)return;\nif(hasRaf)cancelAnimationFrame(handle);\nelse clearTimeout(handle);\n}\nfunction frameBatched(fn){\nlet handle=null;\nlet lastArgs=null;\nconst run=()=>{\nhandle=null;\nconst a=lastArgs;\nlastArgs=null;\nfn(...(a||[]));\n};\nconst wrapped=(...args)=>{\nlastArgs=args;\nif(handle===null)handle=nextFrame(run);\n};\nwrapped.cancel=()=>{\ncancelFrame(handle);\nhandle=null;\nlastArgs=null;\n};\nwrapped.flush=()=>{\nif(handle!==null){\ncancelFrame(handle);\nrun();\n}\n};\nreturn wrapped;\n}\nfunction whenIdle(fn,timeout=50){\nif(typeof requestIdleCallback==='function'){\nreturn requestIdleCallback(fn,{timeout});\n}\nreturn setTimeout(()=>fn({timeRemaining:()=>0,didTimeout:true}),1);\n}\nlet idSeq=0;\nfunction uid(prefix='l'){\nreturn`${prefix}${(++idSeq).toString(36)}`;\n}\n});\n__def(\"packages/worker/src/transport.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"PROTOCOL\",{enumerable:true,get:function(){return PROTOCOL;}});\nObject.defineProperty(__exports,\"OPS\",{enumerable:true,get:function(){return OPS;}});\nObject.defineProperty(__exports,\"CONTROL\",{enumerable:true,get:function(){return CONTROL;}});\nObject.defineProperty(__exports,\"ERRORS\",{enumerable:true,get:function(){return ERRORS;}});\nObject.defineProperty(__exports,\"packHandle\",{enumerable:true,get:function(){return packHandle;}});\nObject.defineProperty(__exports,\"packHandles\",{enumerable:true,get:function(){return packHandles;}});\nObject.defineProperty(__exports,\"TransportedDictionary\",{enumerable:true,get:function(){return TransportedDictionary;}});\nObject.defineProperty(__exports,\"unpackHandle\",{enumerable:true,get:function(){return unpackHandle;}});\nObject.defineProperty(__exports,\"unpackHandles\",{enumerable:true,get:function(){return unpackHandles;}});\nObject.defineProperty(__exports,\"createMaskPool\",{enumerable:true,get:function(){return createMaskPool;}});\nObject.defineProperty(__exports,\"isTransferable\",{enumerable:true,get:function(){return isTransferable;}});\nObject.defineProperty(__exports,\"collectTransfers\",{enumerable:true,get:function(){return collectTransfers;}});\nObject.defineProperty(__exports,\"isPortable\",{enumerable:true,get:function(){return isPortable;}});\nObject.defineProperty(__exports,\"filterColumnIds\",{enumerable:true,get:function(){return filterColumnIds;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst isFunction=__m0[\"isFunction\"];\nconst PROTOCOL=1;\nconst OPS=Object.freeze({\nSORT_COLUMN:'sortColumn',\nSORT_MULTI:'sortMulti',\nEVALUATE_FILTERS:'evaluateFilters',\nCOMPACT:'compact',\nGROUP_BY_COLUMNS:'groupByColumns',\nTOTAL:'total',\nPIVOT:'pivot',\nFACET:'facet',\nCOLUMNIZE:'columnize',\n});\nconst CONTROL=Object.freeze({\nREADY:'ready',\nCANCEL:'cancel',\nPING:'ping',\n});\nconst ERRORS=Object.freeze({\nNO_COMPUTE:'E_NO_COMPUTE',\nNO_KERNEL:'E_NO_KERNEL',\nABORTED:'E_ABORTED',\nKERNEL:'E_KERNEL',\nPROTOCOL:'E_PROTOCOL',\n});\nfunction packHandle(handle){\nif(handle==null)return null;\nconst presence=handle.presence;\nreturn{\nid:handle.id,\nkind:handle.kind,\nnullable:!!handle.nullable,\nvalues:handle.values??null,\npresence:presence?(presence.words??presence):null,\npresenceBits:presence?(presence.size??(presence.words??presence).length*8):0,\ndict:handle.dict?sliceDictionary(handle.dict):null,\noffsets:handle.offsets??null,\nversion:handle.version??0,\n};\n}\nfunction sliceDictionary(dict){\nif(Array.isArray(dict))return dict;\nif(isFunction(dict.values))return dict.values();\nreturn[];\n}\nfunction packHandles(handles){\nconst out=new Array(handles.length);\nfor(let i=0;i<handles.length;i++)out[i]=packHandle(handles[i]);\nreturn out;\n}\nclass TransportedBitset{\n#words;\n#bits;\nconstructor(words,bits){\nthis.#words=words;\nthis.#bits=bits;\n}\nget words(){return this.#words;}\nget size(){return this.#bits;}\nget(i){return(this.#words[i>>>3]&(1<<(i&7)))!==0;}\ncount(){\nconst w=this.#words;\nlet n=0;\nfor(let i=0;i<w.length;i++){\nlet v=w[i];\nwhile(v){v&=v-1;n++;}\n}\nreturn n;\n}\n}\nclass TransportedDictionary{\n#values;\n#index=null;\n#version=0;\n#ranks=new Map();\nconstructor(values){\nthis.#values=values||[];\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\ncodeOf(value){\nif(this.#index===null){\nthis.#index=new Map();\nfor(let i=0;i<this.#values.length;i++)this.#index.set(this.#values[i],i);\n}\nconst found=this.#index.get(value);\nif(found!==undefined)return found;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#index.set(value,code);\nthis.#version++;\nreturn code;\n}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nconst cached=this.#ranks.get(key);\nif(cached&&cached.version===this.#version)return cached.ranks;\nconst n=this.#values.length;\nconst order=new Uint32Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst vals=this.#values;\nconst sorted=Array.from(order).sort((a,b)=>{\nconst av=vals[a];\nconst bv=vals[b];\nif(av===bv)return 0;\nif(av===null||av===undefined)return 1;\nif(bv===null||bv===undefined)return-1;\nreturn cmp(String(av),String(bv));\n});\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<sorted.length;r++)ranks[sorted[r]]=r;\nthis.#ranks.set(key,{version:this.#version,ranks});\nreturn ranks;\n}\n}\nfunction unpackHandle(packed){\nif(packed==null)return null;\nconst presence=packed.presence\n?new TransportedBitset(packed.presence,packed.presenceBits||packed.presence.length*8)\n:null;\nconst dict=packed.dict?new TransportedDictionary(packed.dict):null;\nconst values=packed.values;\nconst offsets=packed.offsets??null;\nconst kind=packed.kind;\nconst get=(physical)=>{\nif(presence&&!presence.get(physical))return null;\nswitch(kind){\ncase'dictionary':\nreturn dict?dict.valueOf(values[physical]):values[physical];\ncase'bitset':\nreturn(values[physical>>>3]&(1<<(physical&7)))!==0;\ncase'multi':{\nif(!offsets)return null;\nconst from=offsets[physical];\nconst to=offsets[physical+1];\nconst out=new Array(to-from);\nfor(let i=from;i<to;i++)out[i-from]=dict?dict.valueOf(values[i]):values[i];\nreturn out;\n}\ndefault:\nreturn values[physical];\n}\n};\nreturn{\nid:packed.id,\nkind,\nnullable:packed.nullable,\nvalues,\npresence,\ndict,\noffsets,\nget,\nversion:packed.version,\n};\n}\nfunction unpackHandles(packed){\nconst out=new Array(packed.length);\nfor(let i=0;i<packed.length;i++)out[i]=unpackHandle(packed[i]);\nreturn out;\n}\nfunction createMaskPool(){\nconst masks=[];\nconst indices=[];\nreturn{\nmask(n){\nfor(let i=0;i<masks.length;i++){\nif(masks[i].length>=n){\nconst buf=masks.splice(i,1)[0].subarray(0,n);\nbuf.fill(0);\nreturn buf;\n}\n}\nreturn new Uint8Array(n);\n},\nindices(n){\nfor(let i=0;i<indices.length;i++){\nif(indices[i].length>=n)return indices.splice(i,1)[0].subarray(0,n);\n}\nreturn new Uint32Array(n);\n},\nrelease(buf){\nif(!buf)return;\nif(buf instanceof Uint8Array)masks.push(buf);\nelse if(buf instanceof Uint32Array)indices.push(buf);\n},\nclear(){masks.length=0;indices.length=0;},\n};\n}\nfunction isTransferable(v){\nif(!ArrayBuffer.isView(v))return false;\nconst buf=(v).buffer;\nif(!buf)return false;\nreturn typeof SharedArrayBuffer==='undefined'||!(buf instanceof SharedArrayBuffer);\n}\nfunction collectTransfers(value,out=[]){\nconst add=(v)=>{\nif(!isTransferable(v))return;\nconst buf=(v).buffer;\nif(!out.includes(buf))out.push(buf);\n};\nif(value==null)return out;\nif(ArrayBuffer.isView(value)){add(value);return out;}\nif(Array.isArray(value)){\nfor(const item of value)add(item);\nreturn out;\n}\nif(typeof value==='object'){\nfor(const key of Object.keys(value)){\nconst item=(value)[key];\nif(Array.isArray(item))for(const sub of item)add(sub);\nelse add(item);\n}\n}\nreturn out;\n}\nfunction isPortable(value,depth=0){\nif(value==null)return true;\nconst t=typeof value;\nif(t==='function'||t==='symbol')return false;\nif(t!=='object')return true;\nif(depth>4)return true;\nif(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||value instanceof Date)return true;\nif(Array.isArray(value)){\nfor(const item of value)if(!isPortable(item,depth+1))return false;\nreturn true;\n}\nfor(const key of Object.keys(value)){\nif(!isPortable((value)[key],depth+1))return false;\n}\nreturn true;\n}\nfunction filterColumnIds(filters,out=new Set()){\nif(!filters||typeof filters!=='object')return out;\nconst node=(filters);\nif(typeof node.col==='string')out.add(node.col);\nconst conditions=node.conditions;\nif(Array.isArray(conditions))for(const child of conditions)filterColumnIds(child,out);\nreturn out;\n}\n});\n__def(\"packages/core/src/store/bitset.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Bitset\",{enumerable:true,get:function(){return Bitset;}});\nconst WORD_BITS=8;\nclass Bitset{\nstatic#POP=new Uint8Array(256);\nstatic{\nfor(let i=1;i<256;i++)Bitset.#POP[i]=Bitset.#POP[i>>1]+(i&1);\n}\n#words;\n#bits;\nconstructor(bits=0){\nconst n=Math.max(0,bits|0);\nthis.#bits=n;\nthis.#words=new Uint8Array(Math.ceil(n/WORD_BITS));\n}\nget size(){return this.#bits;}\nget words(){return this.#words;}\nget bytes(){return this.#words?this.#words.byteLength:0;}\nget(i){\nif(i<0||i>=this.#bits)return 0;\nreturn(this.#words[i>>3]>>(i&7))&1;\n}\nset(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]|=1<<(i&7);\nreturn this;\n}\nclear(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]&=~(1<<(i&7));\nreturn this;\n}\nassign(i,bit){return bit?this.set(i):this.clear(i);}\nfill(bit=false){\nthis.#words.fill(bit?0xff:0);\nif(bit)this.#maskTail();\nreturn this;\n}\ngrow(bits){\nconst n=Math.max(0,bits|0);\nif(n<=this.#bits)return this;\nconst need=Math.ceil(n/WORD_BITS);\nif(need>this.#words.length){\nconst next=new Uint8Array(need);\nnext.set(this.#words);\nthis.#words=next;\n}\nthis.#bits=n;\nreturn this;\n}\ncount(){\nconst w=this.#words;\nconst pop=Bitset.#POP;\nlet total=0;\nfor(let i=0;i<w.length;i++)total+=pop[w[i]];\nreturn total;\n}\nand(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]&=b[i];\nfor(let i=shared;i<w.length;i++)w[i]=0;\nreturn this;\n}\nor(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]|=b[i];\nreturn this;\n}\nnot(){\nconst w=this.#words;\nfor(let i=0;i<w.length;i++)w[i]=~w[i]&0xff;\nthis.#maskTail();\nreturn this;\n}\nclone(){\nconst out=new Bitset(this.#bits);\nout.words.set(this.#words.subarray(0,out.words.length));\nreturn out;\n}\nrelease(){\nthis.#words=new Uint8Array(0);\nthis.#bits=0;\n}\n#maskTail(){\nconst used=this.#bits&7;\nif(used===0)return;\nconst last=(this.#bits>>3);\nif(last<this.#words.length)this.#words[last]&=(1<<used)-1;\n}\nstatic from(bools){\nconst arr=Array.isArray(bools)?bools:Array.from(bools);\nconst out=new Bitset(arr.length);\nfor(let i=0;i<arr.length;i++)if(arr[i])out.set(i);\nreturn out;\n}\n}\n});\n__def(\"packages/core/src/store/dictionary.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Dictionary\",{enumerable:true,get:function(){return Dictionary;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nclass Dictionary{\n#values;\n#codes=new Map();\n#version=0;\n#ranks=null;\n#ranksVersion=-1;\n#ranksLocale='\\u0000';\nconstructor(values=[]){\nthis.#values=[];\nfor(let i=0;i<values.length;i++){\nconst v=values[i];\nif(this.#codes.has(v))continue;\nthis.#codes.set(v,this.#values.length);\nthis.#values.push(v);\n}\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\nget bytes(){\nlet total=this.#values.length*8;\nfor(let i=0;i<this.#values.length;i++){\nconst v=this.#values[i];\nif(typeof v==='string')total+=v.length*2;\ntotal+=16;\n}\nreturn total;\n}\ncodeOf(value){\nconst existing=this.#codes.get(value);\nif(existing!==undefined)return existing;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#codes.set(value,code);\nthis.#version++;\nreturn code;\n}\nlookup(value){\nconst code=this.#codes.get(value);\nreturn code===undefined?-1:code;\n}\nhas(value){return this.#codes.has(value);}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nif(this.#ranks&&this.#ranksVersion===this.#version&&this.#ranksLocale===key){\nreturn this.#ranks;\n}\nconst n=this.#values.length;\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst values=this.#values;\norder.sort((a,b)=>this.#compare(values[a],values[b],cmp));\nconst ranks=new Uint32Array(n);\nfor(let rank=0;rank<n;rank++)ranks[order[rank]]=rank;\nthis.#ranks=ranks;\nthis.#ranksVersion=this.#version;\nthis.#ranksLocale=key;\nreturn ranks;\n}\n#compare(a,b,compare){\nif(typeof a==='string'&&typeof b==='string')return compare(a,b);\nreturn defaultCompare(a,b);\n}\n}\n});\n__def(\"packages/core/src/store/multivalue.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"MultiValue\",{enumerable:true,get:function(){return MultiValue;}});\nclass MultiValue{\n#values;\n#offsets;\n#rows=0;\n#fill=0;\nconstructor(capacity={}){\nconst rows=Math.max(1,capacity.rows??16);\nconst values=Math.max(1,capacity.values??rows);\nthis.#values=new Int32Array(values);\nthis.#offsets=new Uint32Array(rows+1);\n}\nget values(){return this.#values;}\nget offsets(){return this.#offsets;}\nget rows(){return this.#rows;}\nget length(){return this.#fill;}\nget bytes(){return this.#values.byteLength+this.#offsets.byteLength;}\ncount(r){\nif(r<0||r>=this.#rows)return 0;\nreturn this.#offsets[r+1]-this.#offsets[r];\n}\nat(r){\nif(r<0||r>=this.#rows)return this.#values.subarray(0,0);\nreturn this.#values.subarray(this.#offsets[r],this.#offsets[r+1]);\n}\nhas(r,code){\nif(r<0||r>=this.#rows)return false;\nconst v=this.#values;\nconst end=this.#offsets[r+1];\nfor(let i=this.#offsets[r];i<end;i++)if(v[i]===code)return true;\nreturn false;\n}\nhasAny(r,codes){\nfor(let i=0;i<codes.length;i++)if(this.has(r,codes[i]))return true;\nreturn false;\n}\nhasAll(r,codes){\nfor(let i=0;i<codes.length;i++)if(!this.has(r,codes[i]))return false;\nreturn true;\n}\nhasNone(r,codes){return!this.hasAny(r,codes);}\npush(codes){\nconst r=this.#rows;\nconst n=codes.length;\nthis.#ensureRows(r+1);\nthis.#ensureValues(this.#fill+n);\nconst start=this.#fill;\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nthis.#fill+=n;\nthis.#rows=r+1;\nthis.#offsets[r]=start;\nthis.#offsets[r+1]=this.#fill;\nreturn r;\n}\nwrite(r,codes){\nif(r===this.#rows){this.push(codes);return;}\nif(r<0||r>this.#rows)return;\nconst start=this.#offsets[r];\nconst end=this.#offsets[r+1];\nconst n=codes.length;\nif(end-start===n){\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nreturn;\n}\nthis.#rebuild(r,codes);\n}\ncompact(remap,liveCount,dead){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst oldRows=this.#rows;\nconst values=new Int32Array(Math.max(1,this.#fill));\nconst offsets=new Uint32Array(liveCount+1);\nlet w=0;\nfor(let p=0;p<oldRows;p++){\nif(remap[p]===dead)continue;\nconst start=oldOffsets[p];\nconst end=oldOffsets[p+1];\noffsets[remap[p]]=w;\nfor(let i=start;i<end;i++)values[w++]=oldValues[i];\noffsets[remap[p]+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#rows=liveCount;\nthis.#fill=w;\n}\nrelease(){\nthis.#values=new Int32Array(0);\nthis.#offsets=new Uint32Array(1);\nthis.#rows=0;\nthis.#fill=0;\n}\n#ensureRows(rows){\nif(rows+1<=this.#offsets.length)return;\nlet cap=this.#offsets.length-1;\nwhile(cap<rows)cap=cap*2||16;\nconst next=new Uint32Array(cap+1);\nnext.set(this.#offsets);\nthis.#offsets=next;\n}\n#ensureValues(n){\nif(n<=this.#values.length)return;\nlet cap=this.#values.length;\nwhile(cap<n)cap=cap*2||16;\nconst next=new Int32Array(cap);\nnext.set(this.#values);\nthis.#values=next;\n}\n#rebuild(r,codes){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst rows=this.#rows;\nconst delta=codes.length-(oldOffsets[r+1]-oldOffsets[r]);\nconst values=new Int32Array(Math.max(1,this.#fill+delta));\nconst offsets=new Uint32Array(oldOffsets.length);\nlet w=0;\nfor(let p=0;p<rows;p++){\noffsets[p]=w;\nif(p===r){\nfor(let i=0;i<codes.length;i++)values[w++]=codes[i]|0;\n}else{\nfor(let i=oldOffsets[p];i<oldOffsets[p+1];i++)values[w++]=oldValues[i];\n}\noffsets[p+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#fill=w;\n}\n}\n});\n__def(\"packages/core/src/store/columnstore.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"REMOVED\",{enumerable:true,get:function(){return REMOVED;}});\nObject.defineProperty(__exports,\"toFloat\",{enumerable:true,get:function(){return toFloat;}});\nObject.defineProperty(__exports,\"ColumnHandle\",{enumerable:true,get:function(){return ColumnHandle;}});\nObject.defineProperty(__exports,\"ColumnStore\",{enumerable:true,get:function(){return ColumnStore;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/bitset.js\");\nconst Bitset=__m1[\"Bitset\"];\nconst __m2=__req(\"packages/core/src/store/dictionary.js\");\nconst Dictionary=__m2[\"Dictionary\"];\nconst __m3=__req(\"packages/core/src/store/multivalue.js\");\nconst MultiValue=__m3[\"MultiValue\"];\nconst REMOVED=0xFFFFFFFF;\nconst DEFAULT_CAPACITY=1024;\nconst DEFAULT_COLUMNAR_BELOW=5000;\nconst DEFAULT_COMPACT_RATIO=0.2;\nconst KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction absent(v){return v===null||v===undefined;}\nfunction toFloat(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(typeof v==='boolean')return v?1:0;\nconst n=Number(v);\nreturn Number.isNaN(n)&&typeof v==='string'?Date.parse(v):n;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(absent(v))return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction decodeFrom(old,p){\nswitch(old.kind){\ncase'float64':\ncase'int32':return old.buf[p];\ncase'bitset':return old.bits.get(p)===1;\ncase'dictionary':return old.dict.valueOf(old.buf[p]);\ncase'multi':{\nconst codes=old.mv.at(p);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=old.dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return old.buf[p];\n}\n}\nfunction decodePacked(frag,i){\nswitch(frag.kind){\ncase'float64':\ncase'int32':return frag.values[i];\ncase'bitset':return(frag.values[i>>3]&(1<<(i&7)))!==0;\ncase'dictionary':return(frag.table||[])[frag.values[i]];\ncase'multi':{\nconst start=frag.offsets[i];\nconst end=frag.offsets[i+1];\nconst table=frag.table||[];\nconst out=new Array(end-start);\nfor(let k=start;k<end;k++)out[k-start]=table[frag.values[k]];\nreturn out;\n}\ndefault:return frag.values[i];\n}\n}\nclass ColumnHandle{\n#id;\n#kind;\n#target;\n#nullable;\n#read;\n#host;\n#seed;\n#columnar=false;\n#buf=null;\n#bits=null;\n#mv=null;\n#dict=null;\n#presence=null;\n#capacity=0;\n#version=0;\n#overlay=null;\n#cache=null;\n#released=false;\nconstructor(schema,host){\nthis.#id=schema.id;\nconst kind=KINDS.has(schema.kind)?schema.kind:'object';\nif(schema.kind&&!KINDS.has(schema.kind)){\nwarnOnce(`store.kind.${schema.id}`,\n`column \"${schema.id}\" declares unknown storage kind \"${schema.kind}\"; falling back to object`);\n}\nthis.#target=kind;\nthis.#kind=kind;\nthis.#nullable=schema.nullable!==false;\nthis.#seed=schema.dictionary??null;\nthis.#host=host;\nthis.#read=isFunction(schema.read)\n?schema.read\n:pathGetter(schema.field||schema.id);\nthis.#overlay=new Map();\n}\nget id(){return this.#id;}\nget kind(){return this.#columnar?this.#kind:'object';}\nget target(){return this.#target;}\nget nullable(){return this.#nullable;}\nget values(){\nif(this.#released)return null;\nif(!this.#columnar)return this.#lazy().values;\nif(this.#kind==='bitset')return this.#bits.words;\nif(this.#kind==='multi')return this.#mv.values;\nreturn this.#buf;\n}\nget presence(){\nif(this.#released||!this.#nullable)return null;\nreturn this.#columnar?this.#presence:this.#lazy().presence;\n}\nget dict(){\nif(this.#released||!this.#columnar)return null;\nreturn this.#kind==='dictionary'||this.#kind==='multi'?this.#dict:null;\n}\nget offsets(){\nif(this.#released||!this.#columnar||this.#kind!=='multi')return null;\nreturn this.#mv.offsets;\n}\nget version(){return this.#version;}\nget bytes(){\nlet total=0;\nif(this.#buf)total+=this.#buf.byteLength??this.#buf.length*8;\nif(this.#bits)total+=this.#bits.bytes;\nif(this.#mv)total+=this.#mv.bytes;\nif(this.#presence)total+=this.#presence.bytes;\nif(this.#dict)total+=this.#dict.bytes;\nif(this.#overlay)total+=this.#overlay.size*24;\nreturn total;\n}\nget(physical){\nif(this.#released)return undefined;\nif(physical<0||physical>=this.#host.physical())return undefined;\nif(!this.#columnar)return this.#rowValue(physical);\nif(this.#nullable&&this.#presence.get(physical)===0)return null;\nswitch(this.#kind){\ncase'float64':\ncase'int32':return this.#buf[physical];\ncase'bitset':return this.#bits.get(physical)===1;\ncase'dictionary':return this.#dict.valueOf(this.#buf[physical]);\ncase'multi':{\nconst codes=this.#mv.at(physical);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=this.#dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return this.#buf[physical];\n}\n}\nset(physical,value){\nif(this.#released)return;\nif(this.#columnar)this.#writeValue(physical,value);\nelse this.#overlay.set(physical,value===undefined?null:value);\nthis.#version++;\n}\nread(row){return this.#read(row);}\nappendColumn(objects,from,n){\nif(this.#released||n<=0)return;\nif(!this.#columnar){this.#version++;return;}\nconst read=this.#read;\nconst nullable=this.#nullable;\nconst presence=this.#presence;\nlet sawAbsent=false;\nswitch(this.#kind){\ncase'float64':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nif(typeof v==='number'){\nif(nullable)presence.set(from+i);\nbuf[from+i]=v;\ncontinue;\n}\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?NaN:toFloat(v);\n}\nbreak;\n}\ncase'int32':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:toInt(v);\n}\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbits.assign(from+i,!gone&&!!v);\n}\nbreak;\n}\ncase'dictionary':{\nconst buf=this.#buf;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:dict.codeOf(v);\n}\nbreak;\n}\ncase'multi':{\nconst mv=this.#mv;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nconst members=toMembers(v);\nconst codes=new Array(members.length);\nfor(let k=0;k<members.length;k++)codes[k]=dict.codeOf(members[k]);\nmv.write(from+i,codes);\n}\nbreak;\n}\ndefault:{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?null:v;\n}\nbreak;\n}\n}\nif(sawAbsent){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nthis.#version++;\n}\nappendPacked(frag,from,n){\nif(this.#released||n<=0||!frag)return;\nif(!this.#columnar){this.#version++;return;}\nconst presence=this.#presence;\nconst fragPresence=frag.presence;\nif(presence){\nif(fragPresence){\nfor(let i=0;i<n;i++)presence.assign(from+i,(fragPresence[i>>3]&(1<<(i&7)))!==0);\n}else{\nfor(let i=0;i<n;i++)presence.set(from+i);\n}\n}\nconst kindsAgree=frag.kind===this.#kind;\nif(kindsAgree&&(this.#kind==='float64'||this.#kind==='int32')){\nthis.#buf.set(frag.values,from);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='bitset'){\nconst words=frag.values;\nfor(let i=0;i<n;i++)this.#bits.assign(from+i,(words[i>>3]&(1<<(i&7)))!==0);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='dictionary'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst codes=frag.values;\nconst buf=this.#buf;\nconst pres=presence;\nfor(let i=0;i<n;i++){\nif(pres&&(fragPresence?(fragPresence[i>>3]&(1<<(i&7)))===0:false)){buf[from+i]=0;continue;}\nbuf[from+i]=remap[codes[i]]??0;\n}\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='multi'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst flat=frag.values;\nconst offsets=frag.offsets;\nfor(let i=0;i<n;i++){\nconst start=offsets[i];\nconst end=offsets[i+1];\nconst codes=new Array(end-start);\nfor(let k=start;k<end;k++)codes[k-start]=remap[flat[k]]??0;\nthis.#mv.write(from+i,codes);\n}\nthis.#version++;\nreturn;\n}\nfor(let i=0;i<n;i++){\nconst gone=fragPresence\n?(fragPresence[i>>3]&(1<<(i&7)))===0\n:(frag.kind==='object'?frag.values[i]===null:false);\nthis.#writeValue(from+i,gone?null:decodePacked(frag,i));\n}\nthis.#version++;\n}\ntouch(){this.#version++;}\ncolumnarise(capacity,fill){\nif(this.#columnar||this.#released)return;\nconst values=new Array(fill);\nfor(let p=0;p<fill;p++)values[p]=this.#rowValue(p);\nthis.#kind=this.#target;\nthis.#columnar=true;\nthis.#alloc(capacity);\nfor(let p=0;p<fill;p++)this.#writeValue(p,values[p]);\nthis.#overlay.clear();\nthis.#cache=null;\nthis.#version++;\n}\ngrow(capacity){\nif(!this.#columnar||this.#released||capacity<=this.#capacity)return;\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':{\nconst next=new this.#buf.constructor(capacity);\nnext.set(this.#buf);\nthis.#buf=next;\nbreak;\n}\ncase'bitset':this.#bits.grow(capacity);break;\ncase'multi':break;\ndefault:this.#buf.length=capacity;break;\n}\nif(this.#presence)this.#presence.grow(capacity);\nthis.#capacity=capacity;\nthis.#version++;\n}\nconvert(kind){\nif(this.#released||!KINDS.has(kind))return false;\nthis.#target=kind;\nif(!this.#columnar||kind===this.#kind)return false;\nconst old={kind:this.#kind,buf:this.#buf,bits:this.#bits,mv:this.#mv,dict:this.#dict};\nconst n=this.#host.physical();\nconst presence=this.#presence;\nthis.#kind=kind;\nthis.#alloc(this.#capacity);\nfor(let p=0;p<n;p++){\nconst gone=presence!==null&&presence.get(p)===0;\nif(gone&&kind!=='multi')continue;\nthis.#writeValue(p,gone?null:decodeFrom(old,p));\n}\nthis.#version++;\nreturn true;\n}\ncompact(remap,oldFill,liveCount){\nif(this.#released)return;\nif(!this.#columnar){\nconst overlay=this.#overlay;\nif(overlay.size){\nconst next=new Map();\nfor(const[p,v]of overlay)if(remap[p]!==REMOVED)next.set(remap[p],v);\nthis.#overlay=next;\n}\nthis.#cache=null;\nthis.#version++;\nreturn;\n}\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':case'object':{\nconst buf=this.#buf;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)buf[remap[p]]=buf[p];\nif(this.#kind==='object')for(let p=liveCount;p<oldFill;p++)buf[p]=undefined;\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)bits.assign(remap[p],bits.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)bits.clear(p);\nbreak;\n}\ncase'multi':this.#mv.compact(remap,liveCount,REMOVED);break;\ndefault:break;\n}\nif(this.#presence){\nconst pres=this.#presence;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)pres.assign(remap[p],pres.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)pres.clear(p);\n}\nthis.#version++;\n}\nrelease(){\nif(this.#released)return;\nthis.#released=true;\nthis.#buf=null;\nif(this.#bits)this.#bits.release();\nthis.#bits=null;\nif(this.#mv)this.#mv.release();\nthis.#mv=null;\nif(this.#presence)this.#presence.release();\nthis.#presence=null;\nthis.#dict=null;\nthis.#overlay=new Map();\nthis.#cache=null;\nthis.#capacity=0;\nthis.#version++;\n}\n#alloc(capacity){\nconst cap=Math.max(1,capacity);\nthis.#buf=null;\nthis.#bits=null;\nthis.#mv=null;\nswitch(this.#kind){\ncase'float64':this.#buf=new Float64Array(cap);break;\ncase'int32':this.#buf=new Int32Array(cap);break;\ncase'bitset':this.#bits=new Bitset(cap);break;\ncase'dictionary':\nthis.#buf=new Uint32Array(cap);\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ncase'multi':\nthis.#mv=new MultiValue({rows:cap,values:cap});\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ndefault:this.#buf=new Array(cap);break;\n}\nif(this.#kind!=='dictionary'&&this.#kind!=='multi')this.#dict=null;\nif(this.#nullable){\nif(this.#presence)this.#presence.grow(cap);\nelse this.#presence=new Bitset(cap);\n}\nthis.#capacity=cap;\n}\n#writeValue(p,value){\nconst gone=absent(value);\nif(this.#nullable)this.#presence.assign(p,!gone);\nelse if(gone){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nswitch(this.#kind){\ncase'float64':this.#buf[p]=gone?NaN:toFloat(value);break;\ncase'int32':this.#buf[p]=gone?0:toInt(value);break;\ncase'bitset':this.#bits.assign(p,!gone&&!!value);break;\ncase'dictionary':this.#buf[p]=gone?0:this.#dict.codeOf(value);break;\ncase'multi':{\nconst members=toMembers(value);\nconst codes=new Array(members.length);\nfor(let i=0;i<members.length;i++)codes[i]=this.#dict.codeOf(members[i]);\nthis.#mv.write(p,codes);\nbreak;\n}\ndefault:this.#buf[p]=gone?null:value;break;\n}\n}\n#rowValue(p){\nif(this.#overlay.has(p))return this.#overlay.get(p);\nconst v=this.#read(this.#host.rowAt(p));\nreturn v===undefined?null:v;\n}\n#lazy(){\nif(this.#cache&&this.#cache.version===this.#version)return this.#cache;\nconst n=this.#host.physical();\nconst values=new Array(n);\nconst presence=this.#nullable?new Bitset(n):null;\nfor(let p=0;p<n;p++){\nconst v=this.#rowValue(p);\nvalues[p]=v;\nif(presence&&!absent(v))presence.set(p);\n}\nthis.#cache={version:this.#version,values,presence};\nreturn this.#cache;\n}\n}\nclass ColumnStore{\n#schema;\n#handles=new Map();\n#list=[];\n#rows=[];\n#fill=0;\n#capacity=0;\n#live=0;\n#dead=0;\n#tombs=new Bitset(0);\n#columnar=false;\n#retainSource=true;\n#columnarBelow;\n#initial;\n#ratio;\n#destroyed=false;\nconstructor(schema,opts={}){\nthis.#schema=Array.isArray(schema)?schema:[];\nthis.#initial=Math.max(1,opts.initialCapacity??DEFAULT_CAPACITY);\nthis.#retainSource=opts.retainSource!==false;\nthis.#columnarBelow=this.#retainSource?(opts.columnarBelow??DEFAULT_COLUMNAR_BELOW):0;\nthis.#ratio=opts.compactRatio??DEFAULT_COMPACT_RATIO;\nconst host={\nrowAt:(p)=>this.#rows[p],\nphysical:()=>this.#fill,\n};\nfor(const entry of this.#schema){\nif(!entry||!entry.id)continue;\nif(this.#handles.has(entry.id)){\nwarnOnce(`store.dup.${entry.id}`,`duplicate column id \"${entry.id}\" in the store schema; ignoring the second`);\ncontinue;\n}\nconst handle=new ColumnHandle(entry,host);\nthis.#handles.set(entry.id,handle);\nthis.#list.push(handle);\n}\nif(this.#columnarBelow<=0)this.#columnarise();\n}\nget count(){return this.#live;}\nget physical(){return this.#fill;}\nget capacity(){return this.#columnar?this.#capacity:this.#rows.length;}\nget tombstones(){return this.#dead;}\nget columnar(){return this.#columnar;}\nget destroyed(){return this.#destroyed;}\nget bytes(){\nlet total=this.#tombs.bytes+this.#rows.length*8;\nfor(const h of this.#list)total+=h.bytes;\nreturn total;\n}\nappend(objects){\nconst from=this.#fill;\nif(this.#destroyed||!objects)return{from,to:from};\nconst n=objects.length|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource)for(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar){\nif(this.#fill>=this.#columnarBelow)this.#columnarise();\nelse for(const h of this.#list)h.touch();\nreturn{from,to:this.#fill};\n}\nthis.#ensure(this.#fill);\nconst cols=this.#list;\nfor(let c=0;c<cols.length;c++)cols[c].appendColumn(objects,from,n);\nreturn{from,to:this.#fill};\n}\nappendPacked(chunk,objects){\nconst from=this.#fill;\nif(this.#destroyed||!chunk)return{from,to:from};\nconst n=chunk.count|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource&&objects){\nfor(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\n}\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar)this.#columnarise();\nthis.#ensure(this.#fill);\nconst byId=new Map();\nfor(const col of chunk.columns)byId.set(col.id,col);\nfor(const h of this.#list){\nconst frag=byId.get(h.id);\nif(frag)h.appendPacked(frag,from,n);\nelse{\nh.grow(this.#capacity);\n}\n}\nreturn{from,to:this.#fill};\n}\nsource(physical){\nif(this.#retainSource)return this.#rows[physical];\nif(physical<0||physical>=this.#fill)return undefined;\nreturn this.#reconstruct(physical);\n}\nsetSource(physical,object){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nif(!this.#retainSource)return;\nthis.#rows[physical]=object;\n}\nget(colId,physical){\nconst h=this.#handles.get(colId);\nreturn h?h.get(physical):undefined;\n}\nset(colId,physical,value){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nconst h=this.#handles.get(colId);\nif(!h){\nwarnOnce(`store.set.${colId}`,`set() on unknown column \"${colId}\"`);\nreturn;\n}\nh.set(physical,value);\n}\nremove(physical){\nif(this.#destroyed||physical<0||physical>=this.#fill)return false;\nif(this.#tombs.get(physical)===1)return false;\nthis.#tombs.set(physical);\nthis.#dead++;\nthis.#live--;\nreturn true;\n}\nlive(physical){\nif(physical<0||physical>=this.#fill)return false;\nreturn this.#tombs.get(physical)===0;\n}\ncompact(opts={}){\nif(this.#destroyed||this.#dead===0)return null;\nif(!opts.force&&this.#dead/this.#fill<this.#ratio)return null;\nconst oldFill=this.#fill;\nconst remap=new Uint32Array(oldFill);\nlet w=0;\nfor(let p=0;p<oldFill;p++)remap[p]=this.#tombs.get(p)===1?REMOVED:w++;\nfor(const h of this.#list)h.compact(remap,oldFill,w);\nif(this.#retainSource){\nconst rows=this.#rows;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)rows[remap[p]]=rows[p];\nrows.length=w;\n}\nthis.#fill=w;\nthis.#live=w;\nthis.#dead=0;\nthis.#tombs=new Bitset(Math.max(this.#capacity,w));\nreturn remap;\n}\ncolumn(colId){return this.#handles.get(colId);}\ncolumns(){return this.#list.slice();}\nliveIndices(){\nconst out=new Uint32Array(this.#live);\nif(this.#dead===0){\nfor(let p=0;p<this.#fill;p++)out[p]=p;\nreturn out;\n}\nlet k=0;\nfor(let p=0;p<this.#fill;p++)if(this.#tombs.get(p)===0)out[k++]=p;\nreturn out;\n}\nconvert(colId,kind){\nconst h=this.#handles.get(colId);\nreturn h?h.convert(kind):false;\n}\ndestroy(){\nif(this.#destroyed)return;\nthis.#destroyed=true;\nfor(const h of this.#list)h.release();\nthis.#handles.clear();\nthis.#list.length=0;\nthis.#rows.length=0;\nthis.#tombs.release();\nthis.#fill=0;\nthis.#live=0;\nthis.#dead=0;\nthis.#capacity=0;\n}\n#ensure(n){\nif(n<=this.#capacity)return;\nlet cap=this.#capacity||this.#initial;\nwhile(cap<n)cap*=2;\nfor(const h of this.#list)h.grow(cap);\nthis.#tombs.grow(cap);\nthis.#capacity=cap;\n}\n#reconstruct(physical){\nconst out={};\nfor(const h of this.#list)out[h.id]=h.get(physical);\nreturn out;\n}\n#columnarise(){\nif(this.#columnar)return;\nlet cap=this.#initial;\nwhile(cap<this.#fill)cap*=2;\nthis.#columnar=true;\nthis.#capacity=cap;\nthis.#tombs.grow(cap);\nfor(const h of this.#list)h.columnarise(cap,this.#fill);\n}\n}\n});\n__def(\"packages/core/src/store/ingest.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"INGEST_DEFAULTS\",{enumerable:true,get:function(){return INGEST_DEFAULTS;}});\nObject.defineProperty(__exports,\"inferKind\",{enumerable:true,get:function(){return inferKind;}});\nObject.defineProperty(__exports,\"decideText\",{enumerable:true,get:function(){return decideText;}});\nObject.defineProperty(__exports,\"createReaders\",{enumerable:true,get:function(){return createReaders;}});\nObject.defineProperty(__exports,\"Ingest\",{enumerable:true,get:function(){return Ingest;}});\nObject.defineProperty(__exports,\"ingest\",{enumerable:true,get:function(){return ingest;}});\nObject.defineProperty(__exports,\"ingestSync\",{enumerable:true,get:function(){return ingestSync;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst now=__m0[\"now\"];\nconst nextFrame=__m0[\"nextFrame\"];\nconst infoOnce=__m0[\"infoOnce\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/columnstore.js\");\nconst ColumnStore=__m1[\"ColumnStore\"];\nconst INGEST_DEFAULTS=Object.freeze({\nchunkMs:8,\nchunkRows:512,\nsampleSize:100,\ndictionaryRatio:0.1,\ncolumnarBelow:5000,\ninitialCapacity:1024,\n});\nfunction inferKind(samples,hints={}){\nif(hints.multi)return'multi';\nif(samples.length===0)return'object';\nlet numbers=0;let booleans=0;let strings=0;let dates=0;let arrays=0;\nfor(let i=0;i<samples.length;i++){\nconst v=samples[i];\nif(typeof v==='number')numbers++;\nelse if(typeof v==='boolean')booleans++;\nelse if(typeof v==='string')strings++;\nelse if(v instanceof Date)dates++;\nelse if(Array.isArray(v))arrays++;\n}\nconst n=samples.length;\nif(numbers===n)return'float64';\nif(booleans===n)return'bitset';\nif(dates===n)return'float64';\nif(strings===n)return'text';\nif(arrays===n)return'multi';\nreturn'object';\n}\nfunction decideText(distinct,rows,ratio){\nif(rows<=0)return'dictionary';\nreturn distinct<ratio*rows?'dictionary':'object';\n}\nfunction createReaders(columns,computed,context){\nconst readers=new Map();\nconst base=new Map();\nfor(const col of columns){\nif(col.computed)continue;\nconst read=isFunction(col.read)?col.read:pathGetter(col.field||col.id);\nbase.set(col.id,read);\nreaders.set(col.id,read);\n}\nconst order=computed?.order??[];\nconst fns=computed?.fns??{};\nconst deps=computed?.deps??{};\nconst wrapDeps=computed?.wrapDeps??null;\nconst active=order.filter((id)=>isFunction(fns[id]));\nconst wildcard=active.some((id)=>deps[id]==='*');\nlet memo=new WeakMap();\nconst resolve=(data)=>{\nconst values={};\nif(wildcard)for(const[id,read]of base)values[id]=read(data);\nfor(const id of active){\nconst declared=deps[id];\nlet bag;\nif(declared==='*'){\nbag=values;\n}else{\nbag={};\nconst list=declared||[];\nfor(let i=0;i<list.length;i++){\nconst d=list[i];\nbag[d]=d in values?values[d]:base.get(d)?.(data);\n}\n}\nvalues[id]=fns[id](wrapDeps?wrapDeps(bag,id):bag,{\ndata,row:null,column:null,grid:null,context,\n});\n}\nreturn values;\n};\nconst valuesFor=(data)=>{\nif(data===null||(typeof data!=='object'&&typeof data!=='function'))return resolve(data);\nlet v=memo.get(data);\nif(v===undefined){v=resolve(data);memo.set(data,v);}\nreturn v;\n};\nfor(const id of active){\nreaders.set(id,\n(data)=>valuesFor(data)[id]);\n}\nreturn{\nreaders,\nreset(){memo=new WeakMap();},\n};\n}\nclass ColumnPlan{\nspec;\nread;\nkind;\ninferred;\nnullable;\ncandidate=false;\ndistinct=null;\nchange=null;\nreason='';\nconstructor(spec,read){\nthis.spec=spec;\nthis.read=read;\nthis.kind='object';\nthis.inferred=false;\nthis.nullable=spec.nullable!==false;\n}\n}\nclass Ingest{\n#rows;\n#plans=[];\n#store=null;\n#readers;\n#cursor=0;\n#opts;\n#done=false;\n#cancelled=false;\n#elapsed=0;\n#columnar;\nconstructor(rows,plan={},opts={}){\nthis.#rows=Array.isArray(rows)?rows:Array.from(rows||[]);\nthis.#opts={...INGEST_DEFAULTS,...opts};\nconst columns=plan.columns??[];\nthis.#readers=createReaders(columns,plan.computed??null,plan.context);\nthis.#columnar=this.#rows.length>=this.#opts.columnarBelow;\nthis.#planColumns(columns,plan.computed??null);\nthis.#store=new ColumnStore(this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\nread:p.read,\ndictionary:p.spec.dictionary,\n})),{\ninitialCapacity:this.#opts.initialCapacity,\ncolumnarBelow:this.#opts.columnarBelow,\n});\n}\nget store(){return this.#store;}\nget done(){return this.#done||this.#cancelled;}\nget progress(){return this.#cursor;}\nslice(){\nif(this.done)return false;\nif(this.#opts.signal?.aborted){this.#cancelled=true;return false;}\nconst started=now();\nconst{chunkMs,chunkRows}=this.#opts;\nconst total=this.#rows.length;\ndo{\nconst end=Math.min(this.#cursor+chunkRows,total);\nthis.#store.append(this.#rows.slice(this.#cursor,end));\nthis.#measure(this.#cursor,end);\nthis.#cursor=end;\nthis.#readers.reset();\nthis.#reviewCardinality(false);\n}while(this.#cursor<total&&now()-started<chunkMs);\nthis.#elapsed+=now()-started;\nthis.#opts.onProgress?.({loaded:this.#cursor,total});\nif(this.#cursor>=total){\nthis.#reviewCardinality(true);\nthis.#done=true;\nreturn false;\n}\nreturn true;\n}\ncancel(){this.#cancelled=true;}\nresult(){\nreturn{\nstore:this.#store,\nschema:this.#plans.map((p)=>({\nid:p.spec.id,kind:p.kind,nullable:p.nullable,read:p.read,\ndictionary:p.spec.dictionary,\n})),\ndecisions:this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\ninferred:p.inferred,\ndistinct:p.candidate||p.change?this.#distinctOf(p):null,\nchange:p.change,\nreason:p.reason,\n})),\ncount:this.#store.count,\nelapsed:this.#elapsed,\ncancelled:this.#cancelled,\n};\n}\n#planColumns(columns,computed){\nconst rows=this.#rows;\nconst sampleN=Math.min(this.#opts.sampleSize,rows.length);\nconst ratio=this.#opts.dictionaryRatio;\nconst pure=computed?.pure instanceof Set\n?computed.pure\n:new Set(computed?.pure??computed?.order??[]);\nfor(const spec of columns){\nif(!spec||!spec.id)continue;\nif(spec.computed&&(spec.pure===false||(computed&&!pure.has(spec.id)))){\nwarnOnce(`ingest.impure.${spec.id}`,\n`column \"${spec.id}\" is an impure computed column and is not materialised into the store`);\ncontinue;\n}\nconst read=this.#readers.readers.get(spec.id)\n??(isFunction(spec.read)?spec.read:pathGetter(spec.field||spec.id));\nconst plan=new ColumnPlan(spec,read);\nif(spec.kind){\nplan.kind=spec.kind;\nplan.reason='declared by the caller';\n}else if(spec.dictionary){\nplan.kind=spec.multi?'multi':'dictionary';\nplan.reason='value table supplied (lookup column)';\n}else{\nconst samples=[];\nfor(let i=0;i<sampleN&&samples.length<this.#opts.sampleSize;i++){\nconst v=read(rows[i]);\nif(v!==null&&v!==undefined)samples.push(v);\n}\nplan.inferred=true;\nconst kind=inferKind(samples,{multi:spec.multi});\nif(kind==='text'){\nconst distinct=new Set(samples).size;\nplan.kind=decideText(distinct,samples.length,ratio);\nplan.candidate=this.#columnar;\nplan.reason=`sampled ${distinct} distinct in ${samples.length}`;\n}else{\nplan.kind=kind;\nplan.reason=`inferred from ${samples.length} sampled values`;\nif(kind==='object'&&samples.length){\ninfoOnce(`ingest.mixed.${spec.id}`,\n`column \"${spec.id}\" holds mixed or unrecognised value types; storing as an object array. Declare a type to avoid this.`);\n}\n}\nif(plan.kind==='object'&&plan.candidate)plan.distinct=new Set(samples);\n}\nthis.#plans.push(plan);\n}\n}\n#measure(from,to){\nconst rows=this.#rows;\nfor(const plan of this.#plans){\nif(!plan.candidate||!plan.distinct)continue;\nconst set=plan.distinct;\nfor(let i=from;i<to;i++){\nconst v=plan.read(rows[i]);\nif(v!==null&&v!==undefined)set.add(v);\n}\n}\n}\n#distinctOf(plan){\nif(plan.distinct)return plan.distinct.size;\nconst handle=this.#store.column(plan.spec.id);\nreturn handle?.dict?handle.dict.size:0;\n}\n#reviewCardinality(final){\nconst ratio=this.#opts.dictionaryRatio;\nconst total=this.#rows.length;\nfor(const plan of this.#plans){\nif(!plan.candidate)continue;\nconst distinct=this.#distinctOf(plan);\nif(plan.kind==='dictionary'&&distinct>=ratio*total){\nconst handle=this.#store.column(plan.spec.id);\nplan.distinct=new Set(handle?.dict?handle.dict.values():[]);\nthis.#store.convert(plan.spec.id,'object');\nplan.kind='object';\nplan.change='demoted';\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(plan.kind==='object'&&distinct>=ratio*total){\nplan.candidate=false;\nplan.distinct=null;\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(final&&plan.kind==='object'&&distinct<ratio*total){\nthis.#store.convert(plan.spec.id,'dictionary');\nplan.kind='dictionary';\nplan.change=plan.change==='demoted'?null:'promoted';\nplan.reason=`${distinct} distinct values is below ${ratio*100}% of ${total} rows`;\nplan.distinct=null;\n}\nif(final)plan.candidate=false;\n}\n}\n}\nasync function ingest(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,opts);\nconst frame=opts.scheduler?.frame??nextFrame;\nwhile(run.slice()){\nawait new Promise((resolve)=>{frame(resolve);});\n}\nreturn run.result();\n}\nfunction ingestSync(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,{...opts,chunkMs:Infinity});\nwhile(run.slice());\nreturn run.result();\n}\n});\n__def(\"packages/core/src/store/columnpack.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"isPortableSchema\",{enumerable:true,get:function(){return isPortableSchema;}});\nObject.defineProperty(__exports,\"packChunk\",{enumerable:true,get:function(){return packChunk;}});\nObject.defineProperty(__exports,\"packedTransfers\",{enumerable:true,get:function(){return packedTransfers;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/ingest.js\");\nconst inferKind=__m1[\"inferKind\"];\nconst decideText=__m1[\"decideText\"];\nconst INGEST_DEFAULTS=__m1[\"INGEST_DEFAULTS\"];\nconst __m2=__req(\"packages/core/src/store/columnstore.js\");\nconst toFloat=__m2[\"toFloat\"];\nconst PORTABLE_KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction isPortableSchema(schema){\nif(!Array.isArray(schema)||schema.length===0)return false;\nfor(const col of schema){\nif(!col||typeof col.id!=='string')return false;\nif(typeof col.field!=='string'||col.field==='')return false;\nif(col.kind&&!PORTABLE_KINDS.has(col.kind))return false;\n}\nreturn true;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(v===null||v===undefined)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction resolveKind(col,values,rows,ratio){\nif(col.kind)return col.kind;\nconst samples=[];\nfor(let i=0;i<values.length&&samples.length<INGEST_DEFAULTS.sampleSize;i++){\nconst v=values[i];\nif(v!==null&&v!==undefined)samples.push(v);\n}\nconst kind=inferKind(samples,{multi:col.multi});\nif(kind!=='text')return kind;\nconst distinct=new Set(samples).size;\nreturn decideText(distinct,samples.length,ratio);\n}\nfunction packChunk(schema,rows,opts={}){\nconst n=rows.length|0;\nconst ratio=opts.dictionaryRatio??INGEST_DEFAULTS.dictionaryRatio;\nconst columns=[];\nfor(const col of schema){\nconst read=pathGetter(col.field||col.id);\nconst nullable=col.nullable!==false;\nconst raw=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=read(rows[i]);\nraw[i]=v===undefined?null:v;\n}\nconst kind=resolveKind(col,raw,n,ratio);\nconst presence=nullable?new Uint8Array((n+7)>>3):null;\nconst present=(i)=>{if(presence)presence[i>>3]|=1<<(i&7);};\nlet packed;\nswitch(kind){\ncase'float64':{\nconst values=new Float64Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?NaN:toFloat(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'int32':{\nconst values=new Int32Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?0:toInt(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'bitset':{\nconst words=new Uint8Array((n+7)>>3);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nif(!gone&&!!v)words[i>>3]|=1<<(i&7);\n}\npacked={id:col.id,kind,nullable,values:words,presence,offsets:null,table:null};\nbreak;\n}\ncase'dictionary':{\nconst codes=new Uint32Array(n);\nconst table=[];\nconst index=new Map();\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v===null){codes[i]=0;continue;}\npresent(i);\nlet code=index.get(v);\nif(code===undefined){code=table.length;table.push(v);index.set(v,code);}\ncodes[i]=code;\n}\npacked={id:col.id,kind,nullable,values:codes,presence,offsets:null,table};\nbreak;\n}\ncase'multi':{\nconst table=[];\nconst index=new Map();\nconst offsets=new Uint32Array(n+1);\nconst flat=[];\nfor(let i=0;i<n;i++){\nconst v=raw[i];\noffsets[i]=flat.length;\nconst gone=v===null;\nif(!gone)present(i);\nconst members=toMembers(v);\nfor(let k=0;k<members.length;k++){\nconst m=members[k];\nlet code=index.get(m);\nif(code===undefined){code=table.length;table.push(m);index.set(m,code);}\nflat.push(code);\n}\n}\noffsets[n]=flat.length;\npacked={id:col.id,kind,nullable,values:Int32Array.from(flat),presence,offsets,table};\nbreak;\n}\ndefault:{\nconst values=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v!==null)present(i);\nvalues[i]=v;\n}\npacked={id:col.id,kind:'object',nullable,values,presence,offsets:null,table:null};\nbreak;\n}\n}\ncolumns.push(packed);\n}\nreturn{count:n,columns};\n}\nfunction packedTransfers(chunk){\nconst out=[];\nif(!chunk||!Array.isArray(chunk.columns))return out;\nconst add=(v)=>{\nif(ArrayBuffer.isView(v)&&v.buffer&&!out.includes(v.buffer))out.push(v.buffer);\n};\nfor(const col of chunk.columns){\nadd(col.values);\nadd(col.presence);\nadd(col.offsets);\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/compute/handle.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return identity;}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return rowCount;}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return bitReader;}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return presenceReader;}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return dictSize;}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return dictValue;}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return multiValue;}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return valueReader;}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return numericTotalOrder;}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return valueComparator;}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return dictRanks;}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return isMissing;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nconst warnOnce=__m0[\"warnOnce\"];\nfunction identity(n){\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[i]=i;\nreturn out;\n}\nfunction rowCount(handle,opts){\nif(opts&&typeof opts.count==='number')return opts.count;\nif(!handle)return 0;\nif(typeof handle.count==='number')return handle.count;\nif(typeof handle.length==='number')return handle.length;\nconst values=handle.values;\nif(handle.kind==='multi'&&handle.offsets)return Math.max(0,handle.offsets.length-1);\nif(!values)return handle.presence&&typeof handle.presence.size==='number'?handle.presence.size:0;\nif(handle.kind==='bitset'){\nif(typeof values.size==='number')return values.size;\nif(handle.presence&&typeof handle.presence.size==='number')return handle.presence.size;\nwarnOnce(`count:${handle.id}`,`column \"${handle.id}\" is bitset-backed with no declared row count; assuming ${values.length*8}`);\nreturn values.length*8;\n}\nreturn values.length;\n}\nconst bitOrders=new WeakMap();\nfunction bitOrderOf(bitset){\nconst ctor=bitset.constructor;\nif(!ctor)return'unknown';\nconst cached=bitOrders.get(ctor);\nif(cached)return cached;\nlet order='unknown';\ntry{\nlet probe=null;\nif(typeof ctor.from==='function')probe=ctor.from([false,true]);\nelse{\nprobe=new ctor(8);\nprobe.set(1);\n}\nconst words=probe&&probe.words;\nif(words&&words.length){\nif(words[0]===0x02)order='lsb';\nelse if(words[0]===0x40)order='msb';\n}\n}catch{\norder='unknown';\n}\nbitOrders.set(ctor,order);\nreturn order;\n}\nfunction bitReader(bits){\nif(!bits)return()=>0;\nconst raw=bits instanceof Uint8Array?bits:bits.words;\nif(raw instanceof Uint8Array){\nconst order=bits instanceof Uint8Array?'lsb':bitOrderOf(bits);\nif(order==='lsb')return(i)=>(raw[i>>>3]>>>(i&7))&1;\nif(order==='msb')return(i)=>(raw[i>>>3]>>>(7-(i&7)))&1;\n}\nif(typeof bits.get==='function')return(i)=>(bits.get(i)?1:0);\nreturn()=>0;\n}\nfunction presenceReader(handle){\nif(!handle||!handle.presence)return null;\nreturn bitReader(handle.presence);\n}\nfunction dictSize(dict){\nif(!dict)return 0;\nif(typeof dict.size==='number')return dict.size;\nif(typeof dict.values==='function')return dict.values().length;\nreturn 0;\n}\nfunction dictValue(dict,code){\nif(!dict)return null;\nif(typeof dict.valueOf==='function')return dict.valueOf(code);\nif(typeof dict.values==='function')return dict.values()[code];\nreturn null;\n}\nfunction multiValue(handle,i){\nconst offsets=handle.offsets;\nconst values=handle.values;\nif(!offsets||!values)return[];\nconst from=offsets[i];\nconst to=offsets[i+1];\nif(!(to>from))return[];\nconst dict=handle.dict;\nconst out=new Array(to-from);\nfor(let k=from;k<to;k++)out[k-from]=dict?dictValue(dict,values[k]):values[k];\nreturn out;\n}\nfunction valueReader(handle){\nif(!handle)return()=>undefined;\nconst values=handle.values;\nconst present=presenceReader(handle);\nconst kind=handle.kind;\nif(kind==='dictionary'){\nconst dict=handle.dict;\nif(present)return(i)=>(present(i)?dictValue(dict,values[i]):null);\nreturn(i)=>dictValue(dict,values[i]);\n}\nif(kind==='bitset'){\nconst bit=bitReader(values);\nif(present)return(i)=>(present(i)?bit(i)===1:null);\nreturn(i)=>bit(i)===1;\n}\nif(kind==='multi'){\nif(present)return(i)=>(present(i)?multiValue(handle,i):null);\nreturn(i)=>multiValue(handle,i);\n}\nif(!values&&typeof handle.get==='function'){\nconst get=handle.get.bind(handle);\nreturn(i)=>{\nconst v=get(i);\nreturn v===undefined?null:v;\n};\n}\nif(present){\nreturn(i)=>{\nif(!present(i))return null;\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nreturn(i)=>{\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nfunction numericTotalOrder(a,b){\nif(a<b)return-1;\nif(a>b)return 1;\nif(a===b){\nconst na=Object.is(a,-0);\nconst nb=Object.is(b,-0);\nif(na===nb)return 0;\nreturn na?-1:1;\n}\nconst an=Number.isNaN(a);\nconst bn=Number.isNaN(b);\nif(an&&bn)return 0;\nreturn an?1:-1;\n}\nfunction valueComparator(locale){\nconst coll=collator(locale);\nreturn(a,b)=>{\nif(a===b)return 0;\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return coll.compare(a,b);\nif(ta==='number'&&tb==='number')return numericTotalOrder(a,b);\nif(ta==='boolean'&&tb==='boolean')return a===b?0:a?1:-1;\nif(a instanceof Date||b instanceof Date){\nconst na=a instanceof Date?a.getTime():Number(a);\nconst nb=b instanceof Date?b.getTime():Number(b);\nreturn numericTotalOrder(na,nb);\n}\nreturn defaultCompare(a,b);\n};\n}\nfunction dictRanks(dict,locale){\nif(dict&&typeof dict.ranks==='function')return dict.ranks(locale);\nconst table=dict&&typeof dict.values==='function'?dict.values():[];\nconst n=table.length;\nconst cmp=valueComparator(locale);\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\norder.sort((a,b)=>cmp(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<n;r++)ranks[order[r]]=r;\nreturn ranks;\n}\nfunction isMissing(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\n});\n__def(\"packages/core/src/compute/sort.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return radixSortFloat64;}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return radixSortInt32;}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return rankSortDictionary;}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return mergeSortComparator;}});\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return sortColumn;}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return sortMulti;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m0[\"bitReader\"];\nconst dictRanks=__m0[\"dictRanks\"];\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst isMissing=__m0[\"isMissing\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueComparator=__m0[\"valueComparator\"];\nconst valueReader=__m0[\"valueReader\"];\nconst EMPTY_INDICES=new Uint32Array(0);\nconst SCRATCH=new ArrayBuffer(8);\nconst SCRATCH_F64=new Float64Array(SCRATCH);\nconst SCRATCH_U32=new Uint32Array(SCRATCH);\nconst HI=(()=>{\nSCRATCH_F64[0]=-1;\nreturn(SCRATCH_U32[1]&0x80000000)!==0?1:0;\n})();\nconst LO=HI===1?0:1;\nfunction transformDouble(value,out){\nSCRATCH_F64[0]=value;\nlet hi=SCRATCH_U32[HI];\nlet lo=SCRATCH_U32[LO];\nif((hi&0x80000000)!==0){\nhi=~hi>>>0;\nlo=~lo>>>0;\n}else{\nhi=(hi^0x80000000)>>>0;\n}\nout[0]=lo;\nout[1]=hi;\n}\nfunction radixLsd64(idx,lo,hi,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*8);\nfor(let i=0;i<n;i++){\nconst l=lo[i];\nconst h=hi[i];\nhist[l&0xff]++;\nhist[256+((l>>>8)&0xff)]++;\nhist[512+((l>>>16)&0xff)]++;\nhist[768+((l>>>24)&0xff)]++;\nhist[1024+(h&0xff)]++;\nhist[1280+((h>>>8)&0xff)]++;\nhist[1536+((h>>>16)&0xff)]++;\nhist[1792+((h>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcLo=lo;\nlet srcHi=hi;\nlet dstIdx=new Uint32Array(n);\nlet dstLo=new Uint32Array(n);\nlet dstHi=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<8;pass++){\nconst base=pass<<8;\nconst shift=(pass&3)<<3;\nconst useHi=pass>=4;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst l=srcLo[i];\nconst h=srcHi[i];\nconst digit=((useHi?h:l)>>>shift)&0xff;\nconst p=offset[digit]++;\ndstIdx[p]=srcIdx[i];\ndstLo[p]=l;\ndstHi[p]=h;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcLo;srcLo=dstLo;dstLo=t;\nt=srcHi;srcHi=dstHi;dstHi=t;\n}\nreturn srcIdx;\n}\nfunction radixLsd32(idx,keys,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*4);\nfor(let i=0;i<n;i++){\nconst k=keys[i];\nhist[k&0xff]++;\nhist[256+((k>>>8)&0xff)]++;\nhist[512+((k>>>16)&0xff)]++;\nhist[768+((k>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcKeys=keys;\nlet dstIdx=new Uint32Array(n);\nlet dstKeys=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<4;pass++){\nconst base=pass<<8;\nconst shift=pass<<3;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst k=srcKeys[i];\nconst p=offset[(k>>>shift)&0xff]++;\ndstIdx[p]=srcIdx[i];\ndstKeys[p]=k;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcKeys;srcKeys=dstKeys;dstKeys=t;\n}\nreturn srcIdx;\n}\nfunction countingSort(idx,keys,n,radix){\nconst counts=new Uint32Array(radix+1);\nfor(let i=0;i<n;i++)counts[keys[i]]++;\nlet sum=0;\nfor(let k=0;k<=radix;k++){\nconst c=counts[k];\ncounts[k]=sum;\nsum+=c;\n}\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];\nreturn out;\n}\nfunction sortUint32Keys(idx,keys,n,radix){\nif(n<2)return idx;\nif(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);\nreturn radixLsd32(idx,keys,n);\n}\nfunction exact(buffer,n){\nif(buffer.length===n&&buffer.byteOffset===0)return buffer;\nreturn Uint32Array.prototype.slice.call(buffer,0,n);\n}\nfunction radixSortFloat64(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=new Uint32Array(n);\nconst lo=new Uint32Array(n);\nconst hi=new Uint32Array(n);\nconst nans=new Uint32Array(n);\nconst pair=new Uint32Array(2);\nlet m=0;\nlet nanCount=0;\nfor(let i=0;i<n;i++){\nconst row=src[i];\nconst v=values[row];\nif(Number.isNaN(v)){nans[nanCount++]=row;continue;}\ntransformDouble(v,pair);\nif(descending){\nlo[m]=~pair[0]>>>0;\nhi[m]=~pair[1]>>>0;\n}else{\nlo[m]=pair[0];\nhi[m]=pair[1];\n}\nidx[m++]=row;\n}\nconst sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);\nif(nanCount===0)return exact(sorted,m);\nconst out=new Uint32Array(n);\nout.set(sorted.subarray(0,m),0);\nout.set(nans.subarray(0,nanCount),m);\nreturn out;\n}\nfunction radixSortInt32(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst k=(values[idx[i]]^0x80000000)>>>0;\nkeys[i]=descending?(~k>>>0):k;\n}\nreturn exact(radixLsd32(idx,keys,n),n);\n}\nfunction rankSortDictionary(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst ranks=dictRanks(handle.dict,opts.locale);\nconst codes=handle.values;\nconst present=presenceReader(handle);\nconst size=Math.max(dictSize(handle.dict),ranks.length);\nconst absentRank=size;\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nconst descending=!!opts.descending;\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nlet rank=present&&present(row)===0?absentRank:ranks[codes[row]];\nif(rank===undefined)rank=absentRank;\nkeys[i]=descending?absentRank-rank:rank;\n}\nreturn exact(sortUint32Keys(idx,keys,n,size+1),n);\n}\nfunction mergeSortComparator(values,order,compare){\nconst n=order.length;\nlet src=Uint32Array.from(order);\nif(n<2)return src;\nlet dst=new Uint32Array(n);\nfor(let width=1;width<n;width<<=1){\nfor(let start=0;start<n;start+=width<<1){\nconst mid=Math.min(start+width,n);\nconst end=Math.min(start+(width<<1),n);\nlet i=start;\nlet j=mid;\nlet k=start;\nwhile(i<mid&&j<end){\ndst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];\n}\nwhile(i<mid)dst[k++]=src[i++];\nwhile(j<end)dst[k++]=src[j++];\n}\nconst t=src;src=dst;dst=t;\n}\nreturn src;\n}\nfunction sortBitsetColumn(handle,idx,descending){\nconst bit=bitReader(handle.values);\nconst n=idx.length;\nconst out=new Uint32Array(n);\nconst first=descending?1:0;\nlet k=0;\nfor(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];\nfor(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];\nreturn out;\n}\nfunction indexableValues(handle,idx){\nconst values=handle.values;\nconst kind=handle.kind;\nconst direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));\nif(direct&&!handle.presence)return values;\nconst reader=valueReader(handle);\nconst materialised=new Array(rowCount(handle)||0);\nfor(let i=0;i<idx.length;i++){\nconst row=idx[i];\nmaterialised[row]=reader(row);\n}\nreturn materialised;\n}\nfunction allStrings(values,idx){\nfor(let i=0;i<idx.length;i++){\nif(typeof values[idx[i]]!=='string')return false;\n}\nreturn true;\n}\nfunction keyedSortStrings(values,idx,opts){\nconst n=idx.length;\nconst codeOf=new Map();\nconst table=[];\nconst codes=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst v=values[idx[i]];\nlet c=codeOf.get(v);\nif(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}\ncodes[i]=c;\n}\nconst d=table.length;\nconst compare=valueComparator(opts.locale);\nconst order=new Array(d);\nfor(let i=0;i<d;i++)order[i]=i;\norder.sort((a,b)=>compare(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(d);\nfor(let r=0;r<d;r++)ranks[order[r]]=r;\nconst descending=!!opts.descending;\nconst idxOut=Uint32Array.from(idx);\nconst keys=new Uint32Array(n);\nconst top=d-1;\nfor(let i=0;i<n;i++){\nconst rank=ranks[codes[i]];\nkeys[i]=descending?top-rank:rank;\n}\nreturn exact(sortUint32Keys(idxOut,keys,n,d),n);\n}\nfunction sortByComparator(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nif(idx.length>=2&&allStrings(values,idx))return keyedSortStrings(values,idx,opts);\nconst base=valueComparator(opts.locale);\nconst compare=opts.descending?(a,b)=>base(b,a):base;\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction sortByCompare(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nconst user=opts.compare;\nconst descending=!!opts.descending;\nconst compare=descending\n?(a,b)=>-user(a,b,undefined,undefined,true)\n:(a,b)=>user(a,b,undefined,undefined,false);\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction partitionPresent(handle,idx){\nconst n=idx.length;\nconst present=presenceReader(handle);\nconst values=handle.values;\nconst checkNaN=handle.kind==='float64'&&!!values;\nconst looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;\nif(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};\nconst keep=new Uint32Array(n);\nconst drop=new Uint32Array(n);\nlet p=0;\nlet a=0;\nif(present&&checkNaN){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(checkNaN&&!present){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(present&&!looseKind){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1)keep[p++]=row;else drop[a++]=row;\n}\n}else{\nconst reader=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;\n}\n}\nif(a===0)return{present:idx,absent:EMPTY_INDICES};\nreturn{present:keep.subarray(0,p),absent:drop.subarray(0,a)};\n}\nfunction joinRuns(sorted,absent,nullsFirst){\nif(absent.length===0)return sorted;\nconst out=new Uint32Array(sorted.length+absent.length);\nif(nullsFirst){\nout.set(absent,0);\nout.set(sorted,absent.length);\n}else{\nout.set(sorted,0);\nout.set(absent,sorted.length);\n}\nreturn out;\n}\nfunction sortColumn(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nif(!handle||src.length<2)return Uint32Array.from(src);\nconst{present,absent}=partitionPresent(handle,src);\nif(present.length===0)return Uint32Array.from(src);\nconst descending=!!opts.descending;\nlet sorted;\nif(typeof opts.compare==='function'){\nsorted=sortByCompare(handle,present,opts);\n}else{\nswitch(handle.kind){\ncase'float64':\nsorted=radixSortFloat64(handle.values,present,descending);\nbreak;\ncase'int32':\nsorted=radixSortInt32(handle.values,present,descending);\nbreak;\ncase'dictionary':\nsorted=rankSortDictionary(handle,present,opts);\nbreak;\ncase'bitset':\nsorted=sortBitsetColumn(handle,present,descending);\nbreak;\ndefault:\nsorted=sortByComparator(handle,present,opts);\nbreak;\n}\n}\nreturn joinRuns(sorted,absent,!!opts.nullsFirst);\n}\nfunction sortMulti(handles,entries,order,opts={}){\nconst list=entries||[];\nconst first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);\nlet current=order||identity(rowCount(first,opts));\nfor(let i=list.length-1;i>=0;i--){\nconst entry=list[i];\nconst handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);\nif(!handle)continue;\ncurrent=sortColumn(handle,current,{\ndescending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',\nnullsFirst:!!entry.nullsFirst,\nlocale:entry.locale!==undefined?entry.locale:opts.locale,\ncompare:entry.compare,\n});\n}\nreturn current instanceof Uint32Array?current:Uint32Array.from(current);\n}\nfunction byId(handles,id){\nif(!handles||id===undefined)return undefined;\nfor(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];\nreturn undefined;\n}\n});\n__def(\"packages/core/src/format/date.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"scanPattern\",{enumerable:true,get:function(){return scanPattern;}});\nObject.defineProperty(__exports,\"toDate\",{enumerable:true,get:function(){return toDate;}});\nObject.defineProperty(__exports,\"compilePattern\",{enumerable:true,get:function(){return compilePattern;}});\nObject.defineProperty(__exports,\"compileDate\",{enumerable:true,get:function(){return compileDate;}});\nObject.defineProperty(__exports,\"toIsoDate\",{enumerable:true,get:function(){return toIsoDate;}});\nObject.defineProperty(__exports,\"toIsoDateTime\",{enumerable:true,get:function(){return toIsoDateTime;}});\nObject.defineProperty(__exports,\"compareIso\",{enumerable:true,get:function(){return compareIso;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isNil=__m0[\"isNil\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst TOKENS=[\n'yyyy','yy','MMMM','MMM','MM','M','dd','d',\n'EEEE','EEE','HH','H','hh','h','mm','m','ss','s','SSS','a',\n];\nfunction scanPattern(pattern){\nconst out=[];\nlet i=0;\nlet literal='';\nconst flush=()=>{if(literal){out.push({token:null,text:literal});literal='';}};\nwhile(i<pattern.length){\nconst ch=pattern[i];\nif(ch===\"'\"){\nif(pattern[i+1]===\"'\"){literal+=\"'\";i+=2;continue;}\nconst end=pattern.indexOf(\"'\",i+1);\nif(end===-1){literal+=pattern.slice(i+1);i=pattern.length;continue;}\nliteral+=pattern.slice(i+1,end);\ni=end+1;\ncontinue;\n}\nconst token=TOKENS.find((t)=>pattern.startsWith(t,i));\nif(token){flush();out.push({token,text:token});i+=token.length;continue;}\nif(/[A-Za-z]/.test(ch)){\nwarnOnce(\n`date.pattern.token:${ch}`,\n`the date pattern \"${pattern}\" contains '${ch}', which is not a supported token, `\n+'so it is rendered as text. Quote it as a literal to silence this. '\n+`Supported: ${TOKENS.join(' ')}.`,\n);\n}\nliteral+=ch;\ni+=1;\n}\nflush();\nreturn out;\n}\nconst WALL_CLOCK=/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?)?$/;\nfunction toDate(value){\nif(isNil(value)||value==='')return null;\nif(value instanceof Date)return Number.isNaN(value.getTime())?null:value;\nif(typeof value==='number')return Number.isNaN(value)?null:new Date(value);\nif(typeof value==='string'){\nconst wall=WALL_CLOCK.exec(value.trim());\nif(wall){\nconst[,y,mo,d,h='0',mi='0',sec='0']=wall;\nreturn new Date(+y,+mo-1,+d,+h,+mi,+sec);\n}\nconst d=new Date(value);\nreturn Number.isNaN(d.getTime())?null:d;\n}\nreturn null;\n}\nfunction pad(n,w){return String(n).padStart(w,'0');}\nfunction fieldReader(timeZone){\nif(!timeZone){\nreturn(d)=>({\nyear:d.getFullYear(),month:d.getMonth()+1,day:d.getDate(),\nhour:d.getHours(),minute:d.getMinutes(),second:d.getSeconds(),\nms:d.getMilliseconds(),weekday:d.getDay(),\n});\n}\nconst zoned=new Intl.DateTimeFormat('en-US',{\ntimeZone,year:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false,weekday:'short',\n});\nconst days={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};\nreturn(d)=>{\nconst f={year:0,month:1,day:1,hour:0,minute:0,second:0,ms:d.getMilliseconds(),weekday:0};\nfor(const part of zoned.formatToParts(d)){\nswitch(part.type){\ncase'year':f.year=Number(part.value);break;\ncase'month':f.month=Number(part.value);break;\ncase'day':f.day=Number(part.value);break;\ncase'hour':f.hour=Number(part.value)%24;break;\ncase'minute':f.minute=Number(part.value);break;\ncase'second':f.second=Number(part.value);break;\ncase'weekday':f.weekday=days[part.value]??0;break;\ndefault:break;\n}\n}\nreturn f;\n};\n}\nfunction compilePattern(pattern,locale,timeZone){\nconst segments=scanPattern(pattern);\nconst read=fieldReader(timeZone);\nconst used=new Set(segments.filter((s)=>s.token).map((s)=>s.token));\nconst monthShort=used.has('MMM')?new Intl.DateTimeFormat(locale,{month:'short',timeZone}):null;\nconst monthLong=used.has('MMMM')?new Intl.DateTimeFormat(locale,{month:'long',timeZone}):null;\nconst dayShort=used.has('EEE')?new Intl.DateTimeFormat(locale,{weekday:'short',timeZone}):null;\nconst dayLong=used.has('EEEE')?new Intl.DateTimeFormat(locale,{weekday:'long',timeZone}):null;\nreturn(d)=>{\nconst f=read(d);\nlet out='';\nfor(const seg of segments){\nif(!seg.token){out+=seg.text;continue;}\nswitch(seg.token){\ncase'yyyy':out+=pad(f.year,4);break;\ncase'yy':out+=pad(f.year%100,2);break;\ncase'MMMM':out+=monthLong.format(d);break;\ncase'MMM':out+=monthShort.format(d);break;\ncase'MM':out+=pad(f.month,2);break;\ncase'M':out+=String(f.month);break;\ncase'dd':out+=pad(f.day,2);break;\ncase'd':out+=String(f.day);break;\ncase'EEEE':out+=dayLong.format(d);break;\ncase'EEE':out+=dayShort.format(d);break;\ncase'HH':out+=pad(f.hour,2);break;\ncase'H':out+=String(f.hour);break;\ncase'hh':out+=pad(f.hour%12===0?12:f.hour%12,2);break;\ncase'h':out+=String(f.hour%12===0?12:f.hour%12);break;\ncase'mm':out+=pad(f.minute,2);break;\ncase'm':out+=String(f.minute);break;\ncase'ss':out+=pad(f.second,2);break;\ncase's':out+=String(f.second);break;\ncase'SSS':out+=pad(f.ms,3);break;\ncase'a':out+=f.hour<12?'AM':'PM';break;\ndefault:out+=seg.text;break;\n}\n}\nreturn out;\n};\n}\nconst UNITS=[\n['year',365*24*3600e3],\n['month',30*24*3600e3],\n['week',7*24*3600e3],\n['day',24*3600e3],\n['hour',3600e3],\n['minute',60e3],\n['second',1e3],\n];\nfunction compileDate(spec,locale){\nconst s=spec||{};\nconst loc=s.locale||locale||undefined;\nconst nullDisplay=s.nullDisplay??'';\nconst timeZone=s.timeZone;\nlet absolute;\nif(s.pattern){\nabsolute=compilePattern(s.pattern,loc,timeZone);\n}else if(s.dateStyle||s.timeStyle){\nconst opts={timeZone};\nif(s.dateStyle)opts.dateStyle=s.dateStyle;\nif(s.timeStyle)opts.timeStyle=s.timeStyle;\nconst dtf=new Intl.DateTimeFormat(loc,opts);\nabsolute=(d)=>dtf.format(d);\n}else{\nconst dtf=new Intl.DateTimeFormat(loc,{dateStyle:'medium',timeZone});\nabsolute=(d)=>dtf.format(d);\n}\nconst relative=s.relative?new Intl.RelativeTimeFormat(loc,{numeric:'auto'}):null;\nconst thresholdDays=typeof s.relative==='object'&&s.relative\n?(s.relative.threshold??7)\n:7;\nconst thresholdMs=thresholdDays*24*3600e3;\nconst format=(value,params)=>{\nconst d=toDate(value);\nif(!d)return nullDisplay;\nif(relative){\nconst now=params&&typeof params.now==='number'?params.now:Date.now();\nconst delta=d.getTime()-now;\nif(Math.abs(delta)<thresholdMs){\nfor(const[unit,ms]of UNITS){\nif(Math.abs(delta)>=ms||unit==='second'){\nreturn relative.format(Math.round(delta/ms),unit);\n}\n}\n}\n}\nreturn absolute(d);\n};\nformat.spec=s;\nreturn format;\n}\nfunction toIsoDate(value){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst match=/^(\\d{4}-\\d{2}-\\d{2})/.exec(value.trim());\nif(match)return match[1];\nconst parsed=toDate(value);\nreturn parsed?toIsoDate(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nconst pad=(n)=>String(n).padStart(2,'0');\nreturn`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\n}\nfunction toIsoDateTime(value,timeZone){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst text=value.trim();\nif(ZONE_SUFFIX.test(text)){\nconst instant=toDate(text);\nreturn instant?wallClockIn(instant,timeZone):null;\n}\nconst match=/^(\\d{4}-\\d{2}-\\d{2})[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?/.exec(text);\nif(match){\nconst[,day,hour,minute,second]=match;\nreturn`${day}T${hour}:${minute}${second&&second!=='00'?`:${second}`:''}`;\n}\nif(/^\\d{4}-\\d{2}-\\d{2}$/.test(text))return`${text}T00:00`;\nconst parsed=toDate(text);\nreturn parsed?toIsoDateTime(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nreturn wallClockIn(date,timeZone);\n}\nconst ZONE_SUFFIX=/(?:Z|[+-]\\d{2}:?\\d{2})$/i;\nfunction wallClockIn(date,timeZone){\nconst pad=(n)=>String(n).padStart(2,'0');\nif(timeZone){\ntry{\nconst parts=new Intl.DateTimeFormat('en-CA',{\ntimeZone,\nyear:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',\nhour12:false,\n}).formatToParts(date).reduce((out,part)=>{\nif(part.type!=='literal')out[part.type]=part.value;\nreturn out;\n},{});\nconst hour=parts.hour==='24'?'00':parts.hour;\nconst seconds=Number(parts.second);\nreturn`${parts.year}-${parts.month}-${parts.day}T${hour}:${parts.minute}`\n+(seconds?`:${parts.second}`:'');\n}catch{\n}\n}\nconst day=`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\nconst seconds=date.getSeconds();\nconst clock=`${pad(date.getHours())}:${pad(date.getMinutes())}${seconds?`:${pad(seconds)}`:''}`;\nreturn`${day}T${clock}`;\n}\nfunction compareIso(a,b){\nconst left=isNil(a)||a===''?null:String(a);\nconst right=isNil(b)||b===''?null:String(b);\nif(left===null)return right===null?0:1;\nif(right===null)return-1;\nreturn left<right?-1:left>right?1:0;\n}\n});\n__def(\"packages/core/src/compute/filter.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return releaseMask;}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return compilePredicate;}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return testValue;}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return evaluateCondition;}});\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return evaluateFilters;}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return pruneColumn;}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return mentionsColumn;}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return compact;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isBlank=__m0[\"isBlank\"];\nconst toArray=__m0[\"toArray\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/format/date.js\");\nconst toIsoDate=__m1[\"toIsoDate\"];\nconst __m2=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m2[\"bitReader\"];\nconst dictSize=__m2[\"dictSize\"];\nconst dictValue=__m2[\"dictValue\"];\nconst presenceReader=__m2[\"presenceReader\"];\nconst valueComparator=__m2[\"valueComparator\"];\nconst valueReader=__m2[\"valueReader\"];\nconst ISO_DAY=/^\\d{4}-\\d{2}-\\d{2}$/;\nconst NULL_KEY='\\u0000null\\u0000';\nfunction acquireMask(ctx,n){\nconst pool=ctx&&ctx.pool;\nif(pool){\nconst take=pool.mask||pool.acquireMask||pool.acquire||pool.take;\nif(typeof take==='function'){\nconst mask=take.call(pool,n);\nif(mask&&mask.length>=n)return mask;\n}\n}\nreturn new Uint8Array(n);\n}\nfunction releaseMask(ctx,mask){\nconst pool=ctx&&ctx.pool;\nif(!pool||!mask)return;\nconst give=pool.release||pool.releaseMask||pool.free||pool.recycle;\nif(typeof give==='function')give.call(pool,mask);\n}\nfunction fillMask(mask,n,value){\nmask.fill(value,0,n);\nreturn mask;\n}\nfunction unorderable(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\nfunction coerceTarget(value,type){\nif(value===null||value===undefined)return value;\nif(type==='number')return typeof value==='number'?value:Number(value);\nif(type==='date'||type==='dateString'){\nconst iso=toIsoDate(value);\nreturn iso===null?toMillis(value):iso;\n}\nif(type==='boolean'){\nif(typeof value==='boolean')return value;\nif(value==='true'||value===1)return true;\nif(value==='false'||value===0)return false;\nreturn!!value;\n}\nreturn value;\n}\nfunction toMillis(value){\nif(value instanceof Date)return value.getTime();\nif(typeof value==='number')return value;\nreturn Date.parse(String(value));\n}\nfunction toNumber(value){\nif(typeof value==='number')return value;\nif(value instanceof Date)return value.getTime();\nif(value===null||value===undefined||value==='')return NaN;\nreturn Number(value);\n}\nfunction textOf(v,caseSensitive){\nconst s=typeof v==='string'?v:String(v);\nreturn caseSensitive?s:s.toLowerCase();\n}\nfunction setKey(v,caseSensitive){\nif(v===null||v===undefined)return NULL_KEY;\nif(typeof v==='string')return caseSensitive?v:v.toLowerCase();\nif(v instanceof Date)return v.getTime();\nreturn v;\n}\nfunction buildSet(value,caseSensitive,type){\nconst set=new Set();\nfor(const raw of toArray(value)){\nconst entry=coerceTarget(raw,type);\nset.add(setKey(entry,caseSensitive));\nif(typeof entry==='string'&&entry!==''&&Number.isFinite(Number(entry)))set.add(Number(entry));\nelse if(typeof entry==='number'&&Number.isFinite(entry))set.add(setKey(String(entry),caseSensitive));\n}\nreturn set;\n}\nfunction valueEquals(a,b,caseSensitive){\nif(a===null||a===undefined||b===null||b===undefined){\nreturn(a===null||a===undefined)&&(b===null||b===undefined);\n}\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return caseSensitive?a===b:a.toLowerCase()===b.toLowerCase();\nif(a instanceof Date||b instanceof Date)return toMillis(a)===toMillis(b);\nif(ta==='number'&&tb==='number')return a===b||(Number.isNaN(a)&&Number.isNaN(b));\nif(ta==='number'&&tb==='string')return a===Number(b);\nif(ta==='string'&&tb==='number')return Number(a)===b;\nif(ta==='boolean'||tb==='boolean')return a===b;\nif(Array.isArray(a)&&Array.isArray(b)){\nreturn a.length===b.length&&a.every((x,i)=>valueEquals(x,b[i],caseSensitive));\n}\nreturn a===b;\n}\nfunction compileRegExp(value,caseSensitive){\ntry{\nif(value instanceof RegExp){\nconst flags=value.flags.replace(/[gy]/g,'');\nreturn new RegExp(value.source,caseSensitive?flags:flags.includes('i')?flags:`${flags}i`);\n}\nreturn new RegExp(String(value),caseSensitive?'':'i');\n}catch(err){\nwarnOnce(`regex:${String(value)}`,`filter operator \"matches\" received an invalid pattern: ${String(value)}`,err);\nreturn null;\n}\n}\nfunction compilePredicate(condition,locale){\nconst predicate=compileValuePredicate(condition,locale);\nconst type=condition&&condition.type;\nif(type!=='date'&&type!=='dateString')return predicate;\nreturn(v)=>predicate(typeof v==='string'&&ISO_DAY.test(v)?v:(toIsoDate(v)??v));\n}\nfunction compileValuePredicate(condition,locale){\nconst op=condition&&condition.op;\nconst caseSensitive=!!(condition&&condition.caseSensitive);\nconst type=condition&&condition.type;\nconst cmp=valueComparator(locale);\nconst not=(p)=>(v)=>!p(v);\nswitch(op){\ncase'eq':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>valueEquals(v,target,caseSensitive);\n}\ncase'ne':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>!valueEquals(v,target,caseSensitive);\n}\ncase'lt':case'lte':case'gt':case'gte':{\nconst target=coerceTarget(condition.value,type);\nif(unorderable(target))return()=>false;\nconst want=op==='lt'?-1:op==='lte'?0:op==='gt'?1:2;\nreturn(v)=>{\nif(unorderable(v))return false;\nconst c=cmp(v,target);\nreturn want===-1?c<0:want===0?c<=0:want===1?c>0:c>=0;\n};\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=coerceTarget(pair[0],type);\nconst hi=coerceTarget(pair[1],type);\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nif(unorderable(lo)||unorderable(hi))return op==='between'?()=>false:()=>true;\nconst inRange=(v)=>{\nif(unorderable(v))return false;\nconst a=cmp(v,lo);\nconst b=cmp(v,hi);\nreturn(loInclusive?a>=0:a>0)&&(hiInclusive?b<=0:b<0);\n};\nreturn op==='between'?inRange:not(inRange);\n}\ncase'in':case'notIn':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst member=(v)=>set.has(setKey(v,caseSensitive));\nreturn op==='in'?member:not(member);\n}\ncase'contains':case'notContains':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nconst has=(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).includes(needle));\nreturn op==='contains'?has:not(has);\n}\ncase'startsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).startsWith(needle));\n}\ncase'endsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).endsWith(needle));\n}\ncase'matches':{\nconst re=compileRegExp(condition.value,caseSensitive);\nif(!re)return()=>false;\nreturn(v)=>(v===null||v===undefined?false:re.test(String(v)));\n}\ncase'blank':\nreturn(v)=>isBlank(v)||(Array.isArray(v)&&v.length===0);\ncase'notBlank':\nreturn(v)=>!(isBlank(v)||(Array.isArray(v)&&v.length===0));\ncase'containsAny':case'containsNone':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst any=(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nfor(let i=0;i<list.length;i++)if(set.has(setKey(list[i],caseSensitive)))return true;\nreturn false;\n};\nreturn op==='containsAny'?any:not(any);\n}\ncase'containsAll':{\nconst wanted=toArray(condition.value).map((x)=>setKey(coerceTarget(x,type),caseSensitive));\nreturn(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nif(wanted.length===0)return true;\nconst have=new Set(list.map((x)=>setKey(x,caseSensitive)));\nfor(let i=0;i<wanted.length;i++)if(!have.has(wanted[i]))return false;\nreturn true;\n};\n}\ndefault:\nwarnOnce(`op:${String(op)}`,`unknown filter operator \"${String(op)}\"; the condition passes every row`);\nreturn()=>true;\n}\n}\nfunction testValue(value,condition,locale){\nreturn compilePredicate(condition,locale)(value);\n}\nfunction presenceCondition(handle,wantPresent,mask,count){\nconst present=presenceReader(handle);\nif(present){\nconst target=wantPresent?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===target?1:0;\nreturn mask;\n}\nconst kind=handle.kind;\nif(kind==='float64'||kind==='int32'||kind==='bitset'){\nreturn fillMask(mask,count,wantPresent?1:0);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++){\nconst v=read(i);\nconst blank=isBlank(v)||(Array.isArray(v)&&v.length===0);\nmask[i]=blank===wantPresent?0:1;\n}\nreturn mask;\n}\nfunction dictionaryCondition(handle,pred,mask,count){\nconst dict=handle.dict;\nconst size=dictSize(dict);\nconst allowed=new Uint8Array(size);\nfor(let code=0;code<size;code++)allowed[code]=pred(dictValue(dict,code))?1:0;\nconst codes=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=allowed[codes[i]];\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===1?allowed[codes[i]]:absentAnswer;\nreturn mask;\n}\nfunction booleanCondition(handle,pred,mask,count){\nconst bit=bitReader(handle.values);\nconst whenTrue=pred(true)?1:0;\nconst whenFalse=pred(false)?1:0;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=bit(i)===1?whenTrue:whenFalse;\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++){\nmask[i]=present(i)===0?absentAnswer:(bit(i)===1?whenTrue:whenFalse);\n}\nreturn mask;\n}\nfunction numericCondition(handle,condition,pred,mask,count){\nconst values=handle.values;\nconst type=condition.type;\nconst op=condition.op;\nlet handled=true;\nswitch(op){\ncase'eq':case'ne':{\nconst target=toNumber(coerceTarget(condition.value,type));\nconst wantNaN=typeof condition.value==='number'&&Number.isNaN(condition.value);\nconst invert=op==='ne'?1:0;\nif(wantNaN){\nfor(let i=0;i<count;i++)mask[i]=(Number.isNaN(values[i])?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=((values[i]===target)?1:0)^invert;\n}\nbreak;\n}\ncase'lt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<t?1:0;\nbreak;\n}\ncase'lte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<=t?1:0;\nbreak;\n}\ncase'gt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>t?1:0;\nbreak;\n}\ncase'gte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>=t?1:0;\nbreak;\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=toNumber(coerceTarget(pair[0],type));\nconst hi=toNumber(coerceTarget(pair[1],type));\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nconst invert=op==='notBetween'?1:0;\nif(loInclusive&&hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<=hi))?1:0)^invert;\n}else if(loInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<hi))?1:0)^invert;\n}else if(hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<=hi))?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<hi))?1:0)^invert;\n}\nbreak;\n}\ncase'in':case'notIn':{\nconst set=new Set();\nfor(const raw of toArray(condition.value)){\nconst n=toNumber(coerceTarget(raw,type));\nif(!Number.isNaN(n))set.add(n);\n}\nconst invert=op==='notIn'?1:0;\nfor(let i=0;i<count;i++)mask[i]=(set.has(values[i])?1:0)^invert;\nbreak;\n}\ndefault:\nhandled=false;\nbreak;\n}\nif(!handled)return false;\nconst present=presenceReader(handle);\nif(present){\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)if(present(i)===0)mask[i]=absentAnswer;\n}\nreturn true;\n}\nfunction genericCondition(handle,pred,mask,count){\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++)mask[i]=pred(read(i))?1:0;\nreturn mask;\n}\nfunction evaluateCondition(condition,ctx,out){\nconst count=ctx.count|0;\nconst mask=out||acquireMask(ctx,count);\nif(!condition)return fillMask(mask,count,1);\nconst handle=typeof ctx.handle==='function'?ctx.handle(condition.col):undefined;\nconst custom=typeof ctx.custom==='function'?ctx.custom:null;\nif(!handle){\nif(custom){\nfor(let i=0;i<count;i++)mask[i]=custom(condition,i)?1:0;\nreturn mask;\n}\nwarnOnce(`filter:col:${String(condition.col)}`,\n`filter references unknown column \"${String(condition.col)}\"; the condition passes every row`);\nreturn fillMask(mask,count,1);\n}\nconst op=condition.op;\nif(op==='blank'||op==='notBlank')return presenceCondition(handle,op==='notBlank',mask,count);\nconst pred=compilePredicate(condition,ctx.locale);\nswitch(handle.kind){\ncase'dictionary':\nreturn dictionaryCondition(handle,pred,mask,count);\ncase'bitset':\nreturn booleanCondition(handle,pred,mask,count);\ncase'float64':case'int32':\nif(numericCondition(handle,condition,pred,mask,count))return mask;\nreturn genericCondition(handle,pred,mask,count);\ndefault:\nreturn genericCondition(handle,pred,mask,count);\n}\n}\nfunction evaluateNode(node,ctx,count){\nif(!node)return fillMask(acquireMask(ctx,count),count,1);\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(children.length===0)return fillMask(acquireMask(ctx,count),count,1);\nconst acc=evaluateNode(children[0],ctx,count);\nfor(let k=1;k<children.length;k++){\nconst rhs=evaluateNode(children[k],ctx,count);\nif(op==='or')for(let i=0;i<count;i++)acc[i]|=rhs[i];\nelse for(let i=0;i<count;i++)acc[i]&=rhs[i];\nreleaseMask(ctx,rhs);\n}\nif(op==='not')for(let i=0;i<count;i++)acc[i]^=1;\nreturn acc;\n}\nreturn evaluateCondition(node,ctx,acquireMask(ctx,count));\n}\nfunction evaluateFilters(filters,ctx){\nreturn evaluateNode(filters,ctx,ctx.count|0);\n}\nfunction pruneColumn(filters,colId){\nif(!filters||!colId)return filters||null;\nconst node=(filters);\nif(Array.isArray(node.conditions)){\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(op!=='and'){\nreturn mentionsColumn(node,colId)?null:filters;\n}\nconst kept=[];\nfor(const child of node.conditions){\nconst pruned=pruneColumn(child,colId);\nif(pruned)kept.push(pruned);\n}\nif(!kept.length)return null;\nreturn{...node,op:'and',conditions:kept};\n}\nreturn node.col===colId?null:filters;\n}\nfunction mentionsColumn(filters,colId){\nif(!filters||typeof filters!=='object')return false;\nconst node=(filters);\nif(node.col===colId)return true;\nif(Array.isArray(node.conditions)){\nfor(const child of node.conditions)if(mentionsColumn(child,colId))return true;\n}\nreturn false;\n}\nfunction compact(mask,count,out){\nif(out&&out.length>=count){\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])out[k++]=i;\nreturn out.subarray(0,k);\n}\nlet survivors=0;\nfor(let i=0;i<count;i++)survivors+=mask[i]?1:0;\nconst result=new Uint32Array(survivors);\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])result[k++]=i;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/group.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return packKeys;}});\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return groupByColumns;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueReader=__m0[\"valueReader\"];\nconst KEY_SEPARATOR='\\u001F';\nconst NULL_MARKER='\\u0000';\nconst MAX_DIRECT_COUNTS=1<<20;\nfunction packKeys(handles,idx,n){\nconst k=handles.length;\nconst readers=handles.map((h)=>valueReader(h));\nconst allDictionary=k>0&&handles.every((h)=>h&&h.kind==='dictionary'&&h.dict);\nif(allDictionary){\nconst cards=handles.map((h)=>dictSize(h.dict)+1);\nlet product=1;\nfor(let j=0;j<k;j++)product*=cards[j];\nif(product<=Number.MAX_SAFE_INTEGER){\nconst codes=handles.map((h)=>h.values);\nconst presence=handles.map((h)=>presenceReader(h));\nconst keyOf=(row)=>{\nlet key=0;\nfor(let j=0;j<k;j++){\nconst present=presence[j];\nconst code=present&&present(row)===0?cards[j]-1:codes[j][row];\nkey=key*cards[j]+code;\n}\nreturn key;\n};\nconst packed=new Float64Array(n);\nfor(let i=0;i<n;i++)packed[i]=keyOf(idx[i]);\nreturn{packed,strings:null,product,readers,keyOf};\n}\n}\nconst keyOf=(row)=>{\nlet key='';\nfor(let j=0;j<k;j++){\nconst v=readers[j](row);\nkey+=(j===0?'':KEY_SEPARATOR)+(v===null||v===undefined?NULL_MARKER:String(v));\n}\nreturn key;\n};\nconst strings=new Array(n);\nfor(let i=0;i<n;i++)strings[i]=keyOf(idx[i]);\nreturn{packed:null,strings,product:Infinity,readers,keyOf};\n}\nfunction scatterBuckets(idx,ids,n,groups){\nconst offsets=new Uint32Array(groups+1);\nfor(let i=0;i<n;i++)offsets[ids[i]+1]++;\nfor(let g=0;g<groups;g++)offsets[g+1]+=offsets[g];\nconst scattered=new Uint32Array(n);\nconst cursor=offsets.slice(0,groups);\nfor(let i=0;i<n;i++)scattered[cursor[ids[i]]++]=idx[i];\nconst buckets=new Array(groups);\nfor(let g=0;g<groups;g++)buckets[g]=scattered.subarray(offsets[g],offsets[g+1]);\nreturn buckets;\n}\nfunction groupByColumns(handles,order,opts={}){\nconst list=handles||[];\nconst idx=order||identity(rowCount(list[0],opts));\nconst n=idx.length;\nif(list.length===0||n===0)return{keys:[],buckets:[]};\nconst{packed,strings,product,readers}=packKeys(list,idx,n);\nconst ids=new Uint32Array(n);\nlet groups=0;\nlet packedKeys=null;\nif(packed&&product<=Math.max(1024,Math.min(MAX_DIRECT_COUNTS,n*4))){\nconst size=product;\nconst seen=new Int32Array(size).fill(-1);\nfor(let i=0;i<n;i++)seen[packed[i]]=0;\nfor(let key=0;key<size;key++)if(seen[key]===0)seen[key]=groups++;\nfor(let i=0;i<n;i++)ids[i]=seen[packed[i]];\npackedKeys=new Float64Array(groups);\nfor(let key=0;key<size;key++)if(seen[key]>=0)packedKeys[seen[key]]=key;\n}else if(packed){\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=packed[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\npackedKeys=new Float64Array(groups);\nfor(const[key,id]of seen)packedKeys[id]=key;\n}else{\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=strings[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\n}\nconst buckets=scatterBuckets(idx,ids,n,groups);\nconst keys=new Array(groups);\nfor(let g=0;g<groups;g++){\nconst row=buckets[g][0];\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\nkeys[g]=tuple;\n}\nconst result={keys,buckets};\nif(packedKeys)result.packed=packedKeys;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/facet.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return STRATEGIES;}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return GRANULARITIES;}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return DEFAULT_BUCKETS;}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return DEFAULT_CARDINALITY_LIMIT;}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return QUANTILE_SAMPLE;}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return facetKind;}});\nObject.defineProperty(__exports,\"orderedReader\",{enumerable:true,get:function(){return orderedReader;}});\nObject.defineProperty(__exports,\"toNumeric\",{enumerable:true,get:function(){return toNumeric;}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return cardinalityOf;}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return pickGranularity;}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return floorTo;}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return advance;}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return computeBounds;}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return countInto;}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return bucketOf;}});\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return facet;}});\nObject.defineProperty(__exports,\"default\",{enumerable:true,get:function(){return __default;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst dictSize=__m0[\"dictSize\"];\nconst dictValue=__m0[\"dictValue\"];\nconst STRATEGIES=Object.freeze(['equal','quantile','log']);\nconst GRANULARITIES=Object.freeze(['hour','day','week','month','quarter','year']);\nconst DEFAULT_BUCKETS=20;\nconst DEFAULT_CARDINALITY_LIMIT=50;\nconst QUANTILE_SAMPLE=10_000;\nfunction facetKind(handle,type){\nif(!handle)return'none';\nconst base=type&&type.base;\nif(base==='date'||base==='datetime'||base==='time'||base==='dateString')return'date';\nswitch(handle.kind){\ncase'bitset':return'boolean';\ncase'float64':case'int32':return'numeric';\ncase'dictionary':return'category';\ncase'multi':return'category';\ndefault:\nif(base==='number')return'numeric';\nif(base==='boolean')return'boolean';\nif(base==='text')return'category';\nreturn'none';\n}\n}\nfunction orderedReader(handle){\nconst values=handle.values;\nconst kind=handle.kind;\nif((kind==='float64'||kind==='int32')&&values)return(i)=>values[i];\nconst read=valueReader(handle);\nreturn(i)=>toNumeric(read(i));\n}\nfunction toNumeric(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(v===null||v===undefined||v==='')return NaN;\nif(typeof v==='boolean')return v?1:0;\nif(typeof v==='string'){\nconst n=Number(v);\nif(Number.isFinite(n))return n;\nconst t=Date.parse(v);\nreturn Number.isFinite(t)?t:NaN;\n}\nreturn NaN;\n}\nfunction cardinalityOf(handle,indices,count,limit=DEFAULT_CARDINALITY_LIMIT){\nif(!handle)return{cardinality:0,exact:true};\nif(handle.dict)return{cardinality:dictSize(handle.dict),exact:true};\nif(handle.kind==='bitset')return{cardinality:2,exact:true};\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst seen=new Set();\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined)continue;\nseen.add(v);\nif(seen.size>limit)return{cardinality:seen.size,exact:false};\n}\nreturn{cardinality:seen.size,exact:true};\n}\nconst HOUR_MS=3600_000;\nconst DAY_MS=86_400_000;\nfunction pickGranularity(span,target=DEFAULT_BUCKETS){\nconst ms=Number.isFinite(span)&&span>0?span:0;\nconst wide=Math.max(1,target)*2;\nif(ms/HOUR_MS<=wide)return'hour';\nif(ms/DAY_MS<=wide)return'day';\nif(ms/(7*DAY_MS)<=wide)return'week';\nif(ms/(30*DAY_MS)<=wide)return'month';\nif(ms/(91*DAY_MS)<=wide)return'quarter';\nreturn'year';\n}\nfunction floorTo(ms,granularity){\nif(!Number.isFinite(ms))return NaN;\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setMinutes(0,0,0);return d.getTime();\ncase'day':d.setHours(0,0,0,0);return d.getTime();\ncase'week':{\nd.setHours(0,0,0,0);\nconst back=(d.getDay()+6)%7;\nd.setDate(d.getDate()-back);\nreturn d.getTime();\n}\ncase'month':d.setDate(1);d.setHours(0,0,0,0);return d.getTime();\ncase'quarter':\nd.setMonth(Math.floor(d.getMonth()/3)*3,1);\nd.setHours(0,0,0,0);\nreturn d.getTime();\ndefault:d.setMonth(0,1);d.setHours(0,0,0,0);return d.getTime();\n}\n}\nfunction advance(ms,granularity){\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setHours(d.getHours()+1);break;\ncase'day':d.setDate(d.getDate()+1);break;\ncase'week':d.setDate(d.getDate()+7);break;\ncase'month':d.setMonth(d.getMonth()+1);break;\ncase'quarter':d.setMonth(d.getMonth()+3);break;\ndefault:d.setFullYear(d.getFullYear()+1);break;\n}\nreturn d.getTime();\n}\nfunction numericExtent(handle,indices,count){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nlet min=Infinity;\nlet max=-Infinity;\nlet nulls=0;\nlet finite=0;\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){nulls++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){nulls++;continue;}\nif(v<min)min=v;\nif(v>max)max=v;\nfinite++;\n}\nreturn{min,max,nulls,finite};\n}\nfunction sortedSample(handle,indices,count,cap){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nconst step=n>cap?n/cap:1;\nconst out=[];\nfor(let s=0;s<n;s+=step){\nconst i=indices?indices[Math.floor(s)]:Math.floor(s);\nif(present&&!present(i))continue;\nconst v=read(i);\nif(Number.isFinite(v))out.push(v);\n}\nconst arr=Float64Array.from(out);\narr.sort();\nreturn arr;\n}\nfunction computeBounds(handle,indices,count,opts={}){\nconst kind=opts.kind||facetKind(handle,opts.type);\nif(kind==='none'||!handle)return{kind:'none',buckets:[],suppressed:'type'};\nif(kind==='boolean')return boundsForBoolean(handle,indices,count);\nif(kind==='category')return boundsForCategory(handle,indices,count,opts);\nreturn boundsForOrdered(handle,indices,count,kind,opts);\n}\nfunction boundsForBoolean(handle,indices,count){\nconst present=presenceReader(handle);\nlet nulls=0;\nif(present){\nconst n=indices?indices.length:count;\nfor(let k=0;k<n;k++)if(!present(indices?indices[k]:k))nulls++;\n}\nconst buckets=[{value:false,label:'false'},{value:true,label:'true'}];\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'boolean',buckets};\n}\nfunction boundsForCategory(handle,indices,count,opts){\nconst limit=opts.cardinalityLimit??DEFAULT_CARDINALITY_LIMIT;\nconst{cardinality}=cardinalityOf(handle,indices,count,limit);\nif(cardinality>limit&&(opts.aboveLimit||'suppress')==='suppress'){\nreturn{kind:'category',buckets:[],suppressed:'cardinality',cardinality};\n}\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst tally=new Map();\nlet nulls=0;\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){nulls++;continue;}\nif(Array.isArray(v)){\nif(!v.length){nulls++;continue;}\nfor(const m of v)tally.set(m,(tally.get(m)||0)+1);\ncontinue;\n}\ntally.set(v,(tally.get(v)||0)+1);\n}\nlet entries=[...tally.entries()];\nif(opts.order==='alpha'){\nentries.sort((a,b)=>String(a[0]).localeCompare(String(b[0])));\n}else{\nentries.sort((a,b)=>b[1]-a[1]);\n}\nlet remainder=0;\nlet dropped=0;\nif(entries.length>limit){\ndropped=entries.length-limit;\nfor(let i=limit;i<entries.length;i++)remainder+=entries[i][1];\nentries=entries.slice(0,limit);\n}\nconst buckets=entries.map(([value])=>({value,label:String(value)}));\nif(remainder>0)buckets.push({remainder:true,label:`Other (${dropped} values)`});\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'category',buckets,cardinality};\n}\nfunction boundsForOrdered(handle,indices,count,kind,opts){\nconst{min,max,nulls,finite}=numericExtent(handle,indices,count);\nif(!finite){\nreturn{kind,buckets:nulls?[{null:true,label:'Empty'}]:[],empty:true};\n}\nconst wanted=Math.max(1,Math.floor(opts.buckets||DEFAULT_BUCKETS));\nlet buckets=[];\nif(kind==='date'){\nconst granularity=GRANULARITIES.includes(opts.granularity)\n?opts.granularity:pickGranularity(max-min,wanted);\nlet edge=floorTo(min,granularity);\nwhile(edge<=max&&buckets.length<4096){\nconst next=advance(edge,granularity);\nif(!(next>edge))break;\nbuckets.push({from:edge,to:next});\nedge=next;\n}\nreturn{kind,buckets:withNull(buckets,nulls),granularity};\n}\nconst strategy=STRATEGIES.includes(opts.strategy)?opts.strategy:'equal';\nif(strategy==='quantile'){\nconst sample=sortedSample(handle,indices,count,QUANTILE_SAMPLE);\nif(sample.length){\nconst edges=[sample[0]];\nfor(let b=1;b<wanted;b++){\nconst v=sample[Math.min(sample.length-1,Math.floor((b/wanted)*sample.length))];\nif(v>edges[edges.length-1])edges.push(v);\n}\nedges.push(max);\nfor(let b=0;b<edges.length-1;b++)buckets.push({from:edges[b],to:edges[b+1]});\n}\n}else if(strategy==='log'&&min>0){\nconst lo=Math.log10(min);\nconst hi=Math.log10(max);\nconst step=(hi-lo)/wanted||1;\nfor(let b=0;b<wanted;b++){\nbuckets.push({from:10**(lo+b*step),to:10**(lo+(b+1)*step)});\n}\n}\nif(!buckets.length){\nconst width=(max-min)/wanted||1;\nfor(let b=0;b<wanted;b++)buckets.push({from:min+b*width,to:min+(b+1)*width});\n}\nbuckets[buckets.length-1].to=max;\nreturn{kind,buckets:withNull(buckets,nulls),strategy,min,max};\n}\nfunction withNull(buckets,nulls){\nreturn nulls>0?[...buckets,{null:true,label:'Empty'}]:buckets;\n}\nfunction countInto(handle,indices,count,bounds,out){\nconst buckets=(bounds&&bounds.buckets)||[];\nconst counts=out&&out.length>=buckets.length?out.subarray(0,buckets.length)\n:new Uint32Array(buckets.length);\ncounts.fill(0);\nif(!handle||!buckets.length)return counts;\nconst nullBucket=buckets.length-1;\nconst hasNull=!!buckets[nullBucket]&&buckets[nullBucket].null===true;\nconst n=indices?indices.length:count;\nif(bounds.kind==='boolean'){\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined){if(hasNull)counts[nullBucket]++;continue;}\ncounts[v?1:0]++;\n}\nreturn counts;\n}\nif(bounds.kind==='category'){\nconst slot=new Map();\nfor(let b=0;b<buckets.length;b++){\nif(!buckets[b].null&&!buckets[b].remainder)slot.set(buckets[b].value,b);\n}\nconst remainderAt=buckets.findIndex((b)=>b.remainder);\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){if(hasNull)counts[nullBucket]++;continue;}\nif(Array.isArray(v)){\nif(!v.length){if(hasNull)counts[nullBucket]++;continue;}\nfor(const m of v){\nconst at=slot.get(m);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\ncontinue;\n}\nconst at=slot.get(v);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\nreturn counts;\n}\nconst ordered=hasNull?buckets.length-1:buckets.length;\nconst edges=new Float64Array(ordered+1);\nfor(let b=0;b<ordered;b++)edges[b]=buckets[b].from;\nedges[ordered]=ordered?buckets[ordered-1].to:0;\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){if(hasNull)counts[nullBucket]++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){if(hasNull)counts[nullBucket]++;continue;}\nconst at=bucketOf(edges,ordered,v);\nif(at>=0)counts[at]++;\n}\nreturn counts;\n}\nfunction bucketOf(edges,ordered,v){\nif(!ordered)return-1;\nif(v<edges[0])return-1;\nif(v>=edges[ordered])return v===edges[ordered]?ordered-1:-1;\nlet lo=0;\nlet hi=ordered-1;\nwhile(lo<hi){\nconst mid=(lo+hi+1)>>>1;\nif(v>=edges[mid])lo=mid;else hi=mid-1;\n}\nreturn lo;\n}\nfunction facet(handle,indices,count,opts={}){\nconst bounds=opts.bounds||computeBounds(handle,opts.boundsIndices??indices,count,opts);\nreturn{bounds,counts:countInto(handle,indices,count,bounds)};\n}\nconst __default=facet;\n});\n__def(\"packages/core/src/compute/special.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"logGamma\",{enumerable:true,get:function(){return logGamma;}});\nObject.defineProperty(__exports,\"incompleteBeta\",{enumerable:true,get:function(){return incompleteBeta;}});\nObject.defineProperty(__exports,\"normalQuantile\",{enumerable:true,get:function(){return normalQuantile;}});\nObject.defineProperty(__exports,\"studentT\",{enumerable:true,get:function(){return studentT;}});\nObject.defineProperty(__exports,\"studentTQuantile\",{enumerable:true,get:function(){return studentTQuantile;}});\nconst LANCZOS=Object.freeze([\n676.5203681218851,-1259.1392167224028,771.32342877765313,\n-176.61502916214059,12.507343278686905,-0.13857109526572012,\n9.9843695780195716e-6,1.5056327351493116e-7,\n]);\nconst EPS=3e-12;\nconst TINY=1e-300;\nfunction logGamma(x){\nif(x<0.5)return Math.log(Math.PI/Math.sin(Math.PI*x))-logGamma(1-x);\nconst z=x-1;\nlet a=0.99999999999980993;\nconst t=z+7.5;\nfor(let i=0;i<LANCZOS.length;i++)a+=LANCZOS[i]/(z+i+1);\nreturn 0.5*Math.log(2*Math.PI)+(z+0.5)*Math.log(t)-t+Math.log(a);\n}\nfunction betaContinuedFraction(a,b,x){\nconst qab=a+b;\nconst qap=a+1;\nconst qam=a-1;\nlet c=1;\nlet d=1-(qab*x)/qap;\nif(Math.abs(d)<TINY)d=TINY;\nd=1/d;\nlet h=d;\nfor(let m=1;m<=300;m++){\nconst m2=2*m;\nlet aa=(m*(b-m)*x)/((qam+m2)*(a+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nh*=d*c;\naa=(-(a+m)*(qab+m)*x)/((a+m2)*(qap+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nconst step=d*c;\nh*=step;\nif(Math.abs(step-1)<EPS)break;\n}\nreturn h;\n}\nfunction incompleteBeta(a,b,x){\nif(!(a>0)||!(b>0)||!Number.isFinite(x))return Number.NaN;\nif(x<=0)return 0;\nif(x>=1)return 1;\nconst front=Math.exp(\nlogGamma(a+b)-logGamma(a)-logGamma(b)+a*Math.log(x)+b*Math.log(1-x),\n);\nreturn x<(a+1)/(a+b+2)\n?(front*betaContinuedFraction(a,b,x))/a\n:1-(front*betaContinuedFraction(b,a,1-x))/b;\n}\nfunction normalQuantile(p){\nif(!(p>0)||!(p<1))return p===0?-Infinity:(p===1?Infinity:Number.NaN);\nconst a=[-3.969683028665376e+1,2.209460984245205e+2,-2.759285104469687e+2,\n1.383577518672690e+2,-3.066479806614716e+1,2.506628277459239];\nconst b=[-5.447609879822406e+1,1.615858368580409e+2,-1.556989798598866e+2,\n6.680131188771972e+1,-1.328068155288572e+1];\nconst c=[-7.784894002430293e-3,-3.223964580411365e-1,-2.400758277161838,\n-2.549732539343734,4.374664141464968,2.938163982698783];\nconst d=[7.784695709041462e-3,3.224671290700398e-1,2.445134137142996,\n3.754408661907416];\nconst low=0.02425;\nlet q;\nlet r;\nlet x;\nif(p<low){\nq=Math.sqrt(-2*Math.log(p));\nx=(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}else if(p<=1-low){\nq=p-0.5;\nr=q*q;\nx=((((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q)\n/ (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);\n}else{\nq=Math.sqrt(-2*Math.log(1-p));\nx=-(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}\nconst e=0.5*erfc(-x/Math.SQRT2)-p;\nconst u=e*Math.sqrt(2*Math.PI)*Math.exp((x*x)/2);\nreturn x-u/(1+(x*u)/2);\n}\nfunction erfc(x){\nconst z=Math.abs(x);\nconst t=2/(2+z);\nconst ty=4*t-2;\nconst cof=[-1.3026537197817094,6.4196979235649026e-1,1.9476473204185836e-2,\n-9.561514786808631e-3,-9.46595344482036e-4,3.66839497852761e-4,\n4.2523324806907e-5,-2.0278578112534e-5,-1.624290004647e-6,\n1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,6.529054439e-9,\n5.059343495e-9,-9.91364156e-10,-2.27365122e-10,9.6467911e-11,\n2.394038e-12,-6.886027e-12,8.94487e-13,3.13092e-13,-1.12708e-13,\n3.81e-16,7.106e-15];\nlet dd=0;\nlet dv=0;\nlet tmp;\nfor(let j=cof.length-1;j>0;j--){\ntmp=dv;\ndv=ty*dv-dd+cof[j];\ndd=tmp;\n}\nconst ans=t*Math.exp(-z*z+0.5*(cof[0]+ty*dv)-dd);\nreturn x>=0?ans:2-ans;\n}\nfunction studentT(t,df){\nif(!(df>0)||!Number.isFinite(t))return Number.NaN;\nconst tail=0.5*incompleteBeta(df/2,0.5,df/(df+t*t));\nreturn t>0?1-tail:tail;\n}\nfunction studentTQuantile(p,df){\nif(!(p>0)||!(p<1)||!(df>0))return Number.NaN;\nif(df>1e7)return normalQuantile(p);\nlet lo=-1e4;\nlet hi=1e4;\nlet x=normalQuantile(p);\nconst logBeta=logGamma(df/2)+logGamma(0.5)-logGamma((df+1)/2);\nfor(let i=0;i<60;i++){\nconst cdf=studentT(x,df);\nif(cdf<p)lo=x;else hi=x;\nconst pdf=Math.exp(-((df+1)/2)*Math.log(1+(x*x)/df)-logBeta)\n/ Math.sqrt(df);\nconst step=pdf>0?(cdf-p)/pdf:0;\nif(Math.abs(step)<1e-12)break;\nconst next=x-step;\nx=next>lo&&next<hi&&Number.isFinite(next)?next:(lo+hi)/2;\nif(hi-lo<1e-12)break;\n}\nreturn x;\n}\n});\n__def(\"packages/core/src/compute/statistics.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KENDALL_LIMIT\",{enumerable:true,get:function(){return KENDALL_LIMIT;}});\nObject.defineProperty(__exports,\"MAINTENANCE\",{enumerable:true,get:function(){return MAINTENANCE;}});\nObject.defineProperty(__exports,\"numbers\",{enumerable:true,get:function(){return numbers;}});\nObject.defineProperty(__exports,\"frequencies\",{enumerable:true,get:function(){return frequencies;}});\nObject.defineProperty(__exports,\"herfindahl\",{enumerable:true,get:function(){return herfindahl;}});\nObject.defineProperty(__exports,\"entropy\",{enumerable:true,get:function(){return entropy;}});\nObject.defineProperty(__exports,\"evenness\",{enumerable:true,get:function(){return evenness;}});\nObject.defineProperty(__exports,\"topShare\",{enumerable:true,get:function(){return topShare;}});\nObject.defineProperty(__exports,\"gini\",{enumerable:true,get:function(){return gini;}});\nObject.defineProperty(__exports,\"moments\",{enumerable:true,get:function(){return moments;}});\nObject.defineProperty(__exports,\"quantileSorted\",{enumerable:true,get:function(){return quantileSorted;}});\nObject.defineProperty(__exports,\"quantile\",{enumerable:true,get:function(){return quantile;}});\nObject.defineProperty(__exports,\"STAT_FNS\",{enumerable:true,get:function(){return STAT_FNS;}});\nObject.defineProperty(__exports,\"STAT_LABELS\",{enumerable:true,get:function(){return STAT_LABELS;}});\nObject.defineProperty(__exports,\"weightedAverage\",{enumerable:true,get:function(){return weightedAverage;}});\nObject.defineProperty(__exports,\"extremeRow\",{enumerable:true,get:function(){return extremeRow;}});\nObject.defineProperty(__exports,\"correlation\",{enumerable:true,get:function(){return correlation;}});\nObject.defineProperty(__exports,\"trimmedMean\",{enumerable:true,get:function(){return trimmedMean;}});\nObject.defineProperty(__exports,\"winsorizedMean\",{enumerable:true,get:function(){return winsorizedMean;}});\nObject.defineProperty(__exports,\"modifiedZOutliers\",{enumerable:true,get:function(){return modifiedZOutliers;}});\nObject.defineProperty(__exports,\"jarqueBera\",{enumerable:true,get:function(){return jarqueBera;}});\nObject.defineProperty(__exports,\"weightedQuantile\",{enumerable:true,get:function(){return weightedQuantile;}});\nObject.defineProperty(__exports,\"pairs\",{enumerable:true,get:function(){return pairs;}});\nObject.defineProperty(__exports,\"covariance\",{enumerable:true,get:function(){return covariance;}});\nObject.defineProperty(__exports,\"regression\",{enumerable:true,get:function(){return regression;}});\nObject.defineProperty(__exports,\"spearman\",{enumerable:true,get:function(){return spearman;}});\nObject.defineProperty(__exports,\"kendall\",{enumerable:true,get:function(){return kendall;}});\nObject.defineProperty(__exports,\"seriesStats\",{enumerable:true,get:function(){return seriesStats;}});\nObject.defineProperty(__exports,\"D2_N2\",{enumerable:true,get:function(){return D2_N2;}});\nObject.defineProperty(__exports,\"D4_N2\",{enumerable:true,get:function(){return D4_N2;}});\nObject.defineProperty(__exports,\"movingRanges\",{enumerable:true,get:function(){return movingRanges;}});\nObject.defineProperty(__exports,\"withinSigma\",{enumerable:true,get:function(){return withinSigma;}});\nObject.defineProperty(__exports,\"capability\",{enumerable:true,get:function(){return capability;}});\nObject.defineProperty(__exports,\"controlLimits\",{enumerable:true,get:function(){return controlLimits;}});\nObject.defineProperty(__exports,\"westernElectricViolations\",{enumerable:true,get:function(){return westernElectricViolations;}});\nObject.defineProperty(__exports,\"nelsonViolations\",{enumerable:true,get:function(){return nelsonViolations;}});\nObject.defineProperty(__exports,\"CONTROL_RULE_SETS\",{enumerable:true,get:function(){return CONTROL_RULE_SETS;}});\nObject.defineProperty(__exports,\"controlViolations\",{enumerable:true,get:function(){return controlViolations;}});\nObject.defineProperty(__exports,\"countOutside\",{enumerable:true,get:function(){return countOutside;}});\nObject.defineProperty(__exports,\"histogram\",{enumerable:true,get:function(){return histogram;}});\nObject.defineProperty(__exports,\"DEFAULT_CONFIDENCE\",{enumerable:true,get:function(){return DEFAULT_CONFIDENCE;}});\nObject.defineProperty(__exports,\"meanInterval\",{enumerable:true,get:function(){return meanInterval;}});\nObject.defineProperty(__exports,\"proportionInterval\",{enumerable:true,get:function(){return proportionInterval;}});\nObject.defineProperty(__exports,\"slopeInterval\",{enumerable:true,get:function(){return slopeInterval;}});\nObject.defineProperty(__exports,\"capabilityInterval\",{enumerable:true,get:function(){return capabilityInterval;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst __m1=__req(\"packages/core/src/compute/special.js\");\nconst studentTQuantile=__m1[\"studentTQuantile\"];\nconst normalQuantile=__m1[\"normalQuantile\"];\nconst KENDALL_LIMIT=5000;\nconst MAINTENANCE=Object.freeze({\nvariance:'rescan',\nvarianceP:'rescan',\nstddev:'rescan',\nstddevP:'rescan',\nsumSquares:'rescan',\nweightedAvg:'maintained',\nmedian:'rescan',\np25:'rescan',\np75:'rescan',\np90:'rescan',\np95:'rescan',\np99:'rescan',\niqr:'rescan',\nmode:'rescan',\ndistinct:'rescan',\nrange:'rescan',\nskewness:'rescan',\nkurtosis:'rescan',\ngeomean:'rescan',\nharmean:'rescan',\nmad:'rescan',\nargmin:'rescan',\nargmax:'rescan',\nhhi:'rescan',\nentropy:'rescan',\nevenness:'rescan',\ntop3Share:'rescan',\ntop10Share:'rescan',\ngini:'rescan',\ntrimmedMean:'rescan',\nwinsorizedMean:'rescan',\nrobustOutliers:'rescan',\njarqueBera:'rescan',\n});\nfunction numbers(handle,indices){\nconst n=indices.length;\nconst out=new Float64Array(n);\nlet count=0;\nconst numeric=handle&&(handle.kind==='float64'||handle.kind==='int32');\nif(numeric){\nconst values=handle.values;\nconst present=presenceReader(handle);\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present&&present(row)!==1)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nconst v=typeof raw==='number'?raw:Number(raw);\nif(!Number.isFinite(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nfunction frequencies(handle,indices){\nconst seen=new Map();\nconst read=valueReader(handle);\nlet total=0;\nfor(let i=0;i<indices.length;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nif(typeof raw==='number'&&Number.isNaN(raw))continue;\nconst key=typeof raw==='object'?String(raw):raw;\nseen.set(key,(seen.get(key)||0)+1);\ntotal++;\n}\nconst counts=[...seen.values()].sort((a,b)=>b-a);\nreturn{counts,total,distinct:counts.length};\n}\nfunction sharesOf(freq){\nreturn freq.total>0?freq.counts.map((c)=>c/freq.total):[];\n}\nfunction herfindahl(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))sum+=share*share;\nreturn sum;\n}\nfunction entropy(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum;\n}\nfunction evenness(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total||freq.distinct<2)return freq.total?1:null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum/Math.log2(freq.distinct);\n}\nfunction topShare(handle,indices,n=3){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nconst take=Math.max(1,Math.floor(n));\nlet held=0;\nfor(let i=0;i<Math.min(take,freq.counts.length);i++)held+=freq.counts[i];\nreturn held/freq.total;\n}\nfunction gini(handle,indices){\nconst values=numbers(handle,indices);\nconst n=values.length;\nif(!n)return null;\nconst sorted=values.slice().sort();\nif(sorted[0]<0)return null;\nlet total=0;\nlet weighted=0;\nfor(let i=0;i<n;i++){\ntotal+=sorted[i];\nweighted+=(i+1)*sorted[i];\n}\nif(total===0)return 0;\nreturn(2*weighted)/(n*total)-(n+1)/n;\n}\nfunction moments(values){\nlet n=0;\nlet mean=0;\nlet m2=0;\nfor(let i=0;i<values.length;i++){\nconst x=values[i];\nn++;\nconst delta=x-mean;\nmean+=delta/n;\nm2+=delta*(x-mean);\n}\nreturn{n,mean,m2};\n}\nfunction quantileSorted(sorted,p){\nconst n=sorted.length;\nif(!n)return NaN;\nif(n===1)return sorted[0];\nconst h=(n-1)*Math.min(1,Math.max(0,p));\nconst lo=Math.floor(h);\nconst hi=Math.ceil(h);\nif(lo===hi)return sorted[lo];\nreturn sorted[lo]+(h-lo)*(sorted[hi]-sorted[lo]);\n}\nfunction quantile(values,p){\nif(!values.length)return NaN;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,p);\n}\nconst STAT_FNS=Object.freeze({\nhhi:(h,i)=>herfindahl(h,i),\nentropy:(h,i)=>entropy(h,i),\nevenness:(h,i)=>evenness(h,i),\ntop3Share:(h,i)=>topShare(h,i,3),\ntop10Share:(h,i)=>topShare(h,i,10),\ngini:(h,i)=>gini(h,i),\ntrimmedMean:(h,i)=>trimmedMean(numbers(h,i),0.1),\nwinsorizedMean:(h,i)=>winsorizedMean(numbers(h,i),0.1),\nrobustOutliers:(h,i)=>modifiedZOutliers(numbers(h,i),3.5),\njarqueBera:(h,i)=>jarqueBera(numbers(h,i)),\nvariance:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?m2/(n-1):null;\n},\nvarianceP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?m2/n:null;\n},\nstddev:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?Math.sqrt(m2/(n-1)):null;\n},\nstddevP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?Math.sqrt(m2/n):null;\n},\nmedian:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.5):null;\n},\np25:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.25):null;\n},\np75:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.75):null;\n},\np90:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.9):null;\n},\np95:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.95):null;\n},\np99:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.99):null;\n},\niqr:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,0.75)-quantileSorted(sorted,0.25);\n},\nmad:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst middle=quantile(values,0.5);\nconst deviations=new Float64Array(values.length);\nfor(let k=0;k<values.length;k++)deviations[k]=Math.abs(values[k]-middle);\nreturn quantile(deviations,0.5);\n},\nrange:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet lo=Infinity;\nlet hi=-Infinity;\nfor(let k=0;k<values.length;k++){\nif(values[k]<lo)lo=values[k];\nif(values[k]>hi)hi=values[k];\n}\nreturn hi-lo;\n},\ndistinct:(h,i)=>{\nconst read=valueReader(h);\nconst seen=new Set();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nseen.add(v instanceof Date?v.getTime():v);\n}\nreturn seen.size;\n},\nmode:(h,i)=>{\nconst read=valueReader(h);\nconst counts=new Map();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nconst id=v instanceof Date?v.getTime():v;\ncounts.set(id,(counts.get(id)||0)+1);\n}\nlet best=null;\nlet most=1;\nfor(const[value,times]of counts){\nif(times>most){\nmost=times;\nbest=value;\n}\n}\nreturn best;\n},\nskewness:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<3||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**3;\nreturn(n/((n-1)*(n-2)))*sum;\n},\nkurtosis:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<4||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**4;\nconst a=(n*(n+1))/((n-1)*(n-2)*(n-3));\nconst b=(3*(n-1)**2)/((n-2)*(n-3));\nreturn a*sum-b;\n},\ngeomean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]<=0)return null;\nsum+=Math.log(values[k]);\n}\nreturn Math.exp(sum/values.length);\n},\nharmean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]===0)return null;\nsum+=1/values[k];\n}\nreturn values.length/sum;\n},\nsumSquares:(h,i)=>{\nconst values=numbers(h,i);\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=values[k]*values[k];\nreturn sum;\n},\n});\nconst STAT_LABELS=Object.freeze({\nhhi:'Concentration (HHI)',\nentropy:'Entropy',\nevenness:'Evenness',\ntop3Share:'Top 3 share',\ntop10Share:'Top 10 share',\ngini:'Gini coefficient',\ntrimmedMean:'Trimmed mean',\nwinsorizedMean:'Winsorized mean',\nrobustOutliers:'Outliers (robust)',\njarqueBera:'Jarque–Bera',\nmedian:'Median',\np25:'25th percentile',\np75:'75th percentile',\np90:'90th percentile',\np95:'95th percentile',\np99:'99th percentile',\niqr:'Interquartile range',\nmad:'Median absolute deviation',\nvariance:'Variance',\nvarianceP:'Variance (population)',\nstddev:'Standard deviation',\nstddevP:'Standard deviation (population)',\nrange:'Range',\ndistinct:'Distinct',\nmode:'Mode',\nskewness:'Skewness',\nkurtosis:'Kurtosis',\ngeomean:'Geometric mean',\nharmean:'Harmonic mean',\nsumSquares:'Sum of squares',\nweightedAvg:'Weighted average',\nargmin:'Lowest by',\nargmax:'Highest by',\n});\nfunction weightedAverage(handle,weights,indices){\nconst readValue=valueReader(handle);\nconst readWeight=valueReader(weights);\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(readValue(row));\nconst weight=Number(readWeight(row));\nif(!Number.isFinite(value)||!Number.isFinite(weight))continue;\ntop+=value*weight;\nbottom+=weight;\n}\nreturn bottom===0?null:top/bottom;\n}\nfunction extremeRow(handle,indices,largest){\nconst read=valueReader(handle);\nlet best=null;\nlet bestValue=largest?-Infinity:Infinity;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(read(row));\nif(!Number.isFinite(value))continue;\nif(largest?value>bestValue:value<bestValue){\nbestValue=value;\nbest=row;\n}\n}\nreturn best;\n}\nfunction correlation(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nlet n=0;\nlet sx=0;\nlet sy=0;\nlet sxx=0;\nlet syy=0;\nlet sxy=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nn++;\nsx+=x;\nsy+=y;\nsxx+=x*x;\nsyy+=y*y;\nsxy+=x*y;\n}\nif(n<2)return null;\nconst top=n*sxy-sx*sy;\nconst bottom=Math.sqrt((n*sxx-sx*sx)*(n*syy-sy*sy));\nif(bottom===0)return null;\nconst r=top/bottom;\nreturn Math.max(-1,Math.min(1,r));\n}\nfunction trimmedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst kept=sorted.slice(cut,n-cut);\nif(!kept.length)return quantileSorted(sorted,0.5);\nlet sum=0;\nfor(const v of kept)sum+=v;\nreturn sum/kept.length;\n}\nfunction winsorizedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst low=sorted[cut];\nconst high=sorted[n-1-cut];\nlet sum=0;\nfor(const v of sorted)sum+=Math.min(high,Math.max(low,v));\nreturn sum/n;\n}\nfunction modifiedZOutliers(values,threshold=3.5){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst middle=quantileSorted(sorted,0.5);\nconst deviations=sorted.map((v)=>Math.abs(v-middle)).sort((a,b)=>a-b);\nconst mad=quantileSorted(deviations,0.5);\nif(mad===0)return null;\nlet count=0;\nfor(const v of sorted)if(Math.abs((0.6745*(v-middle))/mad)>threshold)count++;\nreturn count;\n}\nfunction jarqueBera(values){\nconst n=values.length;\nif(n<8)return null;\nlet mean=0;\nfor(const v of values)mean+=v;\nmean/=n;\nlet m2=0;\nlet m3=0;\nlet m4=0;\nfor(const v of values){\nconst d=v-mean;\nm2+=d*d;\nm3+=d*d*d;\nm4+=d*d*d*d;\n}\nm2/=n;\nm3/=n;\nm4/=n;\nif(m2===0)return null;\nconst skew=m3/m2**1.5;\nconst excess=m4/(m2*m2)-3;\nreturn(n/6)*(skew*skew+(excess*excess)/4);\n}\nfunction weightedQuantile(values,weights,p){\nconst paired=[];\nlet total=0;\nfor(let i=0;i<values.length;i++){\nconst v=Number(values[i]);\nconst w=Number(weights[i]);\nif(!Number.isFinite(v)||!Number.isFinite(w)||w<=0)continue;\npaired.push([v,w]);\ntotal+=w;\n}\nif(!paired.length||total<=0)return null;\npaired.sort((a,b)=>a[0]-b[0]);\nif(paired.length===1)return paired[0][0];\nconst at=[];\nlet seen=0;\nfor(const[,w]of paired){\nat.push((seen+w/2)/total);\nseen+=w;\n}\nconst target=Math.max(0,Math.min(1,p));\nif(target<=at[0])return paired[0][0];\nif(target>=at[at.length-1])return paired[paired.length-1][0];\nfor(let i=1;i<at.length;i++){\nif(target>at[i])continue;\nconst span=at[i]-at[i-1];\nconst within=span>0?(target-at[i-1])/span:0;\nreturn paired[i-1][0]+(paired[i][0]-paired[i-1][0])*within;\n}\nreturn paired[paired.length-1][0];\n}\nfunction pairs(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nconst xs=new Float64Array(indices.length);\nconst ys=new Float64Array(indices.length);\nlet n=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nxs[n]=x;\nys[n]=y;\nn++;\n}\nreturn{xs:xs.subarray(0,n),ys:ys.subarray(0,n),n};\n}\nfunction covariance(a,b,indices,population=false){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=(xs[i]-mx)*(ys[i]-my);\nreturn sum/(population?n:n-1);\n}\nfunction regression(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sxx=0;\nlet sxy=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=xs[i]-mx;\nconst dy=ys[i]-my;\nsxx+=dx*dx;\nsxy+=dx*dy;\nsyy+=dy*dy;\n}\nif(sxx===0)return null;\nconst slope=sxy/sxx;\nconst intercept=my-slope*mx;\nconst r2=syy===0?1:Math.max(0,Math.min(1,(sxy*sxy)/(sxx*syy)));\nconst residual=Math.max(0,syy-slope*sxy);\nconst stdError=n>2?Math.sqrt(residual/(n-2)/sxx):0;\nreturn{slope,intercept,r2,stdError,n};\n}\nfunction ranksOf(values){\nconst n=values.length;\nconst order=Array.from({length:n},(unused,i)=>i)\n.sort((i,j)=>values[i]-values[j]);\nconst ranks=new Float64Array(n);\nlet i=0;\nwhile(i<n){\nlet j=i;\nwhile(j+1<n&&values[order[j+1]]===values[order[i]])j++;\nconst shared=(i+j)/2+1;\nfor(let k=i;k<=j;k++)ranks[order[k]]=shared;\ni=j+1;\n}\nreturn ranks;\n}\nfunction spearman(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nconst rx=ranksOf(xs);\nconst ry=ranksOf(ys);\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=rx[i];my+=ry[i];}\nmx/=n;\nmy/=n;\nlet sxy=0;\nlet sxx=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=rx[i]-mx;\nconst dy=ry[i]-my;\nsxy+=dx*dy;\nsxx+=dx*dx;\nsyy+=dy*dy;\n}\nif(sxx===0||syy===0)return null;\nreturn Math.max(-1,Math.min(1,sxy/Math.sqrt(sxx*syy)));\n}\nfunction kendall(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2||n>KENDALL_LIMIT)return null;\nlet concordant=0;\nlet discordant=0;\nlet tiedXOnly=0;\nlet tiedYOnly=0;\nfor(let i=0;i<n;i++){\nfor(let j=i+1;j<n;j++){\nconst dx=Math.sign(xs[i]-xs[j]);\nconst dy=Math.sign(ys[i]-ys[j]);\nconst product=dx*dy;\nif(product>0)concordant++;\nelse if(product<0)discordant++;\nelse if(dx===0&&dy===0){}\nelse if(dx===0)tiedXOnly++;\nelse tiedYOnly++;\n}\n}\nconst orderedByX=concordant+discordant+tiedYOnly;\nconst orderedByY=concordant+discordant+tiedXOnly;\nif(orderedByX===0||orderedByY===0)return null;\nreturn(concordant-discordant)/Math.sqrt(orderedByX*orderedByY);\n}\nfunction seriesStats(ordered,opts={}){\nconst n=ordered.length;\nif(n<2)return null;\nconst first=ordered[0];\nconst last=ordered[n-1];\nconst returns=[];\nfor(let i=1;i<n;i++){\nconst previous=ordered[i-1];\nif(previous===0)continue;\nreturns.push((ordered[i]-previous)/Math.abs(previous));\n}\nlet volatility=null;\nif(returns.length>1){\nlet mean=0;\nfor(const r of returns)mean+=r;\nmean/=returns.length;\nlet m2=0;\nfor(const r of returns)m2+=(r-mean)**2;\nvolatility=Math.sqrt(m2/(returns.length-1));\n}\nconst periods=Number(opts.periodsPerYear)>0?Number(opts.periodsPerYear):null;\nlet peak=ordered[0];\nlet peakAt=0;\nlet worst=0;\nlet worstFrom=0;\nlet worstTo=0;\nfor(let i=1;i<n;i++){\nif(ordered[i]>peak){peak=ordered[i];peakAt=i;continue;}\nif(peak<=0)continue;\nconst fall=(peak-ordered[i])/peak;\nif(fall>worst){worst=fall;worstFrom=peakAt;worstTo=i;}\n}\nlet autocorrelation=null;\nif(n>2){\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<n;i++){\nconst d=ordered[i]-mean;\nbottom+=d*d;\nif(i>0)top+=d*(ordered[i-1]-mean);\n}\nautocorrelation=bottom>0?top/bottom:null;\n}\nlet up=0;\nlet down=0;\nfor(const r of returns){if(r>0)up++;else if(r<0)down++;}\nlet growth=null;\nif(first>0&&last>0){\nconst perPeriod=(last/first)**(1/(n-1))-1;\ngrowth=periods?(1+perPeriod)**periods-1:perPeriod;\n}\nreturn{\nn,\nfirst,\nlast,\nchange:last-first,\nchangePercent:first===0?null:((last-first)/Math.abs(first))*100,\nvolatility,\nannualisedVolatility:volatility!==null&&periods?volatility*Math.sqrt(periods):null,\ngrowth,\nmaxDrawdown:worst,\nmaxDrawdownFrom:worstFrom,\nmaxDrawdownTo:worstTo,\nautocorrelation,\nupDays:up,\ndownDays:down,\n};\n}\nconst D2_N2=1.128;\nconst D4_N2=3.267;\nfunction movingRanges(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst ranges=[];\nfor(let i=1;i<n;i++)ranges.push(Math.abs(ordered[i]-ordered[i-1]));\nconst centre=ranges.reduce((t,r)=>t+r,0)/ranges.length;\nreturn{ranges,centre,upper:D4_N2*centre,lower:0};\n}\nfunction withinSigma(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nlet total=0;\nfor(let i=1;i<n;i++)total+=Math.abs(ordered[i]-ordered[i-1]);\nconst meanRange=total/(n-1);\nreturn{sigma:meanRange/D2_N2,meanRange};\n}\nfunction capability(ordered,spec){\nconst n=ordered.length;\nif(n<2||!spec)return null;\nconst lower=Number.isFinite(Number(spec.lower))?Number(spec.lower):null;\nconst upper=Number.isFinite(Number(spec.upper))?Number(spec.upper):null;\nif(lower===null&&upper===null)return null;\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet m2=0;\nfor(let i=0;i<n;i++)m2+=(ordered[i]-mean)**2;\nconst overall=Math.sqrt(m2/(n-1));\nconst within=withinSigma(ordered);\nconst sigmaWithin=within?within.sigma:null;\nconst indices=(sigma)=>{\nif(!sigma||sigma<=0)return{index:null,k:null};\nconst both=lower!==null&&upper!==null;\nconst index=both?(upper-lower)/(6*sigma):null;\nconst upperSide=upper!==null?(upper-mean)/(3*sigma):Infinity;\nconst lowerSide=lower!==null?(mean-lower)/(3*sigma):Infinity;\nreturn{index,k:Math.min(upperSide,lowerSide)};\n};\nconst short=indices(sigmaWithin);\nconst long=indices(overall);\nlet outOfSpec=0;\nfor(let i=0;i<n;i++){\nif(lower!==null&&ordered[i]<lower){outOfSpec++;continue;}\nif(upper!==null&&ordered[i]>upper)outOfSpec++;\n}\nreturn{\nn,\nmean,\nlower,\nupper,\ntarget:Number.isFinite(Number(spec.target))?Number(spec.target):null,\nsigmaWithin,\nsigmaOverall:overall,\ncp:short.index,\ncpk:short.k,\npp:long.index,\nppk:long.k,\noutOfSpec,\ndefectRate:n?outOfSpec/n:null,\n};\n}\nfunction controlLimits(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst within=withinSigma(ordered);\nif(!within||!(within.sigma>0))return null;\nlet centre=0;\nfor(let i=0;i<n;i++)centre+=ordered[i];\ncentre/=n;\nreturn{\ncentre,\nsigma:within.sigma,\nupper:centre+3*within.sigma,\nlower:centre-3*within.sigma,\n};\n}\nfunction westernElectricViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3){\nout.push({index:i,rule:1,description:'beyond three sigma'});\n}\nif(i>=2){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-2;k<=i;k++)if(z(k)*side>2)hits++;\nif(hits>=2){\nout.push({index:i,rule:2,description:'two of three past two sigma'});\nbreak;\n}\n}\n}\nif(i>=4){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-4;k<=i;k++)if(z(k)*side>1)hits++;\nif(hits>=4){\nout.push({index:i,rule:3,description:'four of five past one sigma'});\nbreak;\n}\n}\n}\nif(i>=7){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-7;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){\nout.push({index:i,rule:4,description:'eight in a row on one side'});\nbreak;\n}\n}\n}\n}\nreturn out;\n}\nfunction nelsonViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst oneSide=(from,to,past,need)=>{\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=from;k<=to;k++)if(z(k)*side>past)hits++;\nif(hits>=need)return true;\n}\nreturn false;\n};\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3)out.push({index:i,rule:1,description:'beyond three sigma'});\nif(i>=8){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-8;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){out.push({index:i,rule:2,description:'nine in a row on one side'});break;}\n}\n}\nif(i>=5){\nfor(const dir of[1,-1]){\nlet all=true;\nfor(let k=i-4;k<=i;k++){\nif((ordered[k]-ordered[k-1])*dir<=0){all=false;break;}\n}\nif(all){\nout.push({index:i,rule:3,description:dir>0?'six rising':'six falling'});\nbreak;\n}\n}\n}\nif(i>=13){\nlet alternating=true;\nfor(let k=i-12;k<=i;k++){\nconst a=ordered[k]-ordered[k-1];\nconst b=ordered[k+1<=i?k+1:k]-ordered[k];\nif(k+1>i)break;\nif(a===0||b===0||(a>0)===(b>0)){alternating=false;break;}\n}\nif(alternating)out.push({index:i,rule:4,description:'fourteen alternating'});\n}\nif(i>=2&&oneSide(i-2,i,2,2)){\nout.push({index:i,rule:5,description:'two of three past two sigma'});\n}\nif(i>=4&&oneSide(i-4,i,1,4)){\nout.push({index:i,rule:6,description:'four of five past one sigma'});\n}\nif(i>=14){\nlet inside=true;\nfor(let k=i-14;k<=i;k++)if(Math.abs(z(k))>=1){inside=false;break;}\nif(inside)out.push({index:i,rule:7,description:'fifteen within one sigma'});\n}\nif(i>=7){\nlet outside=true;\nfor(let k=i-7;k<=i;k++)if(Math.abs(z(k))<=1){outside=false;break;}\nif(outside)out.push({index:i,rule:8,description:'eight beyond one sigma'});\n}\n}\nreturn out;\n}\nconst CONTROL_RULE_SETS=Object.freeze(['westernElectric','nelson']);\nfunction controlViolations(ordered,limits,ruleSet='westernElectric'){\nreturn String(ruleSet)==='nelson'\n?nelsonViolations(ordered,limits)\n:westernElectricViolations(ordered,limits);\n}\nfunction countOutside(values,low,high){\nlet count=0;\nfor(let i=0;i<values.length;i++){\nif(values[i]<low||values[i]>high)count++;\n}\nreturn count;\n}\nfunction histogram(sorted,q1,q3,cap=20){\nconst n=sorted.length;\nif(!n)return[];\nconst min=sorted[0];\nconst max=sorted[n-1];\nif(max===min)return[{from:min,to:max,count:n}];\nconst iqr=q3-q1;\nconst fence=1.5*iqr;\nlet lo=iqr>0?Math.max(min,q1-fence):min;\nlet hi=iqr>0?Math.min(max,q3+fence):max;\nif(!(hi>lo)){lo=min;hi=max;}\nconst width=iqr>0?(2*iqr)/Math.cbrt(n):(hi-lo)/(Math.ceil(Math.log2(n))+1);\nconst count=width>0\n?Math.min(cap,Math.max(1,Math.ceil((hi-lo)/width)))\n:1;\nconst step=(hi-lo)/count;\nconst bins=[];\nfor(let i=0;i<count;i++){\nbins.push({from:lo+i*step,to:lo+(i+1)*step,count:0});\n}\nfor(let i=0;i<n;i++){\nconst at=Math.min(count-1,Math.max(0,Math.floor((sorted[i]-lo)/step)));\nbins[at].count++;\n}\nbins[0].from=min;\nbins[count-1].to=max;\nreturn bins;\n}\nconst DEFAULT_CONFIDENCE=0.95;\nfunction level(conf){\nconst c=Number(conf);\nreturn Number.isFinite(c)&&c>0&&c<1?c:DEFAULT_CONFIDENCE;\n}\nfunction meanInterval(values,conf=DEFAULT_CONFIDENCE){\nconst n=values.length;\nif(n<2)return null;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=values[i];\nconst mean=sum/n;\nlet ss=0;\nfor(let i=0;i<n;i++){const d=values[i]-mean;ss+=d*d;}\nconst sd=Math.sqrt(ss/(n-1));\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,n-1);\nconst margin=(t*sd)/Math.sqrt(n);\nreturn{mean,lower:mean-margin,upper:mean+margin,margin,n,confidence:c};\n}\nfunction proportionInterval(successes,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(successes);\nconst total=Number(n);\nif(!(total>0)||!(k>=0)||k>total)return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst p=k/total;\nconst z2=z*z;\nconst denominator=1+z2/total;\nconst centre=(p+z2/(2*total))/denominator;\nconst half=(z/denominator)\n*Math.sqrt((p*(1-p))/total+z2/(4*total*total));\nreturn{\nproportion:p,\nlower:Math.max(0,centre-half),\nupper:Math.min(1,centre+half),\nn:total,\nconfidence:c,\n};\n}\nfunction slopeInterval(fit,conf=DEFAULT_CONFIDENCE){\nif(!fit||!(fit.n>2)||!Number.isFinite(fit.stdError))return null;\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,fit.n-2);\nconst margin=t*fit.stdError;\nreturn{\nslope:fit.slope,\nlower:fit.slope-margin,\nupper:fit.slope+margin,\nmargin,\nconfidence:c,\n};\n}\nfunction capabilityInterval(index,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(index);\nconst count=Number(n);\nif(!Number.isFinite(k)||!(count>1))return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst margin=z*Math.sqrt(1/(9*count)+(k*k)/(2*(count-1)));\nreturn{index:k,lower:k-margin,upper:k+margin,margin,n:count,confidence:c};\n}\n});\n__def(\"packages/core/src/compute/total.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return TOTAL_FNS;}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return TOTAL_LABELS;}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return totalLabel;}});\nObject.defineProperty(__exports,\"aggregatesFor\",{enumerable:true,get:function(){return aggregatesFor;}});\nObject.defineProperty(__exports,\"aggregateAllowed\",{enumerable:true,get:function(){return aggregateAllowed;}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return collectValues;}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return total;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isFunction=__m0[\"isFunction\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m1[\"presenceReader\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst valueReader=__m1[\"valueReader\"];\nconst __m2=__req(\"packages/core/src/compute/statistics.js\");\nconst STAT_FNS=__m2[\"STAT_FNS\"];\nconst STAT_LABELS=__m2[\"STAT_LABELS\"];\nfunction isNumericBacking(handle){\nreturn!!handle&&(handle.kind==='float64'||handle.kind==='int32');\n}\nfunction sum(handle,indices){\nconst n=indices.length;\nlet acc=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(!Number.isNaN(v))acc+=v;\n}\nreturn acc;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1){\nconst v=values[row];\nif(!Number.isNaN(v))acc+=v;\n}\n}\nreturn acc;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=numberOf(read(indices[i]));\nif(v!==null)acc+=v;\n}\nreturn acc;\n}\nsum.kernel=true;\nfunction countValues(handle,indices){\nconst n=indices.length;\nlet count=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++)if(!Number.isNaN(values[indices[i]]))count++;\nreturn count;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1&&!Number.isNaN(values[row]))count++;\n}\nreturn count;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v!==null&&v!==undefined&&!(typeof v==='number'&&Number.isNaN(v)))count++;\n}\nreturn count;\n}\ncountValues.kernel=true;\nfunction count(handle,indices){\nreturn indices.length;\n}\ncount.kernel=true;\nfunction avg(handle,indices){\nconst values=countValues(handle,indices);\nif(values===0)return null;\nreturn sum(handle,indices)/values;\n}\navg.kernel=true;\nfunction extreme(handle,indices,direction,locale){\nconst n=indices.length;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nlet best=null;\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===0)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nconst read=valueReader(handle);\nconst cmp=valueComparator(locale);\nlet best=null;\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v)))continue;\nif(best===null||(direction<0?cmp(v,best)<0:cmp(v,best)>0))best=v;\n}\nreturn best;\n}\nfunction min(handle,indices,ctx){\nreturn extreme(handle,indices,-1,ctx&&ctx.locale);\n}\nmin.kernel=true;\nfunction max(handle,indices,ctx){\nreturn extreme(handle,indices,1,ctx&&ctx.locale);\n}\nmax.kernel=true;\nfunction first(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[0]);\n}\nfirst.kernel=true;\nfunction last(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[indices.length-1]);\n}\nlast.kernel=true;\nfunction numberOf(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nconst TOTAL_FNS={\nsum,min,max,avg,count,first,last,countValues,\n...STAT_FNS,\n};\nconst TOTAL_LABELS=Object.freeze({\n...STAT_LABELS,\nsum:'Sum',\navg:'Average',\nmin:'Min',\nmax:'Max',\ncount:'Count',\ncountValues:'Count of values',\nfirst:'First',\nlast:'Last',\n});\nfunction totalLabel(fn){\nif(!fn)return'';\nif(typeof fn==='string')return TOTAL_LABELS[fn]||fn;\nreturn'Total';\n}\nconst CHOOSER_ORDER=Object.freeze([\n'sum','avg','min','max','count','countValues','first','last',\n]);\nfunction aggregatesFor(column){\nconst supported=column&&column.dataType\n&&column.dataType.totals&&column.dataType.totals.supported;\nif(Array.isArray(supported))return supported.slice();\nconst named=CHOOSER_ORDER.filter((name)=>name in TOTAL_FNS);\nfor(const name of Object.keys(TOTAL_FNS))if(!named.includes(name))named.push(name);\nreturn named;\n}\nfunction aggregateAllowed(column,name){\nif(typeof name!=='string')return true;\nreturn aggregatesFor(column).includes(name);\n}\nfunction collectValues(handle,indices){\nconst read=valueReader(handle);\nconst out=[];\nfor(let i=0;i<indices.length;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined)continue;\nout.push(v);\n}\nreturn out;\n}\nfunction total(handle,indices,fn,ctx){\nconst list=indices||[];\nif(typeof fn==='string'){\nconst kernel=TOTAL_FNS[fn];\nif(!kernel){\nwarnOnce(`total:${fn}`,`unknown total function \"${fn}\"; register it in config.totalFns`);\nreturn null;\n}\nreturn kernel(handle,list,ctx);\n}\nif(isFunction(fn)){\nif(fn.kernel===true)return fn(handle,list,ctx);\nreturn fn(collectValues(handle,list),ctx||{});\n}\nreturn null;\n}\n});\n__def(\"packages/core/src/compute/pivot.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return KEY_DELIMITER;}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return DEFAULT_PATH_SEPARATOR;}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return DEFAULT_MAX_COLUMNS;}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return pivotKey;}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return joinPath;}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return resolvePivotKeys;}});\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return pivot;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nconst packKeys=__m2[\"packKeys\"];\nconst __m3=__req(\"packages/core/src/compute/total.js\");\nconst total=__m3[\"total\"];\nconst KEY_DELIMITER='|';\nconst DEFAULT_PATH_SEPARATOR='/';\nconst DEFAULT_MAX_COLUMNS=2000;\nfunction pivotKey(groupPath,pivotPath,colId){\nreturn`${groupPath}${KEY_DELIMITER}${pivotPath}${KEY_DELIMITER}${colId}`;\n}\nfunction joinPath(parts,separator){\nlet out='';\nfor(let i=0;i<parts.length;i++){\nconst v=parts[i];\nout+=(i===0?'':separator)+(v===null||v===undefined?'':String(v));\n}\nreturn out;\n}\nfunction resolvePivotKeys(handles,order,opts={}){\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst n=order.length;\nconst{keyOf,readers}=packKeys(handles,order,0);\nconst seen=new Map();\nconst tuples=[];\nconst rawKeys=[];\nfor(let i=0;i<n;i++){\nconst row=order[i];\nconst key=keyOf(row);\nif(seen.has(key))continue;\nseen.set(key,tuples.length);\nrawKeys.push(key);\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\ntuples.push(tuple);\n}\nconst cmp=valueComparator(opts.locale);\nconst rank=tuples.map((_,i)=>i);\nrank.sort((a,b)=>{\nconst ta=tuples[a];\nconst tb=tuples[b];\nfor(let j=0;j<ta.length;j++){\nconst c=compareNullable(ta[j],tb[j],cmp);\nif(c!==0)return c;\n}\nreturn a-b;\n});\nconst keys=new Array(rank.length);\nconst paths=new Array(rank.length);\nconst idByKey=new Map();\nfor(let position=0;position<rank.length;position++){\nconst from=rank[position];\nkeys[position]=tuples[from];\npaths[position]=joinPath(tuples[from],separator);\nidByKey.set(rawKeys[from],position);\n}\nconst idOf=(row)=>{\nconst id=idByKey.get(keyOf(row));\nreturn id===undefined?-1:id;\n};\nreturn{keys,paths,idOf};\n}\nfunction compareNullable(a,b,cmp){\nconst na=a===null||a===undefined;\nconst nb=b===null||b===undefined;\nif(na||nb)return na&&nb?0:na?1:-1;\nreturn cmp(a,b);\n}\nfunction resolveValueColumns(opts){\nconst declared=opts.values||opts.totals||[];\nif(declared.length&&typeof declared[0]==='object'&&declared[0]!==null){\nreturn declared.filter((entry)=>entry&&entry.handle);\n}\nconst resolve=typeof opts.handle==='function'?opts.handle:null;\nif(!resolve){\nif(declared.length){\nwarnOnce('pivot:handles',\n'pivot was given total column ids but no handle(colId) resolver, so no cell values were reduced. Pass values: [{ colId, handle, fn }] or opts.handle.');\n}\nreturn[];\n}\nconst totalOf=typeof opts.totalOf==='function'?opts.totalOf:null;\nconst out=[];\nfor(const colId of declared){\nconst handle=resolve(colId);\nif(!handle)continue;\nout.push({colId,handle,fn:totalOf?totalOf(colId):'sum'});\n}\nreturn out;\n}\nfunction normaliseArgs(a,b,c){\nif(Array.isArray(a)){\nconst opts=c||{};\nreturn{...opts,pivotHandles:a,order:b||null,groups:opts.groups||null};\n}\nreturn a||{};\n}\nfunction pivot(input,orderArg,optsArg){\nconst opts=normaliseArgs(input,orderArg,optsArg);\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst valueColumns=resolveValueColumns(opts);\nconst maxColumns=opts.maxColumns===undefined?DEFAULT_MAX_COLUMNS:opts.maxColumns;\nconst groups=opts.groups&&opts.groups.buckets?opts.groups:null;\nconst buckets=groups?groups.buckets:[opts.order||new Uint32Array(0)];\nconst groupPaths=opts.groupPaths\n||(groups?groups.keys.map((tuple)=>joinPath(tuple,separator)):['']);\nconst scope=concatIndices(buckets);\nconst{keys,paths,idOf}=resolvePivotKeys(opts.pivotHandles||[],scope,opts);\nconst columns=paths.length*Math.max(1,valueColumns.length);\nconst fields=derivedFields(paths,valueColumns,separator);\nif(maxColumns&&columns>maxColumns){\nconst empty=new Map();\nreturn{\nkeys,\npaths,\nfields,\ngroupPaths,\ncolumns,\nvalues:empty,\ncells:empty,\nerror:{\ncode:'pivot-max-columns',\nmessage:`[lattice] pivot would generate ${columns} columns, above pivot.maxColumns of ${maxColumns}. Narrow the pivot columns or raise the limit.`,\ncolumns,\nmaxColumns,\n},\n};\n}\nconst cells=new Map();\nconst keyCount=paths.length;\nfor(let g=0;g<buckets.length;g++){\nconst bucket=buckets[g];\nconst groupPath=groupPaths[g]===undefined?'':groupPaths[g];\nconst n=bucket.length;\nif(n===0)continue;\nconst ids=new Int32Array(n);\nconst counts=new Uint32Array(keyCount+1);\nfor(let i=0;i<n;i++){\nconst id=idOf(bucket[i]);\nids[i]=id;\nif(id>=0)counts[id+1]++;\n}\nfor(let k=0;k<keyCount;k++)counts[k+1]+=counts[k];\nconst scattered=new Uint32Array(n);\nconst cursor=counts.slice(0,keyCount);\nfor(let i=0;i<n;i++){\nconst id=ids[i];\nif(id>=0)scattered[cursor[id]++]=bucket[i];\n}\nfor(let k=0;k<keyCount;k++){\nconst from=counts[k];\nconst to=counts[k+1];\nif(to===from)continue;\nconst slice=scattered.subarray(from,to);\nfor(let c=0;c<valueColumns.length;c++){\nconst column=valueColumns[c];\nconst result=total(column.handle,slice,column.fn,opts.totalContext||{locale:opts.locale});\ncells.set(pivotKey(groupPath,paths[k],column.colId),result);\n}\n}\n}\nreturn{keys,paths,fields,groupPaths,columns,values:cells,cells,error:null};\n}\nfunction derivedFields(paths,valueColumns,separator){\nif(valueColumns.length===0)return paths.slice();\nconst out=[];\nfor(const path of paths){\nfor(const column of valueColumns)out.push(`${path}${separator}${column.colId}`);\n}\nreturn out;\n}\nfunction concatIndices(buckets){\nif(buckets.length===1)return buckets[0]||new Uint32Array(0);\nlet n=0;\nfor(const b of buckets)n+=b?b.length:0;\nconst out=new Uint32Array(n);\nlet at=0;\nfor(const b of buckets){\nif(!b||b.length===0)continue;\nout.set(b,at);\nat+=b.length;\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/compute/reference.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return referenceValue;}});\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return referenceSort;}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return referenceFilter;}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return referencePasses;}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return referenceGroup;}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return referenceTotal;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst getPath=__m0[\"getPath\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst isMissing=__m1[\"isMissing\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/filter.js\");\nconst testValue=__m2[\"testValue\"];\nconst KEY_SEPARATOR=String.fromCharCode(0x1f);\nconst NULL_MARKER=String.fromCharCode(0x00);\nfunction referenceValue(row,col){\nconst v=col.includes('.')?getPath(row,col):(row==null?undefined:row[col]);\nreturn v===undefined?null:v;\n}\nfunction referenceSort(rows,entries,opts={}){\nconst list=entries||[];\nlet order=rows.map((_,i)=>i);\nif(list.length===0)return order;\nfor(let e=list.length-1;e>=0;e--){\norder=referenceSortOne(rows,order,list[e],opts);\n}\nreturn order;\n}\nfunction referenceSortOne(rows,order,entry,opts){\nconst locale=entry.locale!==undefined?entry.locale:opts.locale;\nconst base=valueComparator(locale);\nconst descending=entry.descending!==undefined?!!entry.descending:entry.dir==='desc';\nconst present=[];\nconst absent=[];\nfor(const i of order){\nconst v=referenceValue(rows[i],entry.col);\nif(isMissing(v))absent.push(i);else present.push(i);\n}\nconst position=new Map();\nfor(let p=0;p<present.length;p++)position.set(present[p],p);\nconst compare=(a,b)=>{\nconst va=referenceValue(rows[a],entry.col);\nconst vb=referenceValue(rows[b],entry.col);\nlet c;\nif(typeof entry.compare==='function'){\nc=entry.compare(va,vb,rows[a],rows[b],descending);\nif(descending)c=-c;\n}else{\nc=descending?base(vb,va):base(va,vb);\n}\nreturn c!==0?c:position.get(a)-position.get(b);\n};\npresent.sort(compare);\nreturn entry.nullsFirst?absent.concat(present):present.concat(absent);\n}\nfunction referenceFilter(rows,filters,opts={}){\nconst out=[];\nfor(let i=0;i<rows.length;i++){\nif(referencePasses(rows[i],filters,opts,i))out.push(i);\n}\nreturn out;\n}\nfunction referencePasses(row,node,opts,index){\nif(!node)return true;\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nif(children.length===0)return true;\nif(node.op==='or')return children.some((c)=>referencePasses(row,c,opts,index));\nconst all=children.every((c)=>referencePasses(row,c,opts,index));\nreturn node.op==='not'?!all:all;\n}\nif(node.col===undefined&&typeof opts.custom==='function')return!!opts.custom(node,row,index);\nreturn testValue(referenceValue(row,node.col),node,opts.locale);\n}\nfunction referenceGroup(rows,cols,order){\nconst source=order||rows.map((_,i)=>i);\nconst seen=new Map();\nconst keys=[];\nconst buckets=[];\nfor(const i of source){\nconst tuple=cols.map((col)=>referenceValue(rows[i],col));\nconst key=tuple\n.map((v)=>(v===null||v===undefined?NULL_MARKER:String(v)))\n.join(KEY_SEPARATOR);\nlet at=seen.get(key);\nif(at===undefined){\nat=keys.length;\nseen.set(key,at);\nkeys.push(tuple);\nbuckets.push([]);\n}\nbuckets[at].push(i);\n}\nreturn{keys,buckets};\n}\nfunction referenceTotal(values,fn,opts={}){\nconst cmp=valueComparator(opts.locale);\nconst live=values.filter((v)=>!isMissing(v));\nconst numbers=live.map(toNumberOrNull).filter((v)=>v!==null);\nswitch(fn){\ncase'count':return values.length;\ncase'countValues':return live.length;\ncase'sum':return numbers.reduce((a,b)=>a+b,0);\ncase'avg':return live.length===0?null:numbers.reduce((a,b)=>a+b,0)/live.length;\ncase'min':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)<0?b:a));\ncase'max':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)>0?b:a));\ncase'first':return values.length===0?null:normaliseNull(values[0]);\ncase'last':return values.length===0?null:normaliseNull(values[values.length-1]);\ndefault:return null;\n}\n}\nfunction toNumberOrNull(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nfunction normaliseNull(v){\nreturn v===undefined?null:v;\n}\n});\n__def(\"packages/core/src/compute/index.js\",function(__exports,__req){\n'use strict';\nconst __m0=__req(\"packages/core/src/compute/sort.js\");\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return __m0[\"sortColumn\"];}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return __m0[\"sortMulti\"];}});\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return __m0[\"radixSortFloat64\"];}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return __m0[\"radixSortInt32\"];}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return __m0[\"rankSortDictionary\"];}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return __m0[\"mergeSortComparator\"];}});\nconst __m1=__req(\"packages/core/src/compute/filter.js\");\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return __m1[\"evaluateFilters\"];}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return __m1[\"evaluateCondition\"];}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return __m1[\"compact\"];}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return __m1[\"testValue\"];}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return __m1[\"compilePredicate\"];}});\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return __m1[\"releaseMask\"];}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return __m1[\"pruneColumn\"];}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return __m1[\"mentionsColumn\"];}});\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return __m2[\"groupByColumns\"];}});\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return __m2[\"packKeys\"];}});\nconst __m3=__req(\"packages/core/src/compute/facet.js\");\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return __m3[\"facet\"];}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return __m3[\"computeBounds\"];}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return __m3[\"countInto\"];}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return __m3[\"bucketOf\"];}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return __m3[\"facetKind\"];}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return __m3[\"cardinalityOf\"];}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return __m3[\"pickGranularity\"];}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return __m3[\"floorTo\"];}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return __m3[\"advance\"];}});\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return __m3[\"STRATEGIES\"];}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return __m3[\"GRANULARITIES\"];}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return __m3[\"DEFAULT_BUCKETS\"];}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return __m3[\"DEFAULT_CARDINALITY_LIMIT\"];}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return __m3[\"QUANTILE_SAMPLE\"];}});\nconst __m4=__req(\"packages/core/src/compute/total.js\");\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return __m4[\"TOTAL_FNS\"];}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return __m4[\"TOTAL_LABELS\"];}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return __m4[\"totalLabel\"];}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return __m4[\"total\"];}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return __m4[\"collectValues\"];}});\nconst __m5=__req(\"packages/core/src/compute/pivot.js\");\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return __m5[\"pivot\"];}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return __m5[\"resolvePivotKeys\"];}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return __m5[\"pivotKey\"];}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return __m5[\"joinPath\"];}});\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return __m5[\"KEY_DELIMITER\"];}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return __m5[\"DEFAULT_PATH_SEPARATOR\"];}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return __m5[\"DEFAULT_MAX_COLUMNS\"];}});\nconst __m6=__req(\"packages/core/src/compute/reference.js\");\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return __m6[\"referenceSort\"];}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return __m6[\"referenceFilter\"];}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return __m6[\"referenceGroup\"];}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return __m6[\"referenceTotal\"];}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return __m6[\"referencePasses\"];}});\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return __m6[\"referenceValue\"];}});\nconst __m7=__req(\"packages/core/src/compute/handle.js\");\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return __m7[\"identity\"];}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return __m7[\"rowCount\"];}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return __m7[\"presenceReader\"];}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return __m7[\"bitReader\"];}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return __m7[\"valueReader\"];}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return __m7[\"valueComparator\"];}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return __m7[\"numericTotalOrder\"];}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return __m7[\"dictRanks\"];}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return __m7[\"dictSize\"];}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return __m7[\"dictValue\"];}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return __m7[\"multiValue\"];}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return __m7[\"isMissing\"];}});\n});\n__def(\"packages/worker/src/kernel.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"loadCompute\",{enumerable:true,get:function(){return loadCompute;}});\nObject.defineProperty(__exports,\"setCompute\",{enumerable:true,get:function(){return setCompute;}});\nObject.defineProperty(__exports,\"dispatch\",{enumerable:true,get:function(){return dispatch;}});\nObject.defineProperty(__exports,\"handleMessage\",{enumerable:true,get:function(){return handleMessage;}});\nObject.defineProperty(__exports,\"installKernel\",{enumerable:true,get:function(){return installKernel;}});\nconst __m0=__req(\"packages/worker/src/transport.js\");\nconst PROTOCOL=__m0[\"PROTOCOL\"];\nconst OPS=__m0[\"OPS\"];\nconst CONTROL=__m0[\"CONTROL\"];\nconst ERRORS=__m0[\"ERRORS\"];\nconst unpackHandle=__m0[\"unpackHandle\"];\nconst unpackHandles=__m0[\"unpackHandles\"];\nconst createMaskPool=__m0[\"createMaskPool\"];\nconst collectTransfers=__m0[\"collectTransfers\"];\nconst __m1=__req(\"packages/core/src/store/columnpack.js\");\nconst packChunk=__m1[\"packChunk\"];\nconst packedTransfers=__m1[\"packedTransfers\"];\nlet computeModule=null;\nlet computePromise=null;\nlet computeError=null;\nasync function loadCompute(loader){\nif(computeModule)return computeModule;\nif(!computePromise){\nconst load=loader||(()=>Promise.resolve(__req(\"packages/core/src/compute/index.js\")));\ncomputePromise=Promise.resolve()\n.then(load)\n.then((mod)=>{computeModule=mod;return mod;})\n.catch((err)=>{\ncomputeError=err;\ncomputeModule=null;\nreturn null;\n});\n}\nreturn computePromise;\n}\nfunction setCompute(mod){\ncomputeModule=mod;\ncomputePromise=mod?Promise.resolve(mod):null;\ncomputeError=mod?null:computeError;\n}\nfunction filterContext(handles,count,locale){\nconst byId=new Map();\nfor(const h of handles)if(h)byId.set(h.id,h);\nreturn{\nhandle(colId){return byId.get(colId);},\ncount,\npool:createMaskPool(),\nlocale,\n};\n}\nfunction dispatch(request,compute){\nconst{op,args}=request;\nif(op===OPS.COLUMNIZE){\nreturn packChunk(args.schema||[],args.rows||[],args.opts||{});\n}\nconst fn=compute[op];\nif(typeof fn!=='function'){\nconst err=new Error(`[lattice] compute kernel '${op}' is not exported`);\n(err).code=ERRORS.NO_KERNEL;\nthrow err;\n}\nswitch(op){\ncase OPS.SORT_COLUMN:\nreturn fn(unpackHandle(args.handle),args.order??null,args.opts||{});\ncase OPS.SORT_MULTI:{\nconst handles=unpackHandles(args.handles||[]);\nconst entries=(args.entries||[]).map((e)=>({\n...e,\nhandle:handles[e.index],\n}));\nreturn fn(handles,entries,args.order??null);\n}\ncase OPS.EVALUATE_FILTERS:\nreturn fn(args.filters,filterContext(unpackHandles(args.handles||[]),args.count,args.locale));\ncase OPS.COMPACT:\nreturn fn(args.mask,args.count,undefined);\ncase OPS.GROUP_BY_COLUMNS:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.TOTAL:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.fn);\ncase OPS.PIVOT:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.FACET:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.count,args.opts||{});\ndefault:{\nconst err=new Error(`[lattice] unknown worker op '${op}'`);\n(err).code=ERRORS.PROTOCOL;\nthrow err;\n}\n}\n}\nasync function handleMessage(message,opts={}){\nif(!message||message.lattice!==PROTOCOL)return null;\nconst{id,op}=message;\nif(op===CONTROL.CANCEL){\nopts.cancelled?.add(message.target);\nreturn null;\n}\nif(op===CONTROL.PING){\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result:'pong'},transfer:[]};\n}\nif(op===OPS.COLUMNIZE){\nif(opts.cancelled?.has(id)){opts.cancelled.delete(id);return null;}\ntry{\nconst result=packChunk(message.args.schema||[],message.args.rows||[],message.args.opts||{});\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:packedTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{lattice:PROTOCOL,id,ok:false,error:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack}},\ntransfer:[],\n};\n}\n}\nconst compute=await loadCompute(opts.loader);\nif(!compute){\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{\ncode:ERRORS.NO_COMPUTE,\nmessage:`[lattice] compute kernels unavailable in worker: ${computeError?computeError.message:'module not found'}`,\n},\n},\ntransfer:[],\n};\n}\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\ntry{\nconst result=dispatch(message,compute);\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:collectTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack},\n},\ntransfer:[],\n};\n}\n}\nfunction installKernel(scope,opts={}){\nconst cancelled=new Set();\nconst onMessage=async(event)=>{\nconst outcome=await handleMessage(event.data,{loader:opts.loader,cancelled});\nif(!outcome)return;\nscope.postMessage(outcome.reply,outcome.transfer);\n};\nscope.addEventListener('message',onMessage);\nloadCompute(opts.loader).then((mod)=>{\nscope.postMessage({lattice:PROTOCOL,id:0,op:CONTROL.READY,compute:!!mod});\n});\nreturn()=>scope.removeEventListener('message',onMessage);\n}\n});\nvar __entry=__req(\"packages/worker/src/kernel.js\");\nroot[\"__latticeKernel\"]=__entry;\n})(typeof globalThis!=='undefined'?globalThis:this);\n__latticeKernel.installKernel(self);\n",{type:'classic'});
69196
+ __req("packages/worker/src/inline.js").setWorkerSource("(function(root){\n'use strict';\nvar __mods=Object.create(null);\nvar __cache=Object.create(null);\nfunction __def(id,fn){__mods[id]=fn;}\nfunction __req(id){\nvar hit=__cache[id];\nif(hit)return hit;\nvar exports=Object.create(null);\n__cache[id]=exports;\nvar fn=__mods[id];\nif(!fn)throw new Error('[lattice] missing module: '+id);\nfn(exports,__req);\nreturn exports;\n}\n__def(\"packages/core/src/internal/util.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"VERSION\",{enumerable:true,get:function(){return VERSION;}});\nObject.defineProperty(__exports,\"reportedWarnings\",{enumerable:true,get:function(){return reportedWarnings;}});\nObject.defineProperty(__exports,\"warnOnce\",{enumerable:true,get:function(){return warnOnce;}});\nObject.defineProperty(__exports,\"infoOnce\",{enumerable:true,get:function(){return infoOnce;}});\nObject.defineProperty(__exports,\"resetWarnings\",{enumerable:true,get:function(){return resetWarnings;}});\nObject.defineProperty(__exports,\"fail\",{enumerable:true,get:function(){return fail;}});\nObject.defineProperty(__exports,\"invariant\",{enumerable:true,get:function(){return invariant;}});\nObject.defineProperty(__exports,\"DEV\",{enumerable:true,get:function(){return DEV;}});\nObject.defineProperty(__exports,\"isObject\",{enumerable:true,get:function(){return isObject;}});\nObject.defineProperty(__exports,\"isFunction\",{enumerable:true,get:function(){return isFunction;}});\nObject.defineProperty(__exports,\"isNil\",{enumerable:true,get:function(){return isNil;}});\nObject.defineProperty(__exports,\"isBlank\",{enumerable:true,get:function(){return isBlank;}});\nObject.defineProperty(__exports,\"isCtor\",{enumerable:true,get:function(){return isCtor;}});\nObject.defineProperty(__exports,\"pathGetter\",{enumerable:true,get:function(){return pathGetter;}});\nObject.defineProperty(__exports,\"pathSetter\",{enumerable:true,get:function(){return pathSetter;}});\nObject.defineProperty(__exports,\"getPath\",{enumerable:true,get:function(){return getPath;}});\nObject.defineProperty(__exports,\"setPath\",{enumerable:true,get:function(){return setPath;}});\nObject.defineProperty(__exports,\"humanise\",{enumerable:true,get:function(){return humanise;}});\nObject.defineProperty(__exports,\"escapeHtml\",{enumerable:true,get:function(){return escapeHtml;}});\nObject.defineProperty(__exports,\"titleCase\",{enumerable:true,get:function(){return titleCase;}});\nObject.defineProperty(__exports,\"expand\",{enumerable:true,get:function(){return expand;}});\nObject.defineProperty(__exports,\"toArray\",{enumerable:true,get:function(){return toArray;}});\nObject.defineProperty(__exports,\"merge\",{enumerable:true,get:function(){return merge;}});\nObject.defineProperty(__exports,\"mergeRow\",{enumerable:true,get:function(){return mergeRow;}});\nObject.defineProperty(__exports,\"Lru\",{enumerable:true,get:function(){return Lru;}});\nObject.defineProperty(__exports,\"collator\",{enumerable:true,get:function(){return collator;}});\nObject.defineProperty(__exports,\"defaultCompare\",{enumerable:true,get:function(){return defaultCompare;}});\nObject.defineProperty(__exports,\"now\",{enumerable:true,get:function(){return now;}});\nObject.defineProperty(__exports,\"nextFrame\",{enumerable:true,get:function(){return nextFrame;}});\nObject.defineProperty(__exports,\"cancelFrame\",{enumerable:true,get:function(){return cancelFrame;}});\nObject.defineProperty(__exports,\"frameBatched\",{enumerable:true,get:function(){return frameBatched;}});\nObject.defineProperty(__exports,\"settleDebounce\",{enumerable:true,get:function(){return settleDebounce;}});\nObject.defineProperty(__exports,\"whenIdle\",{enumerable:true,get:function(){return whenIdle;}});\nObject.defineProperty(__exports,\"uid\",{enumerable:true,get:function(){return uid;}});\nconst STAMPED_VERSION=\"1.18.0\";\nasync function resolveVersion(){\nif(STAMPED_VERSION!=='0.0.0-source')return STAMPED_VERSION;\ntry{\nif(typeof process==='undefined'||!process.versions||!process.versions.node){\nreturn STAMPED_VERSION;\n}\nconst mod=await import('node:'+'module');\nconst req=mod.createRequire((typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst fs=req('node:'+'fs');\nconst url=new URL('../../../../package.json',(typeof document!=='undefined'&&document.currentScript?document.currentScript.src:''));\nconst text=fs.readFileSync(url,'utf8');\nreturn JSON.parse(text).version||STAMPED_VERSION;\n}catch{\nreturn STAMPED_VERSION;\n}\n}\nconst VERSION=\"1.18.0\";\nconst warned=new Set();\nconst reported=[];\nconst REPORT_LIMIT=500;\nfunction record(key,level,message){\nreported.push({\nkey,\nlevel,\nmessage:message.map((m)=>(typeof m==='string'?m:safeString(m))).join(' '),\nat:Date.now(),\n});\nif(reported.length>REPORT_LIMIT)reported.shift();\n}\nfunction safeString(value){\nif(value instanceof Error)return value.message;\ntry{return JSON.stringify(value);}catch{return String(value);}\n}\nfunction reportedWarnings(){return reported.map((r)=>({...r}));}\nfunction warnOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'warn',message);\nconsole.warn('[lattice]',...message);\n}\nfunction infoOnce(key,...message){\nif(warned.has(key))return;\nwarned.add(key);\nrecord(key,'info',message);\nconsole.info('[lattice]',...message);\n}\nfunction resetWarnings(){\nwarned.clear();\nreported.length=0;\n}\nfunction fail(message,extra){\nconst err=new Error(`[lattice] ${message}`);\nif(extra!==undefined)err.cause=extra;\nthrow err;\n}\nfunction invariant(condition,message){\nif(!condition)fail(message);\n}\nconst DEV=(()=>{\ntry{\nreturn!(typeof process!=='undefined'&&process.env\n&&process.env.NODE_ENV==='production');\n}catch{\nreturn true;\n}\n})();\nfunction isObject(v){\nreturn v!==null&&typeof v==='object'&&!Array.isArray(v);\n}\nfunction isFunction(v){\nreturn typeof v==='function';\n}\nfunction isNil(v){\nreturn v===null||v===undefined;\n}\nfunction isBlank(v){\nreturn v===null||v===undefined||v==='';\n}\nfunction isCtor(v){\nif(typeof v!=='function')return false;\nif(/^class[\\s{]/.test(Function.prototype.toString.call(v)))return true;\nreturn!!(v.prototype&&Object.getOwnPropertyNames(v.prototype).length>1);\n}\nconst pathCache=new Map();\nfunction pathGetter(path){\nlet fn=pathCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o)=>(o==null?undefined:o[path]);\n}else{\nconst parts=path.split('.');\nconst n=parts.length;\nfn=(o)=>{\nlet cur=o;\nfor(let i=0;i<n;i++){\nif(cur==null)return undefined;\ncur=cur[parts[i]];\n}\nreturn cur;\n};\n}\npathCache.set(path,fn);\nreturn fn;\n}\nconst setterCache=new Map();\nfunction pathSetter(path){\nlet fn=setterCache.get(path);\nif(fn)return fn;\nif(!path.includes('.')){\nfn=(o,v)=>{if(o!=null)o[path]=v;};\n}else{\nconst parts=path.split('.');\nconst last=parts.length-1;\nfn=(o,v)=>{\nlet cur=o;\nfor(let i=0;i<last;i++){\nif(cur==null)return;\nconst k=parts[i];\nif(cur[k]==null)cur[k]={};\ncur=cur[k];\n}\nif(cur!=null)cur[parts[last]]=v;\n};\n}\nsetterCache.set(path,fn);\nreturn fn;\n}\nfunction getPath(obj,path){\nreturn pathGetter(path)(obj);\n}\nfunction setPath(obj,path,value){\npathSetter(path)(obj,value);\n}\nfunction humanise(field){\nif(!field)return'';\nconst leaf=field.includes('.')?field.slice(field.lastIndexOf('.')+1):field;\nreturn leaf\n.replace(/[_-]+/g,' ')\n.replace(/([a-z0-9])([A-Z])/g,'$1 $2')\n.replace(/([A-Z]+)([A-Z][a-z])/g,'$1 $2')\n.replace(/\\s+/g,' ')\n.trim()\n.replace(/^./,(c)=>c.toUpperCase());\n}\nconst ESCAPES={'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'};\nfunction escapeHtml(s){\nconst str=s==null?'':String(s);\nreturn/[&<>\"']/.test(str)?str.replace(/[&<>\"']/g,(c)=>ESCAPES[c]):str;\n}\nfunction titleCase(s){\nreturn String(s).replace(/\\w\\S*/g,(t)=>t[0].toUpperCase()+t.slice(1).toLowerCase());\n}\nfunction expand(value,key,whenTrue){\nif(value===undefined)return undefined;\nif(value===true)return{enabled:true,...whenTrue};\nif(value===false)return{enabled:false};\nif(isObject(value))return value;\nreturn{[key]:value,enabled:true};\n}\nfunction toArray(v){\nif(v===undefined||v===null)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction merge(a,b){\nif(!isObject(a))return isObject(b)?{...b}:b;\nif(!isObject(b))return b===undefined?a:b;\nconst out={...a};\nfor(const k of Object.keys(b)){\nconst bv=b[k];\nif(bv===undefined)continue;\nout[k]=isObject(bv)&&isObject(out[k])?merge(out[k],bv):bv;\n}\nreturn out;\n}\nfunction mergeRow(previous,patch){\nif(!isObject(previous)||!isObject(patch)||previous===patch)return patch;\nconst out=Object.create(Object.getPrototypeOf(previous));\nObject.assign(out,previous,patch);\nreturn out;\n}\nclass Lru{\n#max;\n#map=new Map();\n#onEvict;\nconstructor(max=256,onEvict=null){\nthis.#max=max;\nthis.#onEvict=onEvict;\n}\nget size(){\nreturn this.#map.size;\n}\nget max(){\nreturn this.#max;\n}\nset max(v){\nthis.#max=v;\nthis.#trim();\n}\nhas(k){\nreturn this.#map.has(k);\n}\nget(k){\nconst m=this.#map;\nif(!m.has(k))return undefined;\nconst v=m.get(k);\nm.delete(k);\nm.set(k,v);\nreturn v;\n}\npeek(k){\nreturn this.#map.get(k);\n}\nset(k,v){\nconst m=this.#map;\nif(m.has(k))m.delete(k);\nm.set(k,v);\nthis.#trim();\nreturn v;\n}\ndelete(k){\nconst v=this.#map.get(k);\nif(this.#map.delete(k)&&this.#onEvict)this.#onEvict(v,k);\nreturn v;\n}\nclear(){\nif(this.#onEvict)for(const[k,v]of this.#map)this.#onEvict(v,k);\nthis.#map.clear();\n}\nkeys(){\nreturn this.#map.keys();\n}\nvalues(){\nreturn this.#map.values();\n}\n#trim(){\nconst m=this.#map;\nwhile(m.size>this.#max){\nconst oldest=m.keys().next().value;\nconst v=m.get(oldest);\nm.delete(oldest);\nif(this.#onEvict)this.#onEvict(v,oldest);\n}\n}\n}\nconst collators=new Map();\nfunction collator(locale,opts){\nconst key=`${locale||''}|${opts?JSON.stringify(opts):''}`;\nlet c=collators.get(key);\nif(!c){\nc=new Intl.Collator(locale||undefined,{\nnumeric:true,sensitivity:'variant',...opts,\n});\ncollators.set(key,c);\n}\nreturn c;\n}\nfunction defaultCompare(a,b){\nif(a===b)return 0;\nif(a===null||a===undefined)return 1;\nif(b===null||b===undefined)return-1;\nif(typeof a==='number'&&typeof b==='number'){\nif(Number.isNaN(a))return Number.isNaN(b)?0:1;\nif(Number.isNaN(b))return-1;\nreturn a<b?-1:a>b?1:0;\n}\nconst sa=String(a);\nconst sb=String(b);\nreturn sa<sb?-1:sa>sb?1:0;\n}\nfunction now(){\nreturn typeof performance!=='undefined'&&performance.now\n?performance.now()\n:Date.now();\n}\nconst hasRaf=typeof requestAnimationFrame==='function';\nfunction nextFrame(fn){\nif(hasRaf)return requestAnimationFrame(fn);\nreturn setTimeout(()=>fn(now()),16);\n}\nfunction cancelFrame(handle){\nif(handle==null)return;\nif(hasRaf)cancelAnimationFrame(handle);\nelse clearTimeout(handle);\n}\nfunction frameBatched(fn){\nlet handle=null;\nlet lastArgs=null;\nconst run=()=>{\nhandle=null;\nconst a=lastArgs;\nlastArgs=null;\nfn(...(a||[]));\n};\nconst wrapped=(...args)=>{\nlastArgs=args;\nif(handle===null)handle=nextFrame(run);\n};\nwrapped.cancel=()=>{\ncancelFrame(handle);\nhandle=null;\nlastArgs=null;\n};\nwrapped.flush=()=>{\nif(handle!==null){\ncancelFrame(handle);\nrun();\n}\n};\nreturn wrapped;\n}\nfunction settleDebounce(fn,waitMs){\nlet timer=null;\nlet held=null;\nconst trailing=()=>{\ntimer=null;\nif(held===null)return;\nconst args=held;\nheld=null;\nfn(...args);\narm();\n};\nconst arm=()=>{\ntimer=setTimeout(trailing,waitMs);\nif(typeof timer?.unref==='function')timer.unref();\n};\nconst wrapped=(...args)=>{\nif(timer===null){\nfn(...args);\narm();\n}else{\nheld=args;\nclearTimeout(timer);\narm();\n}\n};\nwrapped.flush=()=>{\nif(timer!==null)clearTimeout(timer);\ntimer=null;\nif(held===null)return;\nconst args=held;\nheld=null;\nfn(...args);\n};\nwrapped.cancel=()=>{\nif(timer!==null)clearTimeout(timer);\ntimer=null;\nheld=null;\n};\nwrapped.pending=()=>timer!==null||held!==null;\nreturn wrapped;\n}\nfunction whenIdle(fn,timeout=50){\nif(typeof requestIdleCallback==='function'){\nreturn requestIdleCallback(fn,{timeout});\n}\nreturn setTimeout(()=>fn({timeRemaining:()=>0,didTimeout:true}),1);\n}\nlet idSeq=0;\nfunction uid(prefix='l'){\nreturn`${prefix}${(++idSeq).toString(36)}`;\n}\n});\n__def(\"packages/worker/src/transport.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"PROTOCOL\",{enumerable:true,get:function(){return PROTOCOL;}});\nObject.defineProperty(__exports,\"OPS\",{enumerable:true,get:function(){return OPS;}});\nObject.defineProperty(__exports,\"CONTROL\",{enumerable:true,get:function(){return CONTROL;}});\nObject.defineProperty(__exports,\"ERRORS\",{enumerable:true,get:function(){return ERRORS;}});\nObject.defineProperty(__exports,\"packHandle\",{enumerable:true,get:function(){return packHandle;}});\nObject.defineProperty(__exports,\"packHandles\",{enumerable:true,get:function(){return packHandles;}});\nObject.defineProperty(__exports,\"TransportedDictionary\",{enumerable:true,get:function(){return TransportedDictionary;}});\nObject.defineProperty(__exports,\"unpackHandle\",{enumerable:true,get:function(){return unpackHandle;}});\nObject.defineProperty(__exports,\"unpackHandles\",{enumerable:true,get:function(){return unpackHandles;}});\nObject.defineProperty(__exports,\"createMaskPool\",{enumerable:true,get:function(){return createMaskPool;}});\nObject.defineProperty(__exports,\"isTransferable\",{enumerable:true,get:function(){return isTransferable;}});\nObject.defineProperty(__exports,\"collectTransfers\",{enumerable:true,get:function(){return collectTransfers;}});\nObject.defineProperty(__exports,\"isPortable\",{enumerable:true,get:function(){return isPortable;}});\nObject.defineProperty(__exports,\"filterColumnIds\",{enumerable:true,get:function(){return filterColumnIds;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst isFunction=__m0[\"isFunction\"];\nconst PROTOCOL=1;\nconst OPS=Object.freeze({\nSORT_COLUMN:'sortColumn',\nSORT_MULTI:'sortMulti',\nEVALUATE_FILTERS:'evaluateFilters',\nCOMPACT:'compact',\nGROUP_BY_COLUMNS:'groupByColumns',\nTOTAL:'total',\nPIVOT:'pivot',\nFACET:'facet',\nCOLUMNIZE:'columnize',\n});\nconst CONTROL=Object.freeze({\nREADY:'ready',\nCANCEL:'cancel',\nPING:'ping',\n});\nconst ERRORS=Object.freeze({\nNO_COMPUTE:'E_NO_COMPUTE',\nNO_KERNEL:'E_NO_KERNEL',\nABORTED:'E_ABORTED',\nKERNEL:'E_KERNEL',\nPROTOCOL:'E_PROTOCOL',\n});\nfunction packHandle(handle){\nif(handle==null)return null;\nconst presence=handle.presence;\nreturn{\nid:handle.id,\nkind:handle.kind,\nnullable:!!handle.nullable,\nvalues:handle.values??null,\npresence:presence?(presence.words??presence):null,\npresenceBits:presence?(presence.size??(presence.words??presence).length*8):0,\ndict:handle.dict?sliceDictionary(handle.dict):null,\noffsets:handle.offsets??null,\nversion:handle.version??0,\n};\n}\nfunction sliceDictionary(dict){\nif(Array.isArray(dict))return dict;\nif(isFunction(dict.values))return dict.values();\nreturn[];\n}\nfunction packHandles(handles){\nconst out=new Array(handles.length);\nfor(let i=0;i<handles.length;i++)out[i]=packHandle(handles[i]);\nreturn out;\n}\nclass TransportedBitset{\n#words;\n#bits;\nconstructor(words,bits){\nthis.#words=words;\nthis.#bits=bits;\n}\nget words(){return this.#words;}\nget size(){return this.#bits;}\nget(i){return(this.#words[i>>>3]&(1<<(i&7)))!==0;}\ncount(){\nconst w=this.#words;\nlet n=0;\nfor(let i=0;i<w.length;i++){\nlet v=w[i];\nwhile(v){v&=v-1;n++;}\n}\nreturn n;\n}\n}\nclass TransportedDictionary{\n#values;\n#index=null;\n#version=0;\n#ranks=new Map();\nconstructor(values){\nthis.#values=values||[];\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\ncodeOf(value){\nif(this.#index===null){\nthis.#index=new Map();\nfor(let i=0;i<this.#values.length;i++)this.#index.set(this.#values[i],i);\n}\nconst found=this.#index.get(value);\nif(found!==undefined)return found;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#index.set(value,code);\nthis.#version++;\nreturn code;\n}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nconst cached=this.#ranks.get(key);\nif(cached&&cached.version===this.#version)return cached.ranks;\nconst n=this.#values.length;\nconst order=new Uint32Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst vals=this.#values;\nconst sorted=Array.from(order).sort((a,b)=>{\nconst av=vals[a];\nconst bv=vals[b];\nif(av===bv)return 0;\nif(av===null||av===undefined)return 1;\nif(bv===null||bv===undefined)return-1;\nreturn cmp(String(av),String(bv));\n});\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<sorted.length;r++)ranks[sorted[r]]=r;\nthis.#ranks.set(key,{version:this.#version,ranks});\nreturn ranks;\n}\n}\nfunction unpackHandle(packed){\nif(packed==null)return null;\nconst presence=packed.presence\n?new TransportedBitset(packed.presence,packed.presenceBits||packed.presence.length*8)\n:null;\nconst dict=packed.dict?new TransportedDictionary(packed.dict):null;\nconst values=packed.values;\nconst offsets=packed.offsets??null;\nconst kind=packed.kind;\nconst get=(physical)=>{\nif(presence&&!presence.get(physical))return null;\nswitch(kind){\ncase'dictionary':\nreturn dict?dict.valueOf(values[physical]):values[physical];\ncase'bitset':\nreturn(values[physical>>>3]&(1<<(physical&7)))!==0;\ncase'multi':{\nif(!offsets)return null;\nconst from=offsets[physical];\nconst to=offsets[physical+1];\nconst out=new Array(to-from);\nfor(let i=from;i<to;i++)out[i-from]=dict?dict.valueOf(values[i]):values[i];\nreturn out;\n}\ndefault:\nreturn values[physical];\n}\n};\nreturn{\nid:packed.id,\nkind,\nnullable:packed.nullable,\nvalues,\npresence,\ndict,\noffsets,\nget,\nversion:packed.version,\n};\n}\nfunction unpackHandles(packed){\nconst out=new Array(packed.length);\nfor(let i=0;i<packed.length;i++)out[i]=unpackHandle(packed[i]);\nreturn out;\n}\nfunction createMaskPool(){\nconst masks=[];\nconst indices=[];\nreturn{\nmask(n){\nfor(let i=0;i<masks.length;i++){\nif(masks[i].length>=n){\nconst buf=masks.splice(i,1)[0].subarray(0,n);\nbuf.fill(0);\nreturn buf;\n}\n}\nreturn new Uint8Array(n);\n},\nindices(n){\nfor(let i=0;i<indices.length;i++){\nif(indices[i].length>=n)return indices.splice(i,1)[0].subarray(0,n);\n}\nreturn new Uint32Array(n);\n},\nrelease(buf){\nif(!buf)return;\nif(buf instanceof Uint8Array)masks.push(buf);\nelse if(buf instanceof Uint32Array)indices.push(buf);\n},\nclear(){masks.length=0;indices.length=0;},\n};\n}\nfunction isTransferable(v){\nif(!ArrayBuffer.isView(v))return false;\nconst buf=(v).buffer;\nif(!buf)return false;\nreturn typeof SharedArrayBuffer==='undefined'||!(buf instanceof SharedArrayBuffer);\n}\nfunction collectTransfers(value,out=[]){\nconst add=(v)=>{\nif(!isTransferable(v))return;\nconst buf=(v).buffer;\nif(!out.includes(buf))out.push(buf);\n};\nif(value==null)return out;\nif(ArrayBuffer.isView(value)){add(value);return out;}\nif(Array.isArray(value)){\nfor(const item of value)add(item);\nreturn out;\n}\nif(typeof value==='object'){\nfor(const key of Object.keys(value)){\nconst item=(value)[key];\nif(Array.isArray(item))for(const sub of item)add(sub);\nelse add(item);\n}\n}\nreturn out;\n}\nfunction isPortable(value,depth=0){\nif(value==null)return true;\nconst t=typeof value;\nif(t==='function'||t==='symbol')return false;\nif(t!=='object')return true;\nif(depth>4)return true;\nif(ArrayBuffer.isView(value)||value instanceof ArrayBuffer||value instanceof Date)return true;\nif(Array.isArray(value)){\nfor(const item of value)if(!isPortable(item,depth+1))return false;\nreturn true;\n}\nfor(const key of Object.keys(value)){\nif(!isPortable((value)[key],depth+1))return false;\n}\nreturn true;\n}\nfunction filterColumnIds(filters,out=new Set()){\nif(!filters||typeof filters!=='object')return out;\nconst node=(filters);\nif(typeof node.col==='string')out.add(node.col);\nconst conditions=node.conditions;\nif(Array.isArray(conditions))for(const child of conditions)filterColumnIds(child,out);\nreturn out;\n}\n});\n__def(\"packages/core/src/store/bitset.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Bitset\",{enumerable:true,get:function(){return Bitset;}});\nconst WORD_BITS=8;\nclass Bitset{\nstatic#POP=new Uint8Array(256);\nstatic{\nfor(let i=1;i<256;i++)Bitset.#POP[i]=Bitset.#POP[i>>1]+(i&1);\n}\n#words;\n#bits;\nconstructor(bits=0){\nconst n=Math.max(0,bits|0);\nthis.#bits=n;\nthis.#words=new Uint8Array(Math.ceil(n/WORD_BITS));\n}\nget size(){return this.#bits;}\nget words(){return this.#words;}\nget bytes(){return this.#words?this.#words.byteLength:0;}\nget(i){\nif(i<0||i>=this.#bits)return 0;\nreturn(this.#words[i>>3]>>(i&7))&1;\n}\nset(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]|=1<<(i&7);\nreturn this;\n}\nclear(i){\nif(i>=0&&i<this.#bits)this.#words[i>>3]&=~(1<<(i&7));\nreturn this;\n}\nassign(i,bit){return bit?this.set(i):this.clear(i);}\nfill(bit=false){\nthis.#words.fill(bit?0xff:0);\nif(bit)this.#maskTail();\nreturn this;\n}\ngrow(bits){\nconst n=Math.max(0,bits|0);\nif(n<=this.#bits)return this;\nconst need=Math.ceil(n/WORD_BITS);\nif(need>this.#words.length){\nconst next=new Uint8Array(need);\nnext.set(this.#words);\nthis.#words=next;\n}\nthis.#bits=n;\nreturn this;\n}\ncount(){\nconst w=this.#words;\nconst pop=Bitset.#POP;\nlet total=0;\nfor(let i=0;i<w.length;i++)total+=pop[w[i]];\nreturn total;\n}\nand(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]&=b[i];\nfor(let i=shared;i<w.length;i++)w[i]=0;\nreturn this;\n}\nor(other){\nconst b=other instanceof Bitset?other.words:other;\nconst w=this.#words;\nconst shared=Math.min(w.length,b.length);\nfor(let i=0;i<shared;i++)w[i]|=b[i];\nreturn this;\n}\nnot(){\nconst w=this.#words;\nfor(let i=0;i<w.length;i++)w[i]=~w[i]&0xff;\nthis.#maskTail();\nreturn this;\n}\nclone(){\nconst out=new Bitset(this.#bits);\nout.words.set(this.#words.subarray(0,out.words.length));\nreturn out;\n}\nrelease(){\nthis.#words=new Uint8Array(0);\nthis.#bits=0;\n}\n#maskTail(){\nconst used=this.#bits&7;\nif(used===0)return;\nconst last=(this.#bits>>3);\nif(last<this.#words.length)this.#words[last]&=(1<<used)-1;\n}\nstatic from(bools){\nconst arr=Array.isArray(bools)?bools:Array.from(bools);\nconst out=new Bitset(arr.length);\nfor(let i=0;i<arr.length;i++)if(arr[i])out.set(i);\nreturn out;\n}\n}\n});\n__def(\"packages/core/src/store/dictionary.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"Dictionary\",{enumerable:true,get:function(){return Dictionary;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nclass Dictionary{\n#values;\n#codes=new Map();\n#version=0;\n#ranks=null;\n#ranksVersion=-1;\n#ranksLocale='\\u0000';\nconstructor(values=[]){\nthis.#values=[];\nfor(let i=0;i<values.length;i++){\nconst v=values[i];\nif(this.#codes.has(v))continue;\nthis.#codes.set(v,this.#values.length);\nthis.#values.push(v);\n}\n}\nget size(){return this.#values.length;}\nget version(){return this.#version;}\nget bytes(){\nlet total=this.#values.length*8;\nfor(let i=0;i<this.#values.length;i++){\nconst v=this.#values[i];\nif(typeof v==='string')total+=v.length*2;\ntotal+=16;\n}\nreturn total;\n}\ncodeOf(value){\nconst existing=this.#codes.get(value);\nif(existing!==undefined)return existing;\nconst code=this.#values.length;\nthis.#values.push(value);\nthis.#codes.set(value,code);\nthis.#version++;\nreturn code;\n}\nlookup(value){\nconst code=this.#codes.get(value);\nreturn code===undefined?-1:code;\n}\nhas(value){return this.#codes.has(value);}\nvalueOf(code){return this.#values[code];}\nvalues(){return this.#values;}\nranks(locale){\nconst key=locale||'';\nif(this.#ranks&&this.#ranksVersion===this.#version&&this.#ranksLocale===key){\nreturn this.#ranks;\n}\nconst n=this.#values.length;\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\nconst cmp=collator(locale).compare;\nconst values=this.#values;\norder.sort((a,b)=>this.#compare(values[a],values[b],cmp));\nconst ranks=new Uint32Array(n);\nfor(let rank=0;rank<n;rank++)ranks[order[rank]]=rank;\nthis.#ranks=ranks;\nthis.#ranksVersion=this.#version;\nthis.#ranksLocale=key;\nreturn ranks;\n}\n#compare(a,b,compare){\nif(typeof a==='string'&&typeof b==='string')return compare(a,b);\nreturn defaultCompare(a,b);\n}\n}\n});\n__def(\"packages/core/src/store/multivalue.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"MultiValue\",{enumerable:true,get:function(){return MultiValue;}});\nclass MultiValue{\n#values;\n#offsets;\n#rows=0;\n#fill=0;\nconstructor(capacity={}){\nconst rows=Math.max(1,capacity.rows??16);\nconst values=Math.max(1,capacity.values??rows);\nthis.#values=new Int32Array(values);\nthis.#offsets=new Uint32Array(rows+1);\n}\nget values(){return this.#values;}\nget offsets(){return this.#offsets;}\nget rows(){return this.#rows;}\nget length(){return this.#fill;}\nget bytes(){return this.#values.byteLength+this.#offsets.byteLength;}\ncount(r){\nif(r<0||r>=this.#rows)return 0;\nreturn this.#offsets[r+1]-this.#offsets[r];\n}\nat(r){\nif(r<0||r>=this.#rows)return this.#values.subarray(0,0);\nreturn this.#values.subarray(this.#offsets[r],this.#offsets[r+1]);\n}\nhas(r,code){\nif(r<0||r>=this.#rows)return false;\nconst v=this.#values;\nconst end=this.#offsets[r+1];\nfor(let i=this.#offsets[r];i<end;i++)if(v[i]===code)return true;\nreturn false;\n}\nhasAny(r,codes){\nfor(let i=0;i<codes.length;i++)if(this.has(r,codes[i]))return true;\nreturn false;\n}\nhasAll(r,codes){\nfor(let i=0;i<codes.length;i++)if(!this.has(r,codes[i]))return false;\nreturn true;\n}\nhasNone(r,codes){return!this.hasAny(r,codes);}\npush(codes){\nconst r=this.#rows;\nconst n=codes.length;\nthis.#ensureRows(r+1);\nthis.#ensureValues(this.#fill+n);\nconst start=this.#fill;\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nthis.#fill+=n;\nthis.#rows=r+1;\nthis.#offsets[r]=start;\nthis.#offsets[r+1]=this.#fill;\nreturn r;\n}\nwrite(r,codes){\nif(r===this.#rows){this.push(codes);return;}\nif(r<0||r>this.#rows)return;\nconst start=this.#offsets[r];\nconst end=this.#offsets[r+1];\nconst n=codes.length;\nif(end-start===n){\nfor(let i=0;i<n;i++)this.#values[start+i]=codes[i]|0;\nreturn;\n}\nthis.#rebuild(r,codes);\n}\ncompact(remap,liveCount,dead){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst oldRows=this.#rows;\nconst values=new Int32Array(Math.max(1,this.#fill));\nconst offsets=new Uint32Array(liveCount+1);\nlet w=0;\nfor(let p=0;p<oldRows;p++){\nif(remap[p]===dead)continue;\nconst start=oldOffsets[p];\nconst end=oldOffsets[p+1];\noffsets[remap[p]]=w;\nfor(let i=start;i<end;i++)values[w++]=oldValues[i];\noffsets[remap[p]+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#rows=liveCount;\nthis.#fill=w;\n}\nrelease(){\nthis.#values=new Int32Array(0);\nthis.#offsets=new Uint32Array(1);\nthis.#rows=0;\nthis.#fill=0;\n}\n#ensureRows(rows){\nif(rows+1<=this.#offsets.length)return;\nlet cap=this.#offsets.length-1;\nwhile(cap<rows)cap=cap*2||16;\nconst next=new Uint32Array(cap+1);\nnext.set(this.#offsets);\nthis.#offsets=next;\n}\n#ensureValues(n){\nif(n<=this.#values.length)return;\nlet cap=this.#values.length;\nwhile(cap<n)cap=cap*2||16;\nconst next=new Int32Array(cap);\nnext.set(this.#values);\nthis.#values=next;\n}\n#rebuild(r,codes){\nconst oldValues=this.#values;\nconst oldOffsets=this.#offsets;\nconst rows=this.#rows;\nconst delta=codes.length-(oldOffsets[r+1]-oldOffsets[r]);\nconst values=new Int32Array(Math.max(1,this.#fill+delta));\nconst offsets=new Uint32Array(oldOffsets.length);\nlet w=0;\nfor(let p=0;p<rows;p++){\noffsets[p]=w;\nif(p===r){\nfor(let i=0;i<codes.length;i++)values[w++]=codes[i]|0;\n}else{\nfor(let i=oldOffsets[p];i<oldOffsets[p+1];i++)values[w++]=oldValues[i];\n}\noffsets[p+1]=w;\n}\nthis.#values=values;\nthis.#offsets=offsets;\nthis.#fill=w;\n}\n}\n});\n__def(\"packages/core/src/compute/handle.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return identity;}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return rowCount;}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return bitReader;}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return presenceReader;}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return dictSize;}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return dictValue;}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return multiValue;}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return valueReader;}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return numericTotalOrder;}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return valueComparator;}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return dictRanks;}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return isMissing;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst collator=__m0[\"collator\"];\nconst defaultCompare=__m0[\"defaultCompare\"];\nconst warnOnce=__m0[\"warnOnce\"];\nfunction identity(n){\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[i]=i;\nreturn out;\n}\nfunction rowCount(handle,opts){\nif(opts&&typeof opts.count==='number')return opts.count;\nif(!handle)return 0;\nif(typeof handle.count==='number')return handle.count;\nif(typeof handle.length==='number')return handle.length;\nconst values=handle.values;\nif(handle.kind==='multi'&&handle.offsets)return Math.max(0,handle.offsets.length-1);\nif(!values)return handle.presence&&typeof handle.presence.size==='number'?handle.presence.size:0;\nif(handle.kind==='bitset'){\nif(typeof values.size==='number')return values.size;\nif(handle.presence&&typeof handle.presence.size==='number')return handle.presence.size;\nwarnOnce(`count:${handle.id}`,`column \"${handle.id}\" is bitset-backed with no declared row count; assuming ${values.length*8}`);\nreturn values.length*8;\n}\nreturn values.length;\n}\nconst bitOrders=new WeakMap();\nfunction bitOrderOf(bitset){\nconst ctor=bitset.constructor;\nif(!ctor)return'unknown';\nconst cached=bitOrders.get(ctor);\nif(cached)return cached;\nlet order='unknown';\ntry{\nlet probe=null;\nif(typeof ctor.from==='function')probe=ctor.from([false,true]);\nelse{\nprobe=new ctor(8);\nprobe.set(1);\n}\nconst words=probe&&probe.words;\nif(words&&words.length){\nif(words[0]===0x02)order='lsb';\nelse if(words[0]===0x40)order='msb';\n}\n}catch{\norder='unknown';\n}\nbitOrders.set(ctor,order);\nreturn order;\n}\nfunction bitReader(bits){\nif(!bits)return()=>0;\nconst raw=bits instanceof Uint8Array?bits:bits.words;\nif(raw instanceof Uint8Array){\nconst order=bits instanceof Uint8Array?'lsb':bitOrderOf(bits);\nif(order==='lsb')return(i)=>(raw[i>>>3]>>>(i&7))&1;\nif(order==='msb')return(i)=>(raw[i>>>3]>>>(7-(i&7)))&1;\n}\nif(typeof bits.get==='function')return(i)=>(bits.get(i)?1:0);\nreturn()=>0;\n}\nfunction presenceReader(handle){\nif(!handle||!handle.presence)return null;\nreturn bitReader(handle.presence);\n}\nfunction dictSize(dict){\nif(!dict)return 0;\nif(typeof dict.size==='number')return dict.size;\nif(typeof dict.values==='function')return dict.values().length;\nreturn 0;\n}\nfunction dictValue(dict,code){\nif(!dict)return null;\nif(typeof dict.valueOf==='function')return dict.valueOf(code);\nif(typeof dict.values==='function')return dict.values()[code];\nreturn null;\n}\nfunction multiValue(handle,i){\nconst offsets=handle.offsets;\nconst values=handle.values;\nif(!offsets||!values)return[];\nconst from=offsets[i];\nconst to=offsets[i+1];\nif(!(to>from))return[];\nconst dict=handle.dict;\nconst out=new Array(to-from);\nfor(let k=from;k<to;k++)out[k-from]=dict?dictValue(dict,values[k]):values[k];\nreturn out;\n}\nfunction valueReader(handle){\nif(!handle)return()=>undefined;\nconst values=handle.values;\nconst present=presenceReader(handle);\nconst kind=handle.kind;\nif(kind==='dictionary'){\nconst dict=handle.dict;\nif(present)return(i)=>(present(i)?dictValue(dict,values[i]):null);\nreturn(i)=>dictValue(dict,values[i]);\n}\nif(kind==='bitset'){\nconst bit=bitReader(values);\nif(present)return(i)=>(present(i)?bit(i)===1:null);\nreturn(i)=>bit(i)===1;\n}\nif(kind==='multi'){\nif(present)return(i)=>(present(i)?multiValue(handle,i):null);\nreturn(i)=>multiValue(handle,i);\n}\nif(!values&&typeof handle.get==='function'){\nconst get=handle.get.bind(handle);\nreturn(i)=>{\nconst v=get(i);\nreturn v===undefined?null:v;\n};\n}\nif(present){\nreturn(i)=>{\nif(!present(i))return null;\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nreturn(i)=>{\nconst v=values[i];\nreturn v===undefined?null:v;\n};\n}\nfunction numericTotalOrder(a,b){\nif(a<b)return-1;\nif(a>b)return 1;\nif(a===b){\nconst na=Object.is(a,-0);\nconst nb=Object.is(b,-0);\nif(na===nb)return 0;\nreturn na?-1:1;\n}\nconst an=Number.isNaN(a);\nconst bn=Number.isNaN(b);\nif(an&&bn)return 0;\nreturn an?1:-1;\n}\nfunction valueComparator(locale){\nconst coll=collator(locale);\nreturn(a,b)=>{\nif(a===b)return 0;\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return coll.compare(a,b);\nif(ta==='number'&&tb==='number')return numericTotalOrder(a,b);\nif(ta==='boolean'&&tb==='boolean')return a===b?0:a?1:-1;\nif(a instanceof Date||b instanceof Date){\nconst na=a instanceof Date?a.getTime():Number(a);\nconst nb=b instanceof Date?b.getTime():Number(b);\nreturn numericTotalOrder(na,nb);\n}\nreturn defaultCompare(a,b);\n};\n}\nfunction dictRanks(dict,locale){\nif(dict&&typeof dict.ranks==='function')return dict.ranks(locale);\nconst table=dict&&typeof dict.values==='function'?dict.values():[];\nconst n=table.length;\nconst cmp=valueComparator(locale);\nconst order=new Array(n);\nfor(let i=0;i<n;i++)order[i]=i;\norder.sort((a,b)=>cmp(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(n);\nfor(let r=0;r<n;r++)ranks[order[r]]=r;\nreturn ranks;\n}\nfunction isMissing(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\n});\n__def(\"packages/core/src/compute/sort.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return radixSortFloat64;}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return radixSortInt32;}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return rankSortDictionary;}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return mergeSortComparator;}});\nObject.defineProperty(__exports,\"rankSortStrings\",{enumerable:true,get:function(){return rankSortStrings;}});\nObject.defineProperty(__exports,\"collateStringRanks\",{enumerable:true,get:function(){return collateStringRanks;}});\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return sortColumn;}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return sortMulti;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m0[\"bitReader\"];\nconst dictRanks=__m0[\"dictRanks\"];\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst isMissing=__m0[\"isMissing\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueComparator=__m0[\"valueComparator\"];\nconst valueReader=__m0[\"valueReader\"];\nconst EMPTY_INDICES=new Uint32Array(0);\nconst SCRATCH=new ArrayBuffer(8);\nconst SCRATCH_F64=new Float64Array(SCRATCH);\nconst SCRATCH_U32=new Uint32Array(SCRATCH);\nconst HI=(()=>{\nSCRATCH_F64[0]=-1;\nreturn(SCRATCH_U32[1]&0x80000000)!==0?1:0;\n})();\nconst LO=HI===1?0:1;\nfunction transformDouble(value,out){\nSCRATCH_F64[0]=value;\nlet hi=SCRATCH_U32[HI];\nlet lo=SCRATCH_U32[LO];\nif((hi&0x80000000)!==0){\nhi=~hi>>>0;\nlo=~lo>>>0;\n}else{\nhi=(hi^0x80000000)>>>0;\n}\nout[0]=lo;\nout[1]=hi;\n}\nfunction radixLsd64(idx,lo,hi,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*8);\nfor(let i=0;i<n;i++){\nconst l=lo[i];\nconst h=hi[i];\nhist[l&0xff]++;\nhist[256+((l>>>8)&0xff)]++;\nhist[512+((l>>>16)&0xff)]++;\nhist[768+((l>>>24)&0xff)]++;\nhist[1024+(h&0xff)]++;\nhist[1280+((h>>>8)&0xff)]++;\nhist[1536+((h>>>16)&0xff)]++;\nhist[1792+((h>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcLo=lo;\nlet srcHi=hi;\nlet dstIdx=new Uint32Array(n);\nlet dstLo=new Uint32Array(n);\nlet dstHi=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<8;pass++){\nconst base=pass<<8;\nconst shift=(pass&3)<<3;\nconst useHi=pass>=4;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst l=srcLo[i];\nconst h=srcHi[i];\nconst digit=((useHi?h:l)>>>shift)&0xff;\nconst p=offset[digit]++;\ndstIdx[p]=srcIdx[i];\ndstLo[p]=l;\ndstHi[p]=h;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcLo;srcLo=dstLo;dstLo=t;\nt=srcHi;srcHi=dstHi;dstHi=t;\n}\nreturn srcIdx;\n}\nfunction radixLsd32(idx,keys,n){\nif(n<2)return idx;\nconst hist=new Uint32Array(256*4);\nfor(let i=0;i<n;i++){\nconst k=keys[i];\nhist[k&0xff]++;\nhist[256+((k>>>8)&0xff)]++;\nhist[512+((k>>>16)&0xff)]++;\nhist[768+((k>>>24)&0xff)]++;\n}\nlet srcIdx=idx;\nlet srcKeys=keys;\nlet dstIdx=new Uint32Array(n);\nlet dstKeys=new Uint32Array(n);\nconst offset=new Uint32Array(256);\nfor(let pass=0;pass<4;pass++){\nconst base=pass<<8;\nconst shift=pass<<3;\nlet skip=false;\nfor(let b=0;b<256;b++){\nif(hist[base+b]===n){skip=true;break;}\n}\nif(skip)continue;\nlet sum=0;\nfor(let b=0;b<256;b++){\noffset[b]=sum;\nsum+=hist[base+b];\n}\nfor(let i=0;i<n;i++){\nconst k=srcKeys[i];\nconst p=offset[(k>>>shift)&0xff]++;\ndstIdx[p]=srcIdx[i];\ndstKeys[p]=k;\n}\nlet t=srcIdx;srcIdx=dstIdx;dstIdx=t;\nt=srcKeys;srcKeys=dstKeys;dstKeys=t;\n}\nreturn srcIdx;\n}\nfunction countingSort(idx,keys,n,radix){\nconst counts=new Uint32Array(radix+1);\nfor(let i=0;i<n;i++)counts[keys[i]]++;\nlet sum=0;\nfor(let k=0;k<=radix;k++){\nconst c=counts[k];\ncounts[k]=sum;\nsum+=c;\n}\nconst out=new Uint32Array(n);\nfor(let i=0;i<n;i++)out[counts[keys[i]]++]=idx[i];\nreturn out;\n}\nfunction sortUint32Keys(idx,keys,n,radix){\nif(n<2)return idx;\nif(radix<=65536||radix<=n*2)return countingSort(idx,keys,n,radix);\nreturn radixLsd32(idx,keys,n);\n}\nfunction exact(buffer,n){\nif(buffer.length===n&&buffer.byteOffset===0)return buffer;\nreturn Uint32Array.prototype.slice.call(buffer,0,n);\n}\nfunction radixSortFloat64(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=new Uint32Array(n);\nconst lo=new Uint32Array(n);\nconst hi=new Uint32Array(n);\nconst nans=new Uint32Array(n);\nconst pair=new Uint32Array(2);\nlet m=0;\nlet nanCount=0;\nfor(let i=0;i<n;i++){\nconst row=src[i];\nconst v=values[row];\nif(Number.isNaN(v)){nans[nanCount++]=row;continue;}\ntransformDouble(v,pair);\nif(descending){\nlo[m]=~pair[0]>>>0;\nhi[m]=~pair[1]>>>0;\n}else{\nlo[m]=pair[0];\nhi[m]=pair[1];\n}\nidx[m++]=row;\n}\nconst sorted=radixLsd64(idx.subarray(0,m),lo.subarray(0,m),hi.subarray(0,m),m);\nif(nanCount===0)return exact(sorted,m);\nconst out=new Uint32Array(n);\nout.set(sorted.subarray(0,m),0);\nout.set(nans.subarray(0,nanCount),m);\nreturn out;\n}\nfunction radixSortInt32(values,order,descending=false){\nconst src=order||identity(values.length);\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst k=(values[idx[i]]^0x80000000)>>>0;\nkeys[i]=descending?(~k>>>0):k;\n}\nreturn exact(radixLsd32(idx,keys,n),n);\n}\nfunction rankSortDictionary(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nconst n=src.length;\nif(n<2)return Uint32Array.from(src);\nconst ranks=dictRanks(handle.dict,opts.locale);\nconst codes=handle.values;\nconst present=presenceReader(handle);\nconst size=Math.max(dictSize(handle.dict),ranks.length);\nconst absentRank=size;\nconst idx=Uint32Array.from(src);\nconst keys=new Uint32Array(n);\nconst descending=!!opts.descending;\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nlet rank=present&&present(row)===0?absentRank:ranks[codes[row]];\nif(rank===undefined)rank=absentRank;\nkeys[i]=descending?absentRank-rank:rank;\n}\nreturn exact(sortUint32Keys(idx,keys,n,size+1),n);\n}\nfunction mergeSortComparator(values,order,compare){\nconst n=order.length;\nlet src=Uint32Array.from(order);\nif(n<2)return src;\nlet dst=new Uint32Array(n);\nfor(let width=1;width<n;width<<=1){\nfor(let start=0;start<n;start+=width<<1){\nconst mid=Math.min(start+width,n);\nconst end=Math.min(start+(width<<1),n);\nlet i=start;\nlet j=mid;\nlet k=start;\nwhile(i<mid&&j<end){\ndst[k++]=compare(values[src[i]],values[src[j]])<=0?src[i++]:src[j++];\n}\nwhile(i<mid)dst[k++]=src[i++];\nwhile(j<end)dst[k++]=src[j++];\n}\nconst t=src;src=dst;dst=t;\n}\nreturn src;\n}\nfunction sortBitsetColumn(handle,idx,descending){\nconst bit=bitReader(handle.values);\nconst n=idx.length;\nconst out=new Uint32Array(n);\nconst first=descending?1:0;\nlet k=0;\nfor(let i=0;i<n;i++)if(bit(idx[i])===first)out[k++]=idx[i];\nfor(let i=0;i<n;i++)if(bit(idx[i])!==first)out[k++]=idx[i];\nreturn out;\n}\nfunction indexableValues(handle,idx){\nconst values=handle.values;\nconst kind=handle.kind;\nconst direct=(kind==='object'||kind===undefined)&&(Array.isArray(values)||ArrayBuffer.isView(values));\nif(direct&&!handle.presence)return values;\nconst reader=valueReader(handle);\nconst materialised=new Array(rowCount(handle)||0);\nfor(let i=0;i<idx.length;i++){\nconst row=idx[i];\nmaterialised[row]=reader(row);\n}\nreturn materialised;\n}\nfunction allStrings(values,idx){\nfor(let i=0;i<idx.length;i++){\nif(typeof values[idx[i]]!=='string')return false;\n}\nreturn true;\n}\nfunction rankSortStrings(idx,codes,ranks,d,descending){\nconst n=idx.length;\nconst idxOut=Uint32Array.from(idx);\nif(n<2||d<1)return idxOut;\nconst keys=new Uint32Array(n);\nconst top=d-1;\nfor(let i=0;i<n;i++){\nconst rank=ranks[codes[i]];\nkeys[i]=descending?top-rank:rank;\n}\nreturn exact(sortUint32Keys(idxOut,keys,n,d),n);\n}\nfunction collateStringRanks(table,d,locale){\nconst compare=valueComparator(locale);\nconst order=new Array(d);\nfor(let i=0;i<d;i++)order[i]=i;\norder.sort((a,b)=>compare(table[a],table[b])||a-b);\nconst ranks=new Uint32Array(d);\nfor(let r=0;r<d;r++)ranks[order[r]]=r;\nreturn ranks;\n}\nfunction keyedSortStrings(values,idx,opts){\nconst n=idx.length;\nconst codeOf=new Map();\nconst table=[];\nconst codes=new Uint32Array(n);\nfor(let i=0;i<n;i++){\nconst v=values[idx[i]];\nlet c=codeOf.get(v);\nif(c===undefined){c=table.length;codeOf.set(v,c);table.push(v);}\ncodes[i]=c;\n}\nconst d=table.length;\nconst ranks=collateStringRanks(table,d,opts.locale);\nreturn rankSortStrings(idx,codes,ranks,d,!!opts.descending);\n}\nfunction sortByComparator(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nif(idx.length>=2&&allStrings(values,idx)){\nconst index=handle.stringRank;\nif(index&&index.version===handle.version&&index.usable(idx,values,opts.locale)){\nreturn index.sort(idx,opts);\n}\nreturn keyedSortStrings(values,idx,opts);\n}\nconst base=valueComparator(opts.locale);\nconst compare=opts.descending?(a,b)=>base(b,a):base;\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction sortByCompare(handle,idx,opts){\nconst values=indexableValues(handle,idx);\nconst user=opts.compare;\nconst descending=!!opts.descending;\nconst compare=descending\n?(a,b)=>-user(a,b,undefined,undefined,true)\n:(a,b)=>user(a,b,undefined,undefined,false);\nreturn mergeSortComparator(values,idx,compare);\n}\nfunction partitionPresent(handle,idx){\nconst n=idx.length;\nconst present=presenceReader(handle);\nconst values=handle.values;\nconst checkNaN=handle.kind==='float64'&&!!values;\nconst looseKind=handle.kind==='object'||handle.kind==='multi'||handle.kind===undefined;\nif(!present&&!checkNaN&&!looseKind)return{present:idx,absent:EMPTY_INDICES};\nconst keep=new Uint32Array(n);\nconst drop=new Uint32Array(n);\nlet p=0;\nlet a=0;\nif(present&&checkNaN){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1&&!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(checkNaN&&!present){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!Number.isNaN(values[row]))keep[p++]=row;else drop[a++]=row;\n}\n}else if(present&&!looseKind){\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(present(row)===1)keep[p++]=row;else drop[a++]=row;\n}\n}else{\nconst reader=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst row=idx[i];\nif(!isMissing(reader(row)))keep[p++]=row;else drop[a++]=row;\n}\n}\nif(a===0)return{present:idx,absent:EMPTY_INDICES};\nreturn{present:keep.subarray(0,p),absent:drop.subarray(0,a)};\n}\nfunction joinRuns(sorted,absent,nullsFirst){\nif(absent.length===0)return sorted;\nconst out=new Uint32Array(sorted.length+absent.length);\nif(nullsFirst){\nout.set(absent,0);\nout.set(sorted,absent.length);\n}else{\nout.set(sorted,0);\nout.set(absent,sorted.length);\n}\nreturn out;\n}\nfunction sortColumn(handle,order,opts={}){\nconst src=order||identity(rowCount(handle,opts));\nif(!handle||src.length<2)return Uint32Array.from(src);\nconst{present,absent}=partitionPresent(handle,src);\nif(present.length===0)return Uint32Array.from(src);\nconst descending=!!opts.descending;\nlet sorted;\nif(typeof opts.compare==='function'){\nsorted=sortByCompare(handle,present,opts);\n}else{\nswitch(handle.kind){\ncase'float64':\nsorted=radixSortFloat64(handle.values,present,descending);\nbreak;\ncase'int32':\nsorted=radixSortInt32(handle.values,present,descending);\nbreak;\ncase'dictionary':\nsorted=rankSortDictionary(handle,present,opts);\nbreak;\ncase'bitset':\nsorted=sortBitsetColumn(handle,present,descending);\nbreak;\ndefault:\nsorted=sortByComparator(handle,present,opts);\nbreak;\n}\n}\nreturn joinRuns(sorted,absent,!!opts.nullsFirst);\n}\nfunction sortMulti(handles,entries,order,opts={}){\nconst list=entries||[];\nconst first=(list.length&&(list[0].handle||byId(handles,list[0].col)))||(handles&&handles[0]);\nlet current=order||identity(rowCount(first,opts));\nfor(let i=list.length-1;i>=0;i--){\nconst entry=list[i];\nconst handle=entry.handle||byId(handles,entry.col)||(handles&&handles[i]);\nif(!handle)continue;\ncurrent=sortColumn(handle,current,{\ndescending:entry.descending!==undefined?!!entry.descending:entry.dir==='desc',\nnullsFirst:!!entry.nullsFirst,\nlocale:entry.locale!==undefined?entry.locale:opts.locale,\ncompare:entry.compare,\n});\n}\nreturn current instanceof Uint32Array?current:Uint32Array.from(current);\n}\nfunction byId(handles,id){\nif(!handles||id===undefined)return undefined;\nfor(let i=0;i<handles.length;i++)if(handles[i]&&handles[i].id===id)return handles[i];\nreturn undefined;\n}\n});\n__def(\"packages/core/src/store/stringrank.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"DEFAULT_MAX_DISTINCT\",{enumerable:true,get:function(){return DEFAULT_MAX_DISTINCT;}});\nObject.defineProperty(__exports,\"StringRankIndex\",{enumerable:true,get:function(){return StringRankIndex;}});\nconst __m0=__req(\"packages/core/src/compute/sort.js\");\nconst collateStringRanks=__m0[\"collateStringRanks\"];\nconst rankSortStrings=__m0[\"rankSortStrings\"];\nconst DEFAULT_MAX_DISTINCT=100000;\nclass StringRankIndex{\n#table=[];\n#codeOf=new Map();\n#codeByRow;\n#length=0;\n#generation=0;\n#stamp=-1;\n#maxDistinct;\n#capped=false;\n#ranks=null;\n#ranksGeneration=-1;\n#ranksLocale='\\u0000';\nconstructor(maxDistinct=DEFAULT_MAX_DISTINCT){\nthis.#maxDistinct=maxDistinct>0?maxDistinct:DEFAULT_MAX_DISTINCT;\nthis.#codeByRow=new Uint32Array(0);\n}\nget version(){return this.#stamp;}\nset version(version){this.#stamp=version;}\nget generation(){return this.#generation;}\nget size(){return this.#table.length;}\nget capped(){return this.#capped;}\nget length(){return this.#length;}\nget bytes(){\nlet total=this.#codeByRow.byteLength;\nconst table=this.#table;\nfor(let i=0;i<table.length;i++)total+=table[i].length*2+24;\nreturn total;\n}\n#intern(value,capOnGrowth){\nconst existing=this.#codeOf.get(value);\nif(existing!==undefined)return existing;\nif(this.#capped)return-1;\nif(capOnGrowth&&this.#table.length>=this.#maxDistinct){\nthis.#capped=true;\nreturn-1;\n}\nconst code=this.#table.length;\nthis.#table.push(value);\nthis.#codeOf.set(value,code);\nthis.#generation++;\nreturn code;\n}\nbuild(values,count){\nconst n=count|0;\nthis.#table=[];\nthis.#codeOf=new Map();\nthis.#generation=0;\nthis.#capped=false;\nthis.#ranks=null;\nthis.#ranksGeneration=-1;\nthis.#codeByRow=new Uint32Array(n);\nfor(let row=0;row<n;row++){\nconst v=values[row];\nconst code=typeof v==='string'?this.#intern(v,false):-1;\nthis.#codeByRow[row]=code<0?0:code;\n}\nthis.#length=n;\n}\nappend(values,from,count){\nconst to=(from|0)+(count|0);\nif(to>this.#codeByRow.length){\nconst next=new Uint32Array(to);\nnext.set(this.#codeByRow.subarray(0,this.#length));\nthis.#codeByRow=next;\n}\nfor(let row=from|0;row<to;row++){\nconst v=values[row];\nconst code=typeof v==='string'?this.#intern(v,true):-1;\nthis.#codeByRow[row]=code<0?0:code;\n}\nthis.#length=Math.max(this.#length,to);\n}\nranks(locale){\nconst key=locale||'';\nif(this.#ranks&&this.#ranksGeneration===this.#generation&&this.#ranksLocale===key){\nreturn this.#ranks;\n}\nconst ranks=collateStringRanks(this.#table,this.#table.length,locale);\nthis.#ranks=ranks;\nthis.#ranksGeneration=this.#generation;\nthis.#ranksLocale=key;\nreturn ranks;\n}\nusable(idx,values,locale){\nif(this.#capped||this.#table.length===0)return false;\nconst codeByRow=this.#codeByRow;\nconst table=this.#table;\nconst covered=this.#length;\nfor(let i=0;i<idx.length;i++){\nconst row=idx[i];\nif(row>=covered)return false;\nif(table[codeByRow[row]]!==values[row])return false;\n}\nreturn true;\n}\nsort(idx,opts){\nconst ranks=this.ranks(opts.locale);\nconst d=this.#table.length;\nconst n=idx.length;\nconst codes=new Uint32Array(n);\nconst codeByRow=this.#codeByRow;\nfor(let i=0;i<n;i++)codes[i]=codeByRow[idx[i]];\nreturn rankSortStrings(idx,codes,ranks,d,!!opts.descending);\n}\n}\n});\n__def(\"packages/core/src/store/columnstore.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"REMOVED\",{enumerable:true,get:function(){return REMOVED;}});\nObject.defineProperty(__exports,\"toFloat\",{enumerable:true,get:function(){return toFloat;}});\nObject.defineProperty(__exports,\"ColumnHandle\",{enumerable:true,get:function(){return ColumnHandle;}});\nObject.defineProperty(__exports,\"ColumnStore\",{enumerable:true,get:function(){return ColumnStore;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/bitset.js\");\nconst Bitset=__m1[\"Bitset\"];\nconst __m2=__req(\"packages/core/src/store/dictionary.js\");\nconst Dictionary=__m2[\"Dictionary\"];\nconst __m3=__req(\"packages/core/src/store/multivalue.js\");\nconst MultiValue=__m3[\"MultiValue\"];\nconst __m4=__req(\"packages/core/src/store/stringrank.js\");\nconst StringRankIndex=__m4[\"StringRankIndex\"];\nconst REMOVED=0xFFFFFFFF;\nconst DEFAULT_CAPACITY=1024;\nconst DEFAULT_COLUMNAR_BELOW=5000;\nconst DEFAULT_COMPACT_RATIO=0.2;\nconst KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction absent(v){return v===null||v===undefined;}\nfunction toFloat(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(typeof v==='boolean')return v?1:0;\nconst n=Number(v);\nreturn Number.isNaN(n)&&typeof v==='string'?Date.parse(v):n;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(absent(v))return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction decodeFrom(old,p){\nswitch(old.kind){\ncase'float64':\ncase'int32':return old.buf[p];\ncase'bitset':return old.bits.get(p)===1;\ncase'dictionary':return old.dict.valueOf(old.buf[p]);\ncase'multi':{\nconst codes=old.mv.at(p);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=old.dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return old.buf[p];\n}\n}\nfunction decodePacked(frag,i){\nswitch(frag.kind){\ncase'float64':\ncase'int32':return frag.values[i];\ncase'bitset':return(frag.values[i>>3]&(1<<(i&7)))!==0;\ncase'dictionary':return(frag.table||[])[frag.values[i]];\ncase'multi':{\nconst start=frag.offsets[i];\nconst end=frag.offsets[i+1];\nconst table=frag.table||[];\nconst out=new Array(end-start);\nfor(let k=start;k<end;k++)out[k-start]=table[frag.values[k]];\nreturn out;\n}\ndefault:return frag.values[i];\n}\n}\nclass ColumnHandle{\n#id;\n#kind;\n#target;\n#nullable;\n#read;\n#host;\n#seed;\n#columnar=false;\n#buf=null;\n#bits=null;\n#mv=null;\n#dict=null;\n#stringRank=null;\n#stringRankOn;\n#stringRankMax;\n#stringRankVersion=-1;\n#presence=null;\n#capacity=0;\n#version=0;\n#overlay=null;\n#cache=null;\n#released=false;\nconstructor(schema,host){\nthis.#id=schema.id;\nconst kind=KINDS.has(schema.kind)?schema.kind:'object';\nif(schema.kind&&!KINDS.has(schema.kind)){\nwarnOnce(`store.kind.${schema.id}`,\n`column \"${schema.id}\" declares unknown storage kind \"${schema.kind}\"; falling back to object`);\n}\nthis.#target=kind;\nthis.#kind=kind;\nthis.#nullable=schema.nullable!==false;\nthis.#seed=schema.dictionary??null;\nthis.#host=host;\nthis.#read=isFunction(schema.read)\n?schema.read\n:pathGetter(schema.field||schema.id);\nthis.#stringRankOn=schema.stringRankIndex!=='off';\nthis.#stringRankMax=typeof schema.stringRankMaxDistinct==='number'\n?schema.stringRankMaxDistinct\n:0;\nthis.#overlay=new Map();\n}\nget id(){return this.#id;}\nget kind(){return this.#columnar?this.#kind:'object';}\nget target(){return this.#target;}\nget nullable(){return this.#nullable;}\nget values(){\nif(this.#released)return null;\nif(!this.#columnar)return this.#lazy().values;\nif(this.#kind==='bitset')return this.#bits.words;\nif(this.#kind==='multi')return this.#mv.values;\nreturn this.#buf;\n}\nget presence(){\nif(this.#released||!this.#nullable)return null;\nreturn this.#columnar?this.#presence:this.#lazy().presence;\n}\nget dict(){\nif(this.#released||!this.#columnar)return null;\nreturn this.#kind==='dictionary'||this.#kind==='multi'?this.#dict:null;\n}\nget stringRank(){\nif(this.#released||!this.#stringRankOn)return null;\nif(this.kind!=='object')return null;\nconst values=this.values;\nconst n=this.#host.physical();\nif(!values||n===0)return null;\nif(this.#stringRank===null){\nif(typeof values[0]!=='string')return null;\nconst index=new StringRankIndex(this.#resolveStringRankMax());\nindex.build(values,n);\nindex.version=this.#version;\nthis.#stringRank=index;\nthis.#stringRankVersion=this.#version;\nreturn index.capped?null:index;\n}\nif(this.#stringRank.length<n){\nthis.#stringRank.append(values,this.#stringRank.length,n-this.#stringRank.length);\n}\nthis.#stringRank.version=this.#version;\nthis.#stringRankVersion=this.#version;\nreturn this.#stringRank.capped?null:this.#stringRank;\n}\n#resolveStringRankMax(){return this.#stringRankMax;}\n#dropStringRank(){\nthis.#stringRank=null;\nthis.#stringRankVersion=-1;\n}\nget offsets(){\nif(this.#released||!this.#columnar||this.#kind!=='multi')return null;\nreturn this.#mv.offsets;\n}\nget version(){return this.#version;}\nget bytes(){\nlet total=0;\nif(this.#buf)total+=this.#buf.byteLength??this.#buf.length*8;\nif(this.#bits)total+=this.#bits.bytes;\nif(this.#mv)total+=this.#mv.bytes;\nif(this.#presence)total+=this.#presence.bytes;\nif(this.#dict)total+=this.#dict.bytes;\nif(this.#overlay)total+=this.#overlay.size*24;\nreturn total;\n}\nget(physical){\nif(this.#released)return undefined;\nif(physical<0||physical>=this.#host.physical())return undefined;\nif(!this.#columnar)return this.#rowValue(physical);\nif(this.#nullable&&this.#presence.get(physical)===0)return null;\nswitch(this.#kind){\ncase'float64':\ncase'int32':return this.#buf[physical];\ncase'bitset':return this.#bits.get(physical)===1;\ncase'dictionary':return this.#dict.valueOf(this.#buf[physical]);\ncase'multi':{\nconst codes=this.#mv.at(physical);\nconst out=new Array(codes.length);\nfor(let i=0;i<codes.length;i++)out[i]=this.#dict.valueOf(codes[i]);\nreturn out;\n}\ndefault:return this.#buf[physical];\n}\n}\nset(physical,value){\nif(this.#released)return;\nif(this.#columnar)this.#writeValue(physical,value);\nelse this.#overlay.set(physical,value===undefined?null:value);\nif(this.#stringRank)this.#dropStringRank();\nthis.#version++;\n}\nread(row){return this.#read(row);}\nappendColumn(objects,from,n){\nif(this.#released||n<=0)return;\nif(!this.#columnar){this.#version++;return;}\nconst read=this.#read;\nconst nullable=this.#nullable;\nconst presence=this.#presence;\nlet sawAbsent=false;\nswitch(this.#kind){\ncase'float64':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nif(typeof v==='number'){\nif(nullable)presence.set(from+i);\nbuf[from+i]=v;\ncontinue;\n}\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?NaN:toFloat(v);\n}\nbreak;\n}\ncase'int32':{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:toInt(v);\n}\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbits.assign(from+i,!gone&&!!v);\n}\nbreak;\n}\ncase'dictionary':{\nconst buf=this.#buf;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?0:dict.codeOf(v);\n}\nbreak;\n}\ncase'multi':{\nconst mv=this.#mv;\nconst dict=this.#dict;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nconst members=toMembers(v);\nconst codes=new Array(members.length);\nfor(let k=0;k<members.length;k++)codes[k]=dict.codeOf(members[k]);\nmv.write(from+i,codes);\n}\nbreak;\n}\ndefault:{\nconst buf=this.#buf;\nfor(let i=0;i<n;i++){\nconst v=read(objects[i]);\nconst gone=v===null||v===undefined;\nif(nullable)presence.assign(from+i,!gone);\nelse if(gone)sawAbsent=true;\nbuf[from+i]=gone?null:v;\n}\nbreak;\n}\n}\nif(sawAbsent){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nif(this.#stringRank&&this.#kind==='object'){\nthis.#stringRank.append(this.#buf,from,n);\nthis.#stringRank.version=this.#version+1;\nthis.#stringRankVersion=this.#version+1;\n}\nthis.#version++;\n}\nappendPacked(frag,from,n){\nif(this.#released||n<=0||!frag)return;\nif(!this.#columnar){this.#version++;return;}\nconst presence=this.#presence;\nconst fragPresence=frag.presence;\nif(presence){\nif(fragPresence){\nfor(let i=0;i<n;i++)presence.assign(from+i,(fragPresence[i>>3]&(1<<(i&7)))!==0);\n}else{\nfor(let i=0;i<n;i++)presence.set(from+i);\n}\n}\nconst kindsAgree=frag.kind===this.#kind;\nif(kindsAgree&&(this.#kind==='float64'||this.#kind==='int32')){\nthis.#buf.set(frag.values,from);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='bitset'){\nconst words=frag.values;\nfor(let i=0;i<n;i++)this.#bits.assign(from+i,(words[i>>3]&(1<<(i&7)))!==0);\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='dictionary'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst codes=frag.values;\nconst buf=this.#buf;\nconst pres=presence;\nfor(let i=0;i<n;i++){\nif(pres&&(fragPresence?(fragPresence[i>>3]&(1<<(i&7)))===0:false)){buf[from+i]=0;continue;}\nbuf[from+i]=remap[codes[i]]??0;\n}\nthis.#version++;\nreturn;\n}\nif(kindsAgree&&this.#kind==='multi'){\nconst table=frag.table||[];\nconst remap=new Uint32Array(table.length);\nfor(let t=0;t<table.length;t++)remap[t]=this.#dict.codeOf(table[t]);\nconst flat=frag.values;\nconst offsets=frag.offsets;\nfor(let i=0;i<n;i++){\nconst start=offsets[i];\nconst end=offsets[i+1];\nconst codes=new Array(end-start);\nfor(let k=start;k<end;k++)codes[k-start]=remap[flat[k]]??0;\nthis.#mv.write(from+i,codes);\n}\nthis.#version++;\nreturn;\n}\nfor(let i=0;i<n;i++){\nconst gone=fragPresence\n?(fragPresence[i>>3]&(1<<(i&7)))===0\n:(frag.kind==='object'?frag.values[i]===null:false);\nthis.#writeValue(from+i,gone?null:decodePacked(frag,i));\n}\nthis.#version++;\n}\ntouch(){this.#version++;}\ncolumnarise(capacity,fill){\nif(this.#columnar||this.#released)return;\nconst values=new Array(fill);\nfor(let p=0;p<fill;p++)values[p]=this.#rowValue(p);\nthis.#kind=this.#target;\nthis.#columnar=true;\nthis.#alloc(capacity);\nfor(let p=0;p<fill;p++)this.#writeValue(p,values[p]);\nthis.#overlay.clear();\nthis.#cache=null;\nthis.#dropStringRank();\nthis.#version++;\n}\ngrow(capacity){\nif(!this.#columnar||this.#released||capacity<=this.#capacity)return;\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':{\nconst next=new this.#buf.constructor(capacity);\nnext.set(this.#buf);\nthis.#buf=next;\nbreak;\n}\ncase'bitset':this.#bits.grow(capacity);break;\ncase'multi':break;\ndefault:this.#buf.length=capacity;break;\n}\nif(this.#presence)this.#presence.grow(capacity);\nthis.#capacity=capacity;\nthis.#version++;\n}\nconvert(kind){\nif(this.#released||!KINDS.has(kind))return false;\nthis.#target=kind;\nif(!this.#columnar||kind===this.#kind)return false;\nconst old={kind:this.#kind,buf:this.#buf,bits:this.#bits,mv:this.#mv,dict:this.#dict};\nconst n=this.#host.physical();\nconst presence=this.#presence;\nthis.#kind=kind;\nthis.#alloc(this.#capacity);\nfor(let p=0;p<n;p++){\nconst gone=presence!==null&&presence.get(p)===0;\nif(gone&&kind!=='multi')continue;\nthis.#writeValue(p,gone?null:decodeFrom(old,p));\n}\nthis.#dropStringRank();\nthis.#version++;\nreturn true;\n}\ncompact(remap,oldFill,liveCount){\nif(this.#released)return;\nthis.#dropStringRank();\nif(!this.#columnar){\nconst overlay=this.#overlay;\nif(overlay.size){\nconst next=new Map();\nfor(const[p,v]of overlay)if(remap[p]!==REMOVED)next.set(remap[p],v);\nthis.#overlay=next;\n}\nthis.#cache=null;\nthis.#version++;\nreturn;\n}\nswitch(this.#kind){\ncase'float64':case'int32':case'dictionary':case'object':{\nconst buf=this.#buf;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)buf[remap[p]]=buf[p];\nif(this.#kind==='object')for(let p=liveCount;p<oldFill;p++)buf[p]=undefined;\nbreak;\n}\ncase'bitset':{\nconst bits=this.#bits;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)bits.assign(remap[p],bits.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)bits.clear(p);\nbreak;\n}\ncase'multi':this.#mv.compact(remap,liveCount,REMOVED);break;\ndefault:break;\n}\nif(this.#presence){\nconst pres=this.#presence;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)pres.assign(remap[p],pres.get(p)===1);\nfor(let p=liveCount;p<oldFill;p++)pres.clear(p);\n}\nthis.#version++;\n}\nrelease(){\nif(this.#released)return;\nthis.#released=true;\nthis.#buf=null;\nif(this.#bits)this.#bits.release();\nthis.#bits=null;\nif(this.#mv)this.#mv.release();\nthis.#mv=null;\nif(this.#presence)this.#presence.release();\nthis.#presence=null;\nthis.#dict=null;\nthis.#stringRank=null;\nthis.#overlay=new Map();\nthis.#cache=null;\nthis.#capacity=0;\nthis.#version++;\n}\n#alloc(capacity){\nconst cap=Math.max(1,capacity);\nthis.#buf=null;\nthis.#bits=null;\nthis.#mv=null;\nswitch(this.#kind){\ncase'float64':this.#buf=new Float64Array(cap);break;\ncase'int32':this.#buf=new Int32Array(cap);break;\ncase'bitset':this.#bits=new Bitset(cap);break;\ncase'dictionary':\nthis.#buf=new Uint32Array(cap);\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ncase'multi':\nthis.#mv=new MultiValue({rows:cap,values:cap});\nthis.#dict=this.#dict??new Dictionary(this.#seed??[]);\nbreak;\ndefault:this.#buf=new Array(cap);break;\n}\nif(this.#kind!=='dictionary'&&this.#kind!=='multi')this.#dict=null;\nif(this.#nullable){\nif(this.#presence)this.#presence.grow(cap);\nelse this.#presence=new Bitset(cap);\n}\nthis.#capacity=cap;\n}\n#writeValue(p,value){\nconst gone=absent(value);\nif(this.#nullable)this.#presence.assign(p,!gone);\nelse if(gone){\nwarnOnce(`store.null.${this.#id}`,\n`column \"${this.#id}\" is declared non-nullable but received null; storing a filler value`);\n}\nswitch(this.#kind){\ncase'float64':this.#buf[p]=gone?NaN:toFloat(value);break;\ncase'int32':this.#buf[p]=gone?0:toInt(value);break;\ncase'bitset':this.#bits.assign(p,!gone&&!!value);break;\ncase'dictionary':this.#buf[p]=gone?0:this.#dict.codeOf(value);break;\ncase'multi':{\nconst members=toMembers(value);\nconst codes=new Array(members.length);\nfor(let i=0;i<members.length;i++)codes[i]=this.#dict.codeOf(members[i]);\nthis.#mv.write(p,codes);\nbreak;\n}\ndefault:this.#buf[p]=gone?null:value;break;\n}\n}\n#rowValue(p){\nif(this.#overlay.has(p))return this.#overlay.get(p);\nconst v=this.#read(this.#host.rowAt(p));\nreturn v===undefined?null:v;\n}\n#lazy(){\nif(this.#cache&&this.#cache.version===this.#version)return this.#cache;\nconst n=this.#host.physical();\nconst values=new Array(n);\nconst presence=this.#nullable?new Bitset(n):null;\nfor(let p=0;p<n;p++){\nconst v=this.#rowValue(p);\nvalues[p]=v;\nif(presence&&!absent(v))presence.set(p);\n}\nthis.#cache={version:this.#version,values,presence};\nreturn this.#cache;\n}\n}\nclass ColumnStore{\n#schema;\n#handles=new Map();\n#list=[];\n#rows=[];\n#fill=0;\n#capacity=0;\n#live=0;\n#dead=0;\n#tombs=new Bitset(0);\n#columnar=false;\n#retainSource=true;\n#columnarBelow;\n#initial;\n#ratio;\n#destroyed=false;\nconstructor(schema,opts={}){\nthis.#schema=Array.isArray(schema)?schema:[];\nthis.#initial=Math.max(1,opts.initialCapacity??DEFAULT_CAPACITY);\nthis.#retainSource=opts.retainSource!==false;\nthis.#columnarBelow=this.#retainSource?(opts.columnarBelow??DEFAULT_COLUMNAR_BELOW):0;\nthis.#ratio=opts.compactRatio??DEFAULT_COMPACT_RATIO;\nconst host={\nrowAt:(p)=>this.#rows[p],\nphysical:()=>this.#fill,\n};\nfor(const entry of this.#schema){\nif(!entry||!entry.id)continue;\nif(this.#handles.has(entry.id)){\nwarnOnce(`store.dup.${entry.id}`,`duplicate column id \"${entry.id}\" in the store schema; ignoring the second`);\ncontinue;\n}\nconst handle=new ColumnHandle(entry,host);\nthis.#handles.set(entry.id,handle);\nthis.#list.push(handle);\n}\nif(this.#columnarBelow<=0)this.#columnarise();\n}\nget count(){return this.#live;}\nget physical(){return this.#fill;}\nget capacity(){return this.#columnar?this.#capacity:this.#rows.length;}\nget tombstones(){return this.#dead;}\nget columnar(){return this.#columnar;}\nget destroyed(){return this.#destroyed;}\nget bytes(){\nlet total=this.#tombs.bytes+this.#rows.length*8;\nfor(const h of this.#list)total+=h.bytes;\nreturn total;\n}\nappend(objects){\nconst from=this.#fill;\nif(this.#destroyed||!objects)return{from,to:from};\nconst n=objects.length|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource)for(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar){\nif(this.#fill>=this.#columnarBelow)this.#columnarise();\nelse for(const h of this.#list)h.touch();\nreturn{from,to:this.#fill};\n}\nthis.#ensure(this.#fill);\nconst cols=this.#list;\nfor(let c=0;c<cols.length;c++)cols[c].appendColumn(objects,from,n);\nreturn{from,to:this.#fill};\n}\nappendPacked(chunk,objects){\nconst from=this.#fill;\nif(this.#destroyed||!chunk)return{from,to:from};\nconst n=chunk.count|0;\nif(n===0)return{from,to:from};\nif(this.#retainSource&&objects){\nfor(let i=0;i<n;i++)this.#rows[from+i]=objects[i];\n}\nthis.#fill=from+n;\nthis.#live+=n;\nthis.#tombs.grow(this.#fill);\nif(!this.#columnar)this.#columnarise();\nthis.#ensure(this.#fill);\nconst byId=new Map();\nfor(const col of chunk.columns)byId.set(col.id,col);\nfor(const h of this.#list){\nconst frag=byId.get(h.id);\nif(frag)h.appendPacked(frag,from,n);\nelse{\nh.grow(this.#capacity);\n}\n}\nreturn{from,to:this.#fill};\n}\nsource(physical){\nif(this.#retainSource)return this.#rows[physical];\nif(physical<0||physical>=this.#fill)return undefined;\nreturn this.#reconstruct(physical);\n}\nsetSource(physical,object){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nif(!this.#retainSource)return;\nthis.#rows[physical]=object;\n}\nget(colId,physical){\nconst h=this.#handles.get(colId);\nreturn h?h.get(physical):undefined;\n}\nset(colId,physical,value){\nif(this.#destroyed)return;\nif(physical<0||physical>=this.#fill)return;\nconst h=this.#handles.get(colId);\nif(!h){\nwarnOnce(`store.set.${colId}`,`set() on unknown column \"${colId}\"`);\nreturn;\n}\nh.set(physical,value);\n}\nremove(physical){\nif(this.#destroyed||physical<0||physical>=this.#fill)return false;\nif(this.#tombs.get(physical)===1)return false;\nthis.#tombs.set(physical);\nthis.#dead++;\nthis.#live--;\nreturn true;\n}\nlive(physical){\nif(physical<0||physical>=this.#fill)return false;\nreturn this.#tombs.get(physical)===0;\n}\ncompact(opts={}){\nif(this.#destroyed||this.#dead===0)return null;\nif(!opts.force&&this.#dead/this.#fill<this.#ratio)return null;\nconst oldFill=this.#fill;\nconst remap=new Uint32Array(oldFill);\nlet w=0;\nfor(let p=0;p<oldFill;p++)remap[p]=this.#tombs.get(p)===1?REMOVED:w++;\nfor(const h of this.#list)h.compact(remap,oldFill,w);\nif(this.#retainSource){\nconst rows=this.#rows;\nfor(let p=0;p<oldFill;p++)if(remap[p]!==REMOVED)rows[remap[p]]=rows[p];\nrows.length=w;\n}\nthis.#fill=w;\nthis.#live=w;\nthis.#dead=0;\nthis.#tombs=new Bitset(Math.max(this.#capacity,w));\nreturn remap;\n}\ncolumn(colId){return this.#handles.get(colId);}\ncolumns(){return this.#list.slice();}\nliveIndices(){\nconst out=new Uint32Array(this.#live);\nif(this.#dead===0){\nfor(let p=0;p<this.#fill;p++)out[p]=p;\nreturn out;\n}\nlet k=0;\nfor(let p=0;p<this.#fill;p++)if(this.#tombs.get(p)===0)out[k++]=p;\nreturn out;\n}\nconvert(colId,kind){\nconst h=this.#handles.get(colId);\nreturn h?h.convert(kind):false;\n}\ndestroy(){\nif(this.#destroyed)return;\nthis.#destroyed=true;\nfor(const h of this.#list)h.release();\nthis.#handles.clear();\nthis.#list.length=0;\nthis.#rows.length=0;\nthis.#tombs.release();\nthis.#fill=0;\nthis.#live=0;\nthis.#dead=0;\nthis.#capacity=0;\n}\n#ensure(n){\nif(n<=this.#capacity)return;\nlet cap=this.#capacity||this.#initial;\nwhile(cap<n)cap*=2;\nfor(const h of this.#list)h.grow(cap);\nthis.#tombs.grow(cap);\nthis.#capacity=cap;\n}\n#reconstruct(physical){\nconst out={};\nfor(const h of this.#list)out[h.id]=h.get(physical);\nreturn out;\n}\n#columnarise(){\nif(this.#columnar)return;\nlet cap=this.#initial;\nwhile(cap<this.#fill)cap*=2;\nthis.#columnar=true;\nthis.#capacity=cap;\nthis.#tombs.grow(cap);\nfor(const h of this.#list)h.columnarise(cap,this.#fill);\n}\n}\n});\n__def(\"packages/core/src/store/ingest.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"INGEST_DEFAULTS\",{enumerable:true,get:function(){return INGEST_DEFAULTS;}});\nObject.defineProperty(__exports,\"inferKind\",{enumerable:true,get:function(){return inferKind;}});\nObject.defineProperty(__exports,\"decideText\",{enumerable:true,get:function(){return decideText;}});\nObject.defineProperty(__exports,\"createReaders\",{enumerable:true,get:function(){return createReaders;}});\nObject.defineProperty(__exports,\"Ingest\",{enumerable:true,get:function(){return Ingest;}});\nObject.defineProperty(__exports,\"ingest\",{enumerable:true,get:function(){return ingest;}});\nObject.defineProperty(__exports,\"ingestSync\",{enumerable:true,get:function(){return ingestSync;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst now=__m0[\"now\"];\nconst nextFrame=__m0[\"nextFrame\"];\nconst infoOnce=__m0[\"infoOnce\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst isFunction=__m0[\"isFunction\"];\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/columnstore.js\");\nconst ColumnStore=__m1[\"ColumnStore\"];\nconst INGEST_DEFAULTS=Object.freeze({\nchunkMs:8,\nchunkRows:512,\nsampleSize:100,\ndictionaryRatio:0.1,\ncolumnarBelow:5000,\ninitialCapacity:1024,\n});\nfunction inferKind(samples,hints={}){\nif(hints.multi)return'multi';\nif(samples.length===0)return'object';\nlet numbers=0;let booleans=0;let strings=0;let dates=0;let arrays=0;\nfor(let i=0;i<samples.length;i++){\nconst v=samples[i];\nif(typeof v==='number')numbers++;\nelse if(typeof v==='boolean')booleans++;\nelse if(typeof v==='string')strings++;\nelse if(v instanceof Date)dates++;\nelse if(Array.isArray(v))arrays++;\n}\nconst n=samples.length;\nif(numbers===n)return'float64';\nif(booleans===n)return'bitset';\nif(dates===n)return'float64';\nif(strings===n)return'text';\nif(arrays===n)return'multi';\nreturn'object';\n}\nfunction decideText(distinct,rows,ratio){\nif(rows<=0)return'dictionary';\nreturn distinct<ratio*rows?'dictionary':'object';\n}\nfunction createReaders(columns,computed,context){\nconst readers=new Map();\nconst base=new Map();\nfor(const col of columns){\nif(col.computed)continue;\nconst read=isFunction(col.read)?col.read:pathGetter(col.field||col.id);\nbase.set(col.id,read);\nreaders.set(col.id,read);\n}\nconst order=computed?.order??[];\nconst fns=computed?.fns??{};\nconst deps=computed?.deps??{};\nconst wrapDeps=computed?.wrapDeps??null;\nconst active=order.filter((id)=>isFunction(fns[id]));\nconst wildcard=active.some((id)=>deps[id]==='*');\nlet memo=new WeakMap();\nconst resolve=(data)=>{\nconst values={};\nif(wildcard)for(const[id,read]of base)values[id]=read(data);\nfor(const id of active){\nconst declared=deps[id];\nlet bag;\nif(declared==='*'){\nbag=values;\n}else{\nbag={};\nconst list=declared||[];\nfor(let i=0;i<list.length;i++){\nconst d=list[i];\nbag[d]=d in values?values[d]:base.get(d)?.(data);\n}\n}\nvalues[id]=fns[id](wrapDeps?wrapDeps(bag,id):bag,{\ndata,row:null,column:null,grid:null,context,\n});\n}\nreturn values;\n};\nconst valuesFor=(data)=>{\nif(data===null||(typeof data!=='object'&&typeof data!=='function'))return resolve(data);\nlet v=memo.get(data);\nif(v===undefined){v=resolve(data);memo.set(data,v);}\nreturn v;\n};\nfor(const id of active){\nreaders.set(id,\n(data)=>valuesFor(data)[id]);\n}\nreturn{\nreaders,\nreset(){memo=new WeakMap();},\n};\n}\nclass ColumnPlan{\nspec;\nread;\nkind;\ninferred;\nnullable;\ncandidate=false;\ndistinct=null;\nchange=null;\nreason='';\nconstructor(spec,read){\nthis.spec=spec;\nthis.read=read;\nthis.kind='object';\nthis.inferred=false;\nthis.nullable=spec.nullable!==false;\n}\n}\nclass Ingest{\n#rows;\n#plans=[];\n#store=null;\n#readers;\n#cursor=0;\n#opts;\n#done=false;\n#cancelled=false;\n#elapsed=0;\n#columnar;\nconstructor(rows,plan={},opts={}){\nthis.#rows=Array.isArray(rows)?rows:Array.from(rows||[]);\nthis.#opts={...INGEST_DEFAULTS,...opts};\nconst columns=plan.columns??[];\nthis.#readers=createReaders(columns,plan.computed??null,plan.context);\nthis.#columnar=this.#rows.length>=this.#opts.columnarBelow;\nthis.#planColumns(columns,plan.computed??null);\nthis.#store=new ColumnStore(this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\nread:p.read,\ndictionary:p.spec.dictionary,\n})),{\ninitialCapacity:this.#opts.initialCapacity,\ncolumnarBelow:this.#opts.columnarBelow,\n});\n}\nget store(){return this.#store;}\nget done(){return this.#done||this.#cancelled;}\nget progress(){return this.#cursor;}\nslice(){\nif(this.done)return false;\nif(this.#opts.signal?.aborted){this.#cancelled=true;return false;}\nconst started=now();\nconst{chunkMs,chunkRows}=this.#opts;\nconst total=this.#rows.length;\ndo{\nconst end=Math.min(this.#cursor+chunkRows,total);\nthis.#store.append(this.#rows.slice(this.#cursor,end));\nthis.#measure(this.#cursor,end);\nthis.#cursor=end;\nthis.#readers.reset();\nthis.#reviewCardinality(false);\n}while(this.#cursor<total&&now()-started<chunkMs);\nthis.#elapsed+=now()-started;\nthis.#opts.onProgress?.({loaded:this.#cursor,total});\nif(this.#cursor>=total){\nthis.#reviewCardinality(true);\nthis.#done=true;\nreturn false;\n}\nreturn true;\n}\ncancel(){this.#cancelled=true;}\nresult(){\nreturn{\nstore:this.#store,\nschema:this.#plans.map((p)=>({\nid:p.spec.id,kind:p.kind,nullable:p.nullable,read:p.read,\ndictionary:p.spec.dictionary,\n})),\ndecisions:this.#plans.map((p)=>({\nid:p.spec.id,\nkind:p.kind,\nnullable:p.nullable,\ninferred:p.inferred,\ndistinct:p.candidate||p.change?this.#distinctOf(p):null,\nchange:p.change,\nreason:p.reason,\n})),\ncount:this.#store.count,\nelapsed:this.#elapsed,\ncancelled:this.#cancelled,\n};\n}\n#planColumns(columns,computed){\nconst rows=this.#rows;\nconst sampleN=Math.min(this.#opts.sampleSize,rows.length);\nconst ratio=this.#opts.dictionaryRatio;\nconst pure=computed?.pure instanceof Set\n?computed.pure\n:new Set(computed?.pure??computed?.order??[]);\nfor(const spec of columns){\nif(!spec||!spec.id)continue;\nif(spec.computed&&(spec.pure===false||(computed&&!pure.has(spec.id)))){\nwarnOnce(`ingest.impure.${spec.id}`,\n`column \"${spec.id}\" is an impure computed column and is not materialised into the store`);\ncontinue;\n}\nconst read=this.#readers.readers.get(spec.id)\n??(isFunction(spec.read)?spec.read:pathGetter(spec.field||spec.id));\nconst plan=new ColumnPlan(spec,read);\nif(spec.kind){\nplan.kind=spec.kind;\nplan.reason='declared by the caller';\n}else if(spec.dictionary){\nplan.kind=spec.multi?'multi':'dictionary';\nplan.reason='value table supplied (lookup column)';\n}else{\nconst samples=[];\nfor(let i=0;i<sampleN&&samples.length<this.#opts.sampleSize;i++){\nconst v=read(rows[i]);\nif(v!==null&&v!==undefined)samples.push(v);\n}\nplan.inferred=true;\nconst kind=inferKind(samples,{multi:spec.multi});\nif(kind==='text'){\nconst distinct=new Set(samples).size;\nplan.kind=decideText(distinct,samples.length,ratio);\nplan.candidate=this.#columnar;\nplan.reason=`sampled ${distinct} distinct in ${samples.length}`;\n}else{\nplan.kind=kind;\nplan.reason=`inferred from ${samples.length} sampled values`;\nif(kind==='object'&&samples.length){\ninfoOnce(`ingest.mixed.${spec.id}`,\n`column \"${spec.id}\" holds mixed or unrecognised value types; storing as an object array. Declare a type to avoid this.`);\n}\n}\nif(plan.kind==='object'&&plan.candidate)plan.distinct=new Set(samples);\n}\nthis.#plans.push(plan);\n}\n}\n#measure(from,to){\nconst rows=this.#rows;\nfor(const plan of this.#plans){\nif(!plan.candidate||!plan.distinct)continue;\nconst set=plan.distinct;\nfor(let i=from;i<to;i++){\nconst v=plan.read(rows[i]);\nif(v!==null&&v!==undefined)set.add(v);\n}\n}\n}\n#distinctOf(plan){\nif(plan.distinct)return plan.distinct.size;\nconst handle=this.#store.column(plan.spec.id);\nreturn handle?.dict?handle.dict.size:0;\n}\n#reviewCardinality(final){\nconst ratio=this.#opts.dictionaryRatio;\nconst total=this.#rows.length;\nfor(const plan of this.#plans){\nif(!plan.candidate)continue;\nconst distinct=this.#distinctOf(plan);\nif(plan.kind==='dictionary'&&distinct>=ratio*total){\nconst handle=this.#store.column(plan.spec.id);\nplan.distinct=new Set(handle?.dict?handle.dict.values():[]);\nthis.#store.convert(plan.spec.id,'object');\nplan.kind='object';\nplan.change='demoted';\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(plan.kind==='object'&&distinct>=ratio*total){\nplan.candidate=false;\nplan.distinct=null;\nplan.reason=`${distinct} distinct values is at or above ${ratio*100}% of ${total} rows`;\ncontinue;\n}\nif(final&&plan.kind==='object'&&distinct<ratio*total){\nthis.#store.convert(plan.spec.id,'dictionary');\nplan.kind='dictionary';\nplan.change=plan.change==='demoted'?null:'promoted';\nplan.reason=`${distinct} distinct values is below ${ratio*100}% of ${total} rows`;\nplan.distinct=null;\n}\nif(final)plan.candidate=false;\n}\n}\n}\nasync function ingest(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,opts);\nconst frame=opts.scheduler?.frame??nextFrame;\nwhile(run.slice()){\nawait new Promise((resolve)=>{frame(resolve);});\n}\nreturn run.result();\n}\nfunction ingestSync(rows,plan={},opts={}){\nconst run=new Ingest(rows,plan,{...opts,chunkMs:Infinity});\nwhile(run.slice());\nreturn run.result();\n}\n});\n__def(\"packages/core/src/store/columnpack.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"isPortableSchema\",{enumerable:true,get:function(){return isPortableSchema;}});\nObject.defineProperty(__exports,\"packChunk\",{enumerable:true,get:function(){return packChunk;}});\nObject.defineProperty(__exports,\"packedTransfers\",{enumerable:true,get:function(){return packedTransfers;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst pathGetter=__m0[\"pathGetter\"];\nconst __m1=__req(\"packages/core/src/store/ingest.js\");\nconst inferKind=__m1[\"inferKind\"];\nconst decideText=__m1[\"decideText\"];\nconst INGEST_DEFAULTS=__m1[\"INGEST_DEFAULTS\"];\nconst __m2=__req(\"packages/core/src/store/columnstore.js\");\nconst toFloat=__m2[\"toFloat\"];\nconst PORTABLE_KINDS=new Set(['float64','int32','bitset','dictionary','object','multi']);\nfunction isPortableSchema(schema){\nif(!Array.isArray(schema)||schema.length===0)return false;\nfor(const col of schema){\nif(!col||typeof col.id!=='string')return false;\nif(typeof col.field!=='string'||col.field==='')return false;\nif(col.kind&&!PORTABLE_KINDS.has(col.kind))return false;\n}\nreturn true;\n}\nfunction toInt(v){\nconst n=toFloat(v);\nreturn Number.isFinite(n)?n|0:0;\n}\nfunction toMembers(v){\nif(v===null||v===undefined)return[];\nreturn Array.isArray(v)?v:[v];\n}\nfunction resolveKind(col,values,rows,ratio){\nif(col.kind)return col.kind;\nconst samples=[];\nfor(let i=0;i<values.length&&samples.length<INGEST_DEFAULTS.sampleSize;i++){\nconst v=values[i];\nif(v!==null&&v!==undefined)samples.push(v);\n}\nconst kind=inferKind(samples,{multi:col.multi});\nif(kind!=='text')return kind;\nconst distinct=new Set(samples).size;\nreturn decideText(distinct,samples.length,ratio);\n}\nfunction packChunk(schema,rows,opts={}){\nconst n=rows.length|0;\nconst ratio=opts.dictionaryRatio??INGEST_DEFAULTS.dictionaryRatio;\nconst columns=[];\nfor(const col of schema){\nconst read=pathGetter(col.field||col.id);\nconst nullable=col.nullable!==false;\nconst raw=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=read(rows[i]);\nraw[i]=v===undefined?null:v;\n}\nconst kind=resolveKind(col,raw,n,ratio);\nconst presence=nullable?new Uint8Array((n+7)>>3):null;\nconst present=(i)=>{if(presence)presence[i>>3]|=1<<(i&7);};\nlet packed;\nswitch(kind){\ncase'float64':{\nconst values=new Float64Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?NaN:toFloat(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'int32':{\nconst values=new Int32Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nvalues[i]=gone?0:toInt(v);\n}\npacked={id:col.id,kind,nullable,values,presence,offsets:null,table:null};\nbreak;\n}\ncase'bitset':{\nconst words=new Uint8Array((n+7)>>3);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nconst gone=v===null;\nif(!gone)present(i);\nif(!gone&&!!v)words[i>>3]|=1<<(i&7);\n}\npacked={id:col.id,kind,nullable,values:words,presence,offsets:null,table:null};\nbreak;\n}\ncase'dictionary':{\nconst codes=new Uint32Array(n);\nconst table=[];\nconst index=new Map();\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v===null){codes[i]=0;continue;}\npresent(i);\nlet code=index.get(v);\nif(code===undefined){code=table.length;table.push(v);index.set(v,code);}\ncodes[i]=code;\n}\npacked={id:col.id,kind,nullable,values:codes,presence,offsets:null,table};\nbreak;\n}\ncase'multi':{\nconst table=[];\nconst index=new Map();\nconst offsets=new Uint32Array(n+1);\nconst flat=[];\nfor(let i=0;i<n;i++){\nconst v=raw[i];\noffsets[i]=flat.length;\nconst gone=v===null;\nif(!gone)present(i);\nconst members=toMembers(v);\nfor(let k=0;k<members.length;k++){\nconst m=members[k];\nlet code=index.get(m);\nif(code===undefined){code=table.length;table.push(m);index.set(m,code);}\nflat.push(code);\n}\n}\noffsets[n]=flat.length;\npacked={id:col.id,kind,nullable,values:Int32Array.from(flat),presence,offsets,table};\nbreak;\n}\ndefault:{\nconst values=new Array(n);\nfor(let i=0;i<n;i++){\nconst v=raw[i];\nif(v!==null)present(i);\nvalues[i]=v;\n}\npacked={id:col.id,kind:'object',nullable,values,presence,offsets:null,table:null};\nbreak;\n}\n}\ncolumns.push(packed);\n}\nreturn{count:n,columns};\n}\nfunction packedTransfers(chunk){\nconst out=[];\nif(!chunk||!Array.isArray(chunk.columns))return out;\nconst add=(v)=>{\nif(ArrayBuffer.isView(v)&&v.buffer&&!out.includes(v.buffer))out.push(v.buffer);\n};\nfor(const col of chunk.columns){\nadd(col.values);\nadd(col.presence);\nadd(col.offsets);\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/format/date.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"scanPattern\",{enumerable:true,get:function(){return scanPattern;}});\nObject.defineProperty(__exports,\"toDate\",{enumerable:true,get:function(){return toDate;}});\nObject.defineProperty(__exports,\"compilePattern\",{enumerable:true,get:function(){return compilePattern;}});\nObject.defineProperty(__exports,\"compileDate\",{enumerable:true,get:function(){return compileDate;}});\nObject.defineProperty(__exports,\"toIsoDate\",{enumerable:true,get:function(){return toIsoDate;}});\nObject.defineProperty(__exports,\"toIsoDateTime\",{enumerable:true,get:function(){return toIsoDateTime;}});\nObject.defineProperty(__exports,\"compareIso\",{enumerable:true,get:function(){return compareIso;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isNil=__m0[\"isNil\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst TOKENS=[\n'yyyy','yy','MMMM','MMM','MM','M','dd','d',\n'EEEE','EEE','HH','H','hh','h','mm','m','ss','s','SSS','a',\n];\nfunction scanPattern(pattern){\nconst out=[];\nlet i=0;\nlet literal='';\nconst flush=()=>{if(literal){out.push({token:null,text:literal});literal='';}};\nwhile(i<pattern.length){\nconst ch=pattern[i];\nif(ch===\"'\"){\nif(pattern[i+1]===\"'\"){literal+=\"'\";i+=2;continue;}\nconst end=pattern.indexOf(\"'\",i+1);\nif(end===-1){literal+=pattern.slice(i+1);i=pattern.length;continue;}\nliteral+=pattern.slice(i+1,end);\ni=end+1;\ncontinue;\n}\nconst token=TOKENS.find((t)=>pattern.startsWith(t,i));\nif(token){flush();out.push({token,text:token});i+=token.length;continue;}\nif(/[A-Za-z]/.test(ch)){\nwarnOnce(\n`date.pattern.token:${ch}`,\n`the date pattern \"${pattern}\" contains '${ch}', which is not a supported token, `\n+'so it is rendered as text. Quote it as a literal to silence this. '\n+`Supported: ${TOKENS.join(' ')}.`,\n);\n}\nliteral+=ch;\ni+=1;\n}\nflush();\nreturn out;\n}\nconst WALL_CLOCK=/^(\\d{4})-(\\d{2})-(\\d{2})(?:[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?(?:\\.\\d+)?)?$/;\nfunction toDate(value){\nif(isNil(value)||value==='')return null;\nif(value instanceof Date)return Number.isNaN(value.getTime())?null:value;\nif(typeof value==='number')return Number.isNaN(value)?null:new Date(value);\nif(typeof value==='string'){\nconst wall=WALL_CLOCK.exec(value.trim());\nif(wall){\nconst[,y,mo,d,h='0',mi='0',sec='0']=wall;\nreturn new Date(+y,+mo-1,+d,+h,+mi,+sec);\n}\nconst d=new Date(value);\nreturn Number.isNaN(d.getTime())?null:d;\n}\nreturn null;\n}\nfunction pad(n,w){return String(n).padStart(w,'0');}\nfunction fieldReader(timeZone){\nif(!timeZone){\nreturn(d)=>({\nyear:d.getFullYear(),month:d.getMonth()+1,day:d.getDate(),\nhour:d.getHours(),minute:d.getMinutes(),second:d.getSeconds(),\nms:d.getMilliseconds(),weekday:d.getDay(),\n});\n}\nconst zoned=new Intl.DateTimeFormat('en-US',{\ntimeZone,year:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false,weekday:'short',\n});\nconst days={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};\nreturn(d)=>{\nconst f={year:0,month:1,day:1,hour:0,minute:0,second:0,ms:d.getMilliseconds(),weekday:0};\nfor(const part of zoned.formatToParts(d)){\nswitch(part.type){\ncase'year':f.year=Number(part.value);break;\ncase'month':f.month=Number(part.value);break;\ncase'day':f.day=Number(part.value);break;\ncase'hour':f.hour=Number(part.value)%24;break;\ncase'minute':f.minute=Number(part.value);break;\ncase'second':f.second=Number(part.value);break;\ncase'weekday':f.weekday=days[part.value]??0;break;\ndefault:break;\n}\n}\nreturn f;\n};\n}\nfunction compilePattern(pattern,locale,timeZone){\nconst segments=scanPattern(pattern);\nconst read=fieldReader(timeZone);\nconst used=new Set(segments.filter((s)=>s.token).map((s)=>s.token));\nconst monthShort=used.has('MMM')?new Intl.DateTimeFormat(locale,{month:'short',timeZone}):null;\nconst monthLong=used.has('MMMM')?new Intl.DateTimeFormat(locale,{month:'long',timeZone}):null;\nconst dayShort=used.has('EEE')?new Intl.DateTimeFormat(locale,{weekday:'short',timeZone}):null;\nconst dayLong=used.has('EEEE')?new Intl.DateTimeFormat(locale,{weekday:'long',timeZone}):null;\nreturn(d)=>{\nconst f=read(d);\nlet out='';\nfor(const seg of segments){\nif(!seg.token){out+=seg.text;continue;}\nswitch(seg.token){\ncase'yyyy':out+=pad(f.year,4);break;\ncase'yy':out+=pad(f.year%100,2);break;\ncase'MMMM':out+=monthLong.format(d);break;\ncase'MMM':out+=monthShort.format(d);break;\ncase'MM':out+=pad(f.month,2);break;\ncase'M':out+=String(f.month);break;\ncase'dd':out+=pad(f.day,2);break;\ncase'd':out+=String(f.day);break;\ncase'EEEE':out+=dayLong.format(d);break;\ncase'EEE':out+=dayShort.format(d);break;\ncase'HH':out+=pad(f.hour,2);break;\ncase'H':out+=String(f.hour);break;\ncase'hh':out+=pad(f.hour%12===0?12:f.hour%12,2);break;\ncase'h':out+=String(f.hour%12===0?12:f.hour%12);break;\ncase'mm':out+=pad(f.minute,2);break;\ncase'm':out+=String(f.minute);break;\ncase'ss':out+=pad(f.second,2);break;\ncase's':out+=String(f.second);break;\ncase'SSS':out+=pad(f.ms,3);break;\ncase'a':out+=f.hour<12?'AM':'PM';break;\ndefault:out+=seg.text;break;\n}\n}\nreturn out;\n};\n}\nconst UNITS=[\n['year',365*24*3600e3],\n['month',30*24*3600e3],\n['week',7*24*3600e3],\n['day',24*3600e3],\n['hour',3600e3],\n['minute',60e3],\n['second',1e3],\n];\nfunction compileDate(spec,locale){\nconst s=spec||{};\nconst loc=s.locale||locale||undefined;\nconst nullDisplay=s.nullDisplay??'';\nconst timeZone=s.timeZone;\nlet absolute;\nif(s.pattern){\nabsolute=compilePattern(s.pattern,loc,timeZone);\n}else if(s.dateStyle||s.timeStyle){\nconst opts={timeZone};\nif(s.dateStyle)opts.dateStyle=s.dateStyle;\nif(s.timeStyle)opts.timeStyle=s.timeStyle;\nconst dtf=new Intl.DateTimeFormat(loc,opts);\nabsolute=(d)=>dtf.format(d);\n}else{\nconst dtf=new Intl.DateTimeFormat(loc,{dateStyle:'medium',timeZone});\nabsolute=(d)=>dtf.format(d);\n}\nconst relative=s.relative?new Intl.RelativeTimeFormat(loc,{numeric:'auto'}):null;\nconst thresholdDays=typeof s.relative==='object'&&s.relative\n?(s.relative.threshold??7)\n:7;\nconst thresholdMs=thresholdDays*24*3600e3;\nconst format=(value,params)=>{\nconst d=toDate(value);\nif(!d)return nullDisplay;\nif(relative){\nconst now=params&&typeof params.now==='number'?params.now:Date.now();\nconst delta=d.getTime()-now;\nif(Math.abs(delta)<thresholdMs){\nfor(const[unit,ms]of UNITS){\nif(Math.abs(delta)>=ms||unit==='second'){\nreturn relative.format(Math.round(delta/ms),unit);\n}\n}\n}\n}\nreturn absolute(d);\n};\nformat.spec=s;\nreturn format;\n}\nfunction toIsoDate(value){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst match=/^(\\d{4}-\\d{2}-\\d{2})/.exec(value.trim());\nif(match)return match[1];\nconst parsed=toDate(value);\nreturn parsed?toIsoDate(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nconst pad=(n)=>String(n).padStart(2,'0');\nreturn`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\n}\nfunction toIsoDateTime(value,timeZone){\nif(isNil(value)||value==='')return null;\nif(typeof value==='string'){\nconst text=value.trim();\nif(ZONE_SUFFIX.test(text)){\nconst instant=toDate(text);\nreturn instant?wallClockIn(instant,timeZone):null;\n}\nconst match=/^(\\d{4}-\\d{2}-\\d{2})[T ](\\d{2}):(\\d{2})(?::(\\d{2}))?/.exec(text);\nif(match){\nconst[,day,hour,minute,second]=match;\nreturn`${day}T${hour}:${minute}${second&&second!=='00'?`:${second}`:''}`;\n}\nif(/^\\d{4}-\\d{2}-\\d{2}$/.test(text))return`${text}T00:00`;\nconst parsed=toDate(text);\nreturn parsed?toIsoDateTime(parsed):null;\n}\nconst date=toDate(value);\nif(!date)return null;\nreturn wallClockIn(date,timeZone);\n}\nconst ZONE_SUFFIX=/(?:Z|[+-]\\d{2}:?\\d{2})$/i;\nfunction wallClockIn(date,timeZone){\nconst pad=(n)=>String(n).padStart(2,'0');\nif(timeZone){\ntry{\nconst parts=new Intl.DateTimeFormat('en-CA',{\ntimeZone,\nyear:'numeric',month:'2-digit',day:'2-digit',\nhour:'2-digit',minute:'2-digit',second:'2-digit',\nhour12:false,\n}).formatToParts(date).reduce((out,part)=>{\nif(part.type!=='literal')out[part.type]=part.value;\nreturn out;\n},{});\nconst hour=parts.hour==='24'?'00':parts.hour;\nconst seconds=Number(parts.second);\nreturn`${parts.year}-${parts.month}-${parts.day}T${hour}:${parts.minute}`\n+(seconds?`:${parts.second}`:'');\n}catch{\n}\n}\nconst day=`${date.getFullYear()}-${pad(date.getMonth()+1)}-${pad(date.getDate())}`;\nconst seconds=date.getSeconds();\nconst clock=`${pad(date.getHours())}:${pad(date.getMinutes())}${seconds?`:${pad(seconds)}`:''}`;\nreturn`${day}T${clock}`;\n}\nfunction compareIso(a,b){\nconst left=isNil(a)||a===''?null:String(a);\nconst right=isNil(b)||b===''?null:String(b);\nif(left===null)return right===null?0:1;\nif(right===null)return-1;\nreturn left<right?-1:left>right?1:0;\n}\n});\n__def(\"packages/core/src/compute/filter.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return releaseMask;}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return compilePredicate;}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return testValue;}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return evaluateCondition;}});\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return evaluateFilters;}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return pruneColumn;}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return mentionsColumn;}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return compact;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isBlank=__m0[\"isBlank\"];\nconst toArray=__m0[\"toArray\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/format/date.js\");\nconst toIsoDate=__m1[\"toIsoDate\"];\nconst __m2=__req(\"packages/core/src/compute/handle.js\");\nconst bitReader=__m2[\"bitReader\"];\nconst dictSize=__m2[\"dictSize\"];\nconst dictValue=__m2[\"dictValue\"];\nconst presenceReader=__m2[\"presenceReader\"];\nconst valueComparator=__m2[\"valueComparator\"];\nconst valueReader=__m2[\"valueReader\"];\nconst ISO_DAY=/^\\d{4}-\\d{2}-\\d{2}$/;\nconst NULL_KEY='\\u0000null\\u0000';\nfunction acquireMask(ctx,n){\nconst pool=ctx&&ctx.pool;\nif(pool){\nconst take=pool.mask||pool.acquireMask||pool.acquire||pool.take;\nif(typeof take==='function'){\nconst mask=take.call(pool,n);\nif(mask&&mask.length>=n)return mask;\n}\n}\nreturn new Uint8Array(n);\n}\nfunction releaseMask(ctx,mask){\nconst pool=ctx&&ctx.pool;\nif(!pool||!mask)return;\nconst give=pool.release||pool.releaseMask||pool.free||pool.recycle;\nif(typeof give==='function')give.call(pool,mask);\n}\nfunction fillMask(mask,n,value){\nmask.fill(value,0,n);\nreturn mask;\n}\nfunction unorderable(v){\nreturn v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));\n}\nfunction coerceTarget(value,type){\nif(value===null||value===undefined)return value;\nif(type==='number')return typeof value==='number'?value:Number(value);\nif(type==='date'||type==='dateString'){\nconst iso=toIsoDate(value);\nreturn iso===null?toMillis(value):iso;\n}\nif(type==='boolean'){\nif(typeof value==='boolean')return value;\nif(value==='true'||value===1)return true;\nif(value==='false'||value===0)return false;\nreturn!!value;\n}\nreturn value;\n}\nfunction toMillis(value){\nif(value instanceof Date)return value.getTime();\nif(typeof value==='number')return value;\nreturn Date.parse(String(value));\n}\nfunction toNumber(value){\nif(typeof value==='number')return value;\nif(value instanceof Date)return value.getTime();\nif(value===null||value===undefined||value==='')return NaN;\nreturn Number(value);\n}\nfunction textOf(v,caseSensitive){\nconst s=typeof v==='string'?v:String(v);\nreturn caseSensitive?s:s.toLowerCase();\n}\nfunction setKey(v,caseSensitive){\nif(v===null||v===undefined)return NULL_KEY;\nif(typeof v==='string')return caseSensitive?v:v.toLowerCase();\nif(v instanceof Date)return v.getTime();\nreturn v;\n}\nfunction buildSet(value,caseSensitive,type){\nconst set=new Set();\nfor(const raw of toArray(value)){\nconst entry=coerceTarget(raw,type);\nset.add(setKey(entry,caseSensitive));\nif(typeof entry==='string'&&entry!==''&&Number.isFinite(Number(entry)))set.add(Number(entry));\nelse if(typeof entry==='number'&&Number.isFinite(entry))set.add(setKey(String(entry),caseSensitive));\n}\nreturn set;\n}\nfunction valueEquals(a,b,caseSensitive){\nif(a===null||a===undefined||b===null||b===undefined){\nreturn(a===null||a===undefined)&&(b===null||b===undefined);\n}\nconst ta=typeof a;\nconst tb=typeof b;\nif(ta==='string'&&tb==='string')return caseSensitive?a===b:a.toLowerCase()===b.toLowerCase();\nif(a instanceof Date||b instanceof Date)return toMillis(a)===toMillis(b);\nif(ta==='number'&&tb==='number')return a===b||(Number.isNaN(a)&&Number.isNaN(b));\nif(ta==='number'&&tb==='string')return a===Number(b);\nif(ta==='string'&&tb==='number')return Number(a)===b;\nif(ta==='boolean'||tb==='boolean')return a===b;\nif(Array.isArray(a)&&Array.isArray(b)){\nreturn a.length===b.length&&a.every((x,i)=>valueEquals(x,b[i],caseSensitive));\n}\nreturn a===b;\n}\nfunction compileRegExp(value,caseSensitive){\ntry{\nif(value instanceof RegExp){\nconst flags=value.flags.replace(/[gy]/g,'');\nreturn new RegExp(value.source,caseSensitive?flags:flags.includes('i')?flags:`${flags}i`);\n}\nreturn new RegExp(String(value),caseSensitive?'':'i');\n}catch(err){\nwarnOnce(`regex:${String(value)}`,`filter operator \"matches\" received an invalid pattern: ${String(value)}`,err);\nreturn null;\n}\n}\nfunction compilePredicate(condition,locale){\nconst predicate=compileValuePredicate(condition,locale);\nconst type=condition&&condition.type;\nif(type!=='date'&&type!=='dateString')return predicate;\nreturn(v)=>predicate(typeof v==='string'&&ISO_DAY.test(v)?v:(toIsoDate(v)??v));\n}\nfunction compileValuePredicate(condition,locale){\nconst op=condition&&condition.op;\nconst caseSensitive=!!(condition&&condition.caseSensitive);\nconst type=condition&&condition.type;\nconst cmp=valueComparator(locale);\nconst not=(p)=>(v)=>!p(v);\nswitch(op){\ncase'eq':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>valueEquals(v,target,caseSensitive);\n}\ncase'ne':{\nconst target=coerceTarget(condition.value,type);\nreturn(v)=>!valueEquals(v,target,caseSensitive);\n}\ncase'lt':case'lte':case'gt':case'gte':{\nconst target=coerceTarget(condition.value,type);\nif(unorderable(target))return()=>false;\nconst want=op==='lt'?-1:op==='lte'?0:op==='gt'?1:2;\nreturn(v)=>{\nif(unorderable(v))return false;\nconst c=cmp(v,target);\nreturn want===-1?c<0:want===0?c<=0:want===1?c>0:c>=0;\n};\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=coerceTarget(pair[0],type);\nconst hi=coerceTarget(pair[1],type);\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nif(unorderable(lo)||unorderable(hi))return op==='between'?()=>false:()=>true;\nconst inRange=(v)=>{\nif(unorderable(v))return false;\nconst a=cmp(v,lo);\nconst b=cmp(v,hi);\nreturn(loInclusive?a>=0:a>0)&&(hiInclusive?b<=0:b<0);\n};\nreturn op==='between'?inRange:not(inRange);\n}\ncase'in':case'notIn':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst member=(v)=>set.has(setKey(v,caseSensitive));\nreturn op==='in'?member:not(member);\n}\ncase'contains':case'notContains':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nconst has=(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).includes(needle));\nreturn op==='contains'?has:not(has);\n}\ncase'startsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).startsWith(needle));\n}\ncase'endsWith':{\nconst needle=textOf(coerceTarget(condition.value,type),caseSensitive);\nreturn(v)=>(v===null||v===undefined?false:textOf(v,caseSensitive).endsWith(needle));\n}\ncase'matches':{\nconst re=compileRegExp(condition.value,caseSensitive);\nif(!re)return()=>false;\nreturn(v)=>(v===null||v===undefined?false:re.test(String(v)));\n}\ncase'blank':\nreturn(v)=>isBlank(v)||(Array.isArray(v)&&v.length===0);\ncase'notBlank':\nreturn(v)=>!(isBlank(v)||(Array.isArray(v)&&v.length===0));\ncase'containsAny':case'containsNone':{\nconst set=buildSet(condition.value,caseSensitive,type);\nconst any=(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nfor(let i=0;i<list.length;i++)if(set.has(setKey(list[i],caseSensitive)))return true;\nreturn false;\n};\nreturn op==='containsAny'?any:not(any);\n}\ncase'containsAll':{\nconst wanted=toArray(condition.value).map((x)=>setKey(coerceTarget(x,type),caseSensitive));\nreturn(v)=>{\nconst list=v===null||v===undefined?[]:toArray(v);\nif(wanted.length===0)return true;\nconst have=new Set(list.map((x)=>setKey(x,caseSensitive)));\nfor(let i=0;i<wanted.length;i++)if(!have.has(wanted[i]))return false;\nreturn true;\n};\n}\ndefault:\nwarnOnce(`op:${String(op)}`,`unknown filter operator \"${String(op)}\"; the condition passes every row`);\nreturn()=>true;\n}\n}\nfunction testValue(value,condition,locale){\nreturn compilePredicate(condition,locale)(value);\n}\nfunction presenceCondition(handle,wantPresent,mask,count){\nconst present=presenceReader(handle);\nif(present){\nconst target=wantPresent?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===target?1:0;\nreturn mask;\n}\nconst kind=handle.kind;\nif(kind==='float64'||kind==='int32'||kind==='bitset'){\nreturn fillMask(mask,count,wantPresent?1:0);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++){\nconst v=read(i);\nconst blank=isBlank(v)||(Array.isArray(v)&&v.length===0);\nmask[i]=blank===wantPresent?0:1;\n}\nreturn mask;\n}\nfunction dictionaryCondition(handle,pred,mask,count){\nconst dict=handle.dict;\nconst size=dictSize(dict);\nconst allowed=new Uint8Array(size);\nfor(let code=0;code<size;code++)allowed[code]=pred(dictValue(dict,code))?1:0;\nconst codes=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=allowed[codes[i]];\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)mask[i]=present(i)===1?allowed[codes[i]]:absentAnswer;\nreturn mask;\n}\nfunction booleanCondition(handle,pred,mask,count){\nconst bit=bitReader(handle.values);\nconst whenTrue=pred(true)?1:0;\nconst whenFalse=pred(false)?1:0;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<count;i++)mask[i]=bit(i)===1?whenTrue:whenFalse;\nreturn mask;\n}\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++){\nmask[i]=present(i)===0?absentAnswer:(bit(i)===1?whenTrue:whenFalse);\n}\nreturn mask;\n}\nfunction numericCondition(handle,condition,pred,mask,count){\nconst values=handle.values;\nconst type=condition.type;\nconst op=condition.op;\nlet handled=true;\nswitch(op){\ncase'eq':case'ne':{\nconst target=toNumber(coerceTarget(condition.value,type));\nconst wantNaN=typeof condition.value==='number'&&Number.isNaN(condition.value);\nconst invert=op==='ne'?1:0;\nif(wantNaN){\nfor(let i=0;i<count;i++)mask[i]=(Number.isNaN(values[i])?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=((values[i]===target)?1:0)^invert;\n}\nbreak;\n}\ncase'lt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<t?1:0;\nbreak;\n}\ncase'lte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]<=t?1:0;\nbreak;\n}\ncase'gt':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>t?1:0;\nbreak;\n}\ncase'gte':{\nconst t=toNumber(coerceTarget(condition.value,type));\nfor(let i=0;i<count;i++)mask[i]=values[i]>=t?1:0;\nbreak;\n}\ncase'between':case'notBetween':{\nconst pair=toArray(condition.value);\nconst lo=toNumber(coerceTarget(pair[0],type));\nconst hi=toNumber(coerceTarget(pair[1],type));\nconst bounds=condition.bounds||'[]';\nconst loInclusive=bounds.charAt(0)!=='(';\nconst hiInclusive=bounds.charAt(1)!==')';\nconst invert=op==='notBetween'?1:0;\nif(loInclusive&&hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<=hi))?1:0)^invert;\n}else if(loInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>=lo)&(values[i]<hi))?1:0)^invert;\n}else if(hiInclusive){\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<=hi))?1:0)^invert;\n}else{\nfor(let i=0;i<count;i++)mask[i]=(((values[i]>lo)&(values[i]<hi))?1:0)^invert;\n}\nbreak;\n}\ncase'in':case'notIn':{\nconst set=new Set();\nfor(const raw of toArray(condition.value)){\nconst n=toNumber(coerceTarget(raw,type));\nif(!Number.isNaN(n))set.add(n);\n}\nconst invert=op==='notIn'?1:0;\nfor(let i=0;i<count;i++)mask[i]=(set.has(values[i])?1:0)^invert;\nbreak;\n}\ndefault:\nhandled=false;\nbreak;\n}\nif(!handled)return false;\nconst present=presenceReader(handle);\nif(present){\nconst absentAnswer=pred(null)?1:0;\nfor(let i=0;i<count;i++)if(present(i)===0)mask[i]=absentAnswer;\n}\nreturn true;\n}\nfunction genericCondition(handle,pred,mask,count){\nconst read=valueReader(handle);\nfor(let i=0;i<count;i++)mask[i]=pred(read(i))?1:0;\nreturn mask;\n}\nfunction evaluateCondition(condition,ctx,out){\nconst count=ctx.count|0;\nconst mask=out||acquireMask(ctx,count);\nif(!condition)return fillMask(mask,count,1);\nconst handle=typeof ctx.handle==='function'?ctx.handle(condition.col):undefined;\nconst custom=typeof ctx.custom==='function'?ctx.custom:null;\nif(!handle){\nif(custom){\nfor(let i=0;i<count;i++)mask[i]=custom(condition,i)?1:0;\nreturn mask;\n}\nwarnOnce(`filter:col:${String(condition.col)}`,\n`filter references unknown column \"${String(condition.col)}\"; the condition passes every row`);\nreturn fillMask(mask,count,1);\n}\nconst op=condition.op;\nif(op==='blank'||op==='notBlank')return presenceCondition(handle,op==='notBlank',mask,count);\nconst pred=compilePredicate(condition,ctx.locale);\nswitch(handle.kind){\ncase'dictionary':\nreturn dictionaryCondition(handle,pred,mask,count);\ncase'bitset':\nreturn booleanCondition(handle,pred,mask,count);\ncase'float64':case'int32':\nif(numericCondition(handle,condition,pred,mask,count))return mask;\nreturn genericCondition(handle,pred,mask,count);\ndefault:\nreturn genericCondition(handle,pred,mask,count);\n}\n}\nfunction evaluateNode(node,ctx,count){\nif(!node)return fillMask(acquireMask(ctx,count),count,1);\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(children.length===0)return fillMask(acquireMask(ctx,count),count,1);\nconst acc=evaluateNode(children[0],ctx,count);\nfor(let k=1;k<children.length;k++){\nconst rhs=evaluateNode(children[k],ctx,count);\nif(op==='or')for(let i=0;i<count;i++)acc[i]|=rhs[i];\nelse for(let i=0;i<count;i++)acc[i]&=rhs[i];\nreleaseMask(ctx,rhs);\n}\nif(op==='not')for(let i=0;i<count;i++)acc[i]^=1;\nreturn acc;\n}\nreturn evaluateCondition(node,ctx,acquireMask(ctx,count));\n}\nfunction evaluateFilters(filters,ctx){\nreturn evaluateNode(filters,ctx,ctx.count|0);\n}\nfunction pruneColumn(filters,colId){\nif(!filters||!colId)return filters||null;\nconst node=(filters);\nif(Array.isArray(node.conditions)){\nconst op=node.op==='or'?'or':node.op==='not'?'not':'and';\nif(op!=='and'){\nreturn mentionsColumn(node,colId)?null:filters;\n}\nconst kept=[];\nfor(const child of node.conditions){\nconst pruned=pruneColumn(child,colId);\nif(pruned)kept.push(pruned);\n}\nif(!kept.length)return null;\nreturn{...node,op:'and',conditions:kept};\n}\nreturn node.col===colId?null:filters;\n}\nfunction mentionsColumn(filters,colId){\nif(!filters||typeof filters!=='object')return false;\nconst node=(filters);\nif(node.col===colId)return true;\nif(Array.isArray(node.conditions)){\nfor(const child of node.conditions)if(mentionsColumn(child,colId))return true;\n}\nreturn false;\n}\nfunction compact(mask,count,out){\nif(out&&out.length>=count){\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])out[k++]=i;\nreturn out.subarray(0,k);\n}\nlet survivors=0;\nfor(let i=0;i<count;i++)survivors+=mask[i]?1:0;\nconst result=new Uint32Array(survivors);\nlet k=0;\nfor(let i=0;i<count;i++)if(mask[i])result[k++]=i;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/group.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return packKeys;}});\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return groupByColumns;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst dictSize=__m0[\"dictSize\"];\nconst identity=__m0[\"identity\"];\nconst presenceReader=__m0[\"presenceReader\"];\nconst rowCount=__m0[\"rowCount\"];\nconst valueReader=__m0[\"valueReader\"];\nconst KEY_SEPARATOR='\\u001F';\nconst NULL_MARKER='\\u0000';\nconst MAX_DIRECT_COUNTS=1<<20;\nfunction packKeys(handles,idx,n){\nconst k=handles.length;\nconst readers=handles.map((h)=>valueReader(h));\nconst allDictionary=k>0&&handles.every((h)=>h&&h.kind==='dictionary'&&h.dict);\nif(allDictionary){\nconst cards=handles.map((h)=>dictSize(h.dict)+1);\nlet product=1;\nfor(let j=0;j<k;j++)product*=cards[j];\nif(product<=Number.MAX_SAFE_INTEGER){\nconst codes=handles.map((h)=>h.values);\nconst presence=handles.map((h)=>presenceReader(h));\nconst keyOf=(row)=>{\nlet key=0;\nfor(let j=0;j<k;j++){\nconst present=presence[j];\nconst code=present&&present(row)===0?cards[j]-1:codes[j][row];\nkey=key*cards[j]+code;\n}\nreturn key;\n};\nconst packed=new Float64Array(n);\nfor(let i=0;i<n;i++)packed[i]=keyOf(idx[i]);\nreturn{packed,strings:null,product,readers,keyOf};\n}\n}\nconst keyOf=(row)=>{\nlet key='';\nfor(let j=0;j<k;j++){\nconst v=readers[j](row);\nkey+=(j===0?'':KEY_SEPARATOR)+(v===null||v===undefined?NULL_MARKER:String(v));\n}\nreturn key;\n};\nconst strings=new Array(n);\nfor(let i=0;i<n;i++)strings[i]=keyOf(idx[i]);\nreturn{packed:null,strings,product:Infinity,readers,keyOf};\n}\nfunction scatterBuckets(idx,ids,n,groups){\nconst offsets=new Uint32Array(groups+1);\nfor(let i=0;i<n;i++)offsets[ids[i]+1]++;\nfor(let g=0;g<groups;g++)offsets[g+1]+=offsets[g];\nconst scattered=new Uint32Array(n);\nconst cursor=offsets.slice(0,groups);\nfor(let i=0;i<n;i++)scattered[cursor[ids[i]]++]=idx[i];\nconst buckets=new Array(groups);\nfor(let g=0;g<groups;g++)buckets[g]=scattered.subarray(offsets[g],offsets[g+1]);\nreturn buckets;\n}\nfunction groupByColumns(handles,order,opts={}){\nconst list=handles||[];\nconst idx=order||identity(rowCount(list[0],opts));\nconst n=idx.length;\nif(list.length===0||n===0)return{keys:[],buckets:[]};\nconst{packed,strings,product,readers}=packKeys(list,idx,n);\nconst ids=new Uint32Array(n);\nlet groups=0;\nlet packedKeys=null;\nif(packed&&product<=Math.max(1024,Math.min(MAX_DIRECT_COUNTS,n*4))){\nconst size=product;\nconst seen=new Int32Array(size).fill(-1);\nfor(let i=0;i<n;i++)seen[packed[i]]=0;\nfor(let key=0;key<size;key++)if(seen[key]===0)seen[key]=groups++;\nfor(let i=0;i<n;i++)ids[i]=seen[packed[i]];\npackedKeys=new Float64Array(groups);\nfor(let key=0;key<size;key++)if(seen[key]>=0)packedKeys[seen[key]]=key;\n}else if(packed){\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=packed[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\npackedKeys=new Float64Array(groups);\nfor(const[key,id]of seen)packedKeys[id]=key;\n}else{\nconst seen=new Map();\nfor(let i=0;i<n;i++){\nconst key=strings[i];\nlet id=seen.get(key);\nif(id===undefined){id=groups++;seen.set(key,id);}\nids[i]=id;\n}\n}\nconst buckets=scatterBuckets(idx,ids,n,groups);\nconst keys=new Array(groups);\nfor(let g=0;g<groups;g++){\nconst row=buckets[g][0];\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\nkeys[g]=tuple;\n}\nconst result={keys,buckets};\nif(packedKeys)result.packed=packedKeys;\nreturn result;\n}\n});\n__def(\"packages/core/src/compute/facet.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return STRATEGIES;}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return GRANULARITIES;}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return DEFAULT_BUCKETS;}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return DEFAULT_CARDINALITY_LIMIT;}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return QUANTILE_SAMPLE;}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return facetKind;}});\nObject.defineProperty(__exports,\"orderedReader\",{enumerable:true,get:function(){return orderedReader;}});\nObject.defineProperty(__exports,\"toNumeric\",{enumerable:true,get:function(){return toNumeric;}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return cardinalityOf;}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return pickGranularity;}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return floorTo;}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return advance;}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return computeBounds;}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return countInto;}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return bucketOf;}});\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return facet;}});\nObject.defineProperty(__exports,\"default\",{enumerable:true,get:function(){return __default;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst dictSize=__m0[\"dictSize\"];\nconst dictValue=__m0[\"dictValue\"];\nconst STRATEGIES=Object.freeze(['equal','quantile','log']);\nconst GRANULARITIES=Object.freeze(['hour','day','week','month','quarter','year']);\nconst DEFAULT_BUCKETS=20;\nconst DEFAULT_CARDINALITY_LIMIT=50;\nconst QUANTILE_SAMPLE=10_000;\nfunction facetKind(handle,type){\nif(!handle)return'none';\nconst base=type&&type.base;\nif(base==='date'||base==='datetime'||base==='time'||base==='dateString')return'date';\nswitch(handle.kind){\ncase'bitset':return'boolean';\ncase'float64':case'int32':return'numeric';\ncase'dictionary':return'category';\ncase'multi':return'category';\ndefault:\nif(base==='number')return'numeric';\nif(base==='boolean')return'boolean';\nif(base==='text')return'category';\nreturn'none';\n}\n}\nfunction orderedReader(handle){\nconst values=handle.values;\nconst kind=handle.kind;\nif((kind==='float64'||kind==='int32')&&values)return(i)=>values[i];\nconst read=valueReader(handle);\nreturn(i)=>toNumeric(read(i));\n}\nfunction toNumeric(v){\nif(typeof v==='number')return v;\nif(v instanceof Date)return v.getTime();\nif(v===null||v===undefined||v==='')return NaN;\nif(typeof v==='boolean')return v?1:0;\nif(typeof v==='string'){\nconst n=Number(v);\nif(Number.isFinite(n))return n;\nconst t=Date.parse(v);\nreturn Number.isFinite(t)?t:NaN;\n}\nreturn NaN;\n}\nfunction cardinalityOf(handle,indices,count,limit=DEFAULT_CARDINALITY_LIMIT){\nif(!handle)return{cardinality:0,exact:true};\nif(handle.dict)return{cardinality:dictSize(handle.dict),exact:true};\nif(handle.kind==='bitset')return{cardinality:2,exact:true};\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst seen=new Set();\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined)continue;\nseen.add(v);\nif(seen.size>limit)return{cardinality:seen.size,exact:false};\n}\nreturn{cardinality:seen.size,exact:true};\n}\nconst HOUR_MS=3600_000;\nconst DAY_MS=86_400_000;\nfunction pickGranularity(span,target=DEFAULT_BUCKETS){\nconst ms=Number.isFinite(span)&&span>0?span:0;\nconst wide=Math.max(1,target)*2;\nif(ms/HOUR_MS<=wide)return'hour';\nif(ms/DAY_MS<=wide)return'day';\nif(ms/(7*DAY_MS)<=wide)return'week';\nif(ms/(30*DAY_MS)<=wide)return'month';\nif(ms/(91*DAY_MS)<=wide)return'quarter';\nreturn'year';\n}\nfunction floorTo(ms,granularity){\nif(!Number.isFinite(ms))return NaN;\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setMinutes(0,0,0);return d.getTime();\ncase'day':d.setHours(0,0,0,0);return d.getTime();\ncase'week':{\nd.setHours(0,0,0,0);\nconst back=(d.getDay()+6)%7;\nd.setDate(d.getDate()-back);\nreturn d.getTime();\n}\ncase'month':d.setDate(1);d.setHours(0,0,0,0);return d.getTime();\ncase'quarter':\nd.setMonth(Math.floor(d.getMonth()/3)*3,1);\nd.setHours(0,0,0,0);\nreturn d.getTime();\ndefault:d.setMonth(0,1);d.setHours(0,0,0,0);return d.getTime();\n}\n}\nfunction advance(ms,granularity){\nconst d=new Date(ms);\nswitch(granularity){\ncase'hour':d.setHours(d.getHours()+1);break;\ncase'day':d.setDate(d.getDate()+1);break;\ncase'week':d.setDate(d.getDate()+7);break;\ncase'month':d.setMonth(d.getMonth()+1);break;\ncase'quarter':d.setMonth(d.getMonth()+3);break;\ndefault:d.setFullYear(d.getFullYear()+1);break;\n}\nreturn d.getTime();\n}\nfunction numericExtent(handle,indices,count){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nlet min=Infinity;\nlet max=-Infinity;\nlet nulls=0;\nlet finite=0;\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){nulls++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){nulls++;continue;}\nif(v<min)min=v;\nif(v>max)max=v;\nfinite++;\n}\nreturn{min,max,nulls,finite};\n}\nfunction sortedSample(handle,indices,count,cap){\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nconst n=indices?indices.length:count;\nconst step=n>cap?n/cap:1;\nconst out=[];\nfor(let s=0;s<n;s+=step){\nconst i=indices?indices[Math.floor(s)]:Math.floor(s);\nif(present&&!present(i))continue;\nconst v=read(i);\nif(Number.isFinite(v))out.push(v);\n}\nconst arr=Float64Array.from(out);\narr.sort();\nreturn arr;\n}\nfunction computeBounds(handle,indices,count,opts={}){\nconst kind=opts.kind||facetKind(handle,opts.type);\nif(kind==='none'||!handle)return{kind:'none',buckets:[],suppressed:'type'};\nif(kind==='boolean')return boundsForBoolean(handle,indices,count);\nif(kind==='category')return boundsForCategory(handle,indices,count,opts);\nreturn boundsForOrdered(handle,indices,count,kind,opts);\n}\nfunction boundsForBoolean(handle,indices,count){\nconst present=presenceReader(handle);\nlet nulls=0;\nif(present){\nconst n=indices?indices.length:count;\nfor(let k=0;k<n;k++)if(!present(indices?indices[k]:k))nulls++;\n}\nconst buckets=[{value:false,label:'false'},{value:true,label:'true'}];\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'boolean',buckets};\n}\nfunction boundsForCategory(handle,indices,count,opts){\nconst limit=opts.cardinalityLimit??DEFAULT_CARDINALITY_LIMIT;\nconst{cardinality}=cardinalityOf(handle,indices,count,limit);\nif(cardinality>limit&&(opts.aboveLimit||'suppress')==='suppress'){\nreturn{kind:'category',buckets:[],suppressed:'cardinality',cardinality};\n}\nconst read=valueReader(handle);\nconst n=indices?indices.length:count;\nconst tally=new Map();\nlet nulls=0;\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){nulls++;continue;}\nif(Array.isArray(v)){\nif(!v.length){nulls++;continue;}\nfor(const m of v)tally.set(m,(tally.get(m)||0)+1);\ncontinue;\n}\ntally.set(v,(tally.get(v)||0)+1);\n}\nlet entries=[...tally.entries()];\nif(opts.order==='alpha'){\nentries.sort((a,b)=>String(a[0]).localeCompare(String(b[0])));\n}else{\nentries.sort((a,b)=>b[1]-a[1]);\n}\nlet remainder=0;\nlet dropped=0;\nif(entries.length>limit){\ndropped=entries.length-limit;\nfor(let i=limit;i<entries.length;i++)remainder+=entries[i][1];\nentries=entries.slice(0,limit);\n}\nconst buckets=entries.map(([value])=>({value,label:String(value)}));\nif(remainder>0)buckets.push({remainder:true,label:`Other (${dropped} values)`});\nif(nulls>0)buckets.push({null:true,label:'Empty'});\nreturn{kind:'category',buckets,cardinality};\n}\nfunction boundsForOrdered(handle,indices,count,kind,opts){\nconst{min,max,nulls,finite}=numericExtent(handle,indices,count);\nif(!finite){\nreturn{kind,buckets:nulls?[{null:true,label:'Empty'}]:[],empty:true};\n}\nconst wanted=Math.max(1,Math.floor(opts.buckets||DEFAULT_BUCKETS));\nlet buckets=[];\nif(kind==='date'){\nconst granularity=GRANULARITIES.includes(opts.granularity)\n?opts.granularity:pickGranularity(max-min,wanted);\nlet edge=floorTo(min,granularity);\nwhile(edge<=max&&buckets.length<4096){\nconst next=advance(edge,granularity);\nif(!(next>edge))break;\nbuckets.push({from:edge,to:next});\nedge=next;\n}\nreturn{kind,buckets:withNull(buckets,nulls),granularity};\n}\nconst strategy=STRATEGIES.includes(opts.strategy)?opts.strategy:'equal';\nif(strategy==='quantile'){\nconst sample=sortedSample(handle,indices,count,QUANTILE_SAMPLE);\nif(sample.length){\nconst edges=[sample[0]];\nfor(let b=1;b<wanted;b++){\nconst v=sample[Math.min(sample.length-1,Math.floor((b/wanted)*sample.length))];\nif(v>edges[edges.length-1])edges.push(v);\n}\nedges.push(max);\nfor(let b=0;b<edges.length-1;b++)buckets.push({from:edges[b],to:edges[b+1]});\n}\n}else if(strategy==='log'&&min>0){\nconst lo=Math.log10(min);\nconst hi=Math.log10(max);\nconst step=(hi-lo)/wanted||1;\nfor(let b=0;b<wanted;b++){\nbuckets.push({from:10**(lo+b*step),to:10**(lo+(b+1)*step)});\n}\n}\nif(!buckets.length){\nconst width=(max-min)/wanted||1;\nfor(let b=0;b<wanted;b++)buckets.push({from:min+b*width,to:min+(b+1)*width});\n}\nbuckets[buckets.length-1].to=max;\nreturn{kind,buckets:withNull(buckets,nulls),strategy,min,max};\n}\nfunction withNull(buckets,nulls){\nreturn nulls>0?[...buckets,{null:true,label:'Empty'}]:buckets;\n}\nfunction countInto(handle,indices,count,bounds,out){\nconst buckets=(bounds&&bounds.buckets)||[];\nconst counts=out&&out.length>=buckets.length?out.subarray(0,buckets.length)\n:new Uint32Array(buckets.length);\ncounts.fill(0);\nif(!handle||!buckets.length)return counts;\nconst nullBucket=buckets.length-1;\nconst hasNull=!!buckets[nullBucket]&&buckets[nullBucket].null===true;\nconst n=indices?indices.length:count;\nif(bounds.kind==='boolean'){\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined){if(hasNull)counts[nullBucket]++;continue;}\ncounts[v?1:0]++;\n}\nreturn counts;\n}\nif(bounds.kind==='category'){\nconst slot=new Map();\nfor(let b=0;b<buckets.length;b++){\nif(!buckets[b].null&&!buckets[b].remainder)slot.set(buckets[b].value,b);\n}\nconst remainderAt=buckets.findIndex((b)=>b.remainder);\nconst read=valueReader(handle);\nfor(let k=0;k<n;k++){\nconst v=read(indices?indices[k]:k);\nif(v===null||v===undefined||v===''){if(hasNull)counts[nullBucket]++;continue;}\nif(Array.isArray(v)){\nif(!v.length){if(hasNull)counts[nullBucket]++;continue;}\nfor(const m of v){\nconst at=slot.get(m);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\ncontinue;\n}\nconst at=slot.get(v);\nif(at!==undefined)counts[at]++;\nelse if(remainderAt>=0)counts[remainderAt]++;\n}\nreturn counts;\n}\nconst ordered=hasNull?buckets.length-1:buckets.length;\nconst edges=new Float64Array(ordered+1);\nfor(let b=0;b<ordered;b++)edges[b]=buckets[b].from;\nedges[ordered]=ordered?buckets[ordered-1].to:0;\nconst read=orderedReader(handle);\nconst present=presenceReader(handle);\nfor(let k=0;k<n;k++){\nconst i=indices?indices[k]:k;\nif(present&&!present(i)){if(hasNull)counts[nullBucket]++;continue;}\nconst v=read(i);\nif(!Number.isFinite(v)){if(hasNull)counts[nullBucket]++;continue;}\nconst at=bucketOf(edges,ordered,v);\nif(at>=0)counts[at]++;\n}\nreturn counts;\n}\nfunction bucketOf(edges,ordered,v){\nif(!ordered)return-1;\nif(v<edges[0])return-1;\nif(v>=edges[ordered])return v===edges[ordered]?ordered-1:-1;\nlet lo=0;\nlet hi=ordered-1;\nwhile(lo<hi){\nconst mid=(lo+hi+1)>>>1;\nif(v>=edges[mid])lo=mid;else hi=mid-1;\n}\nreturn lo;\n}\nfunction facet(handle,indices,count,opts={}){\nconst bounds=opts.bounds||computeBounds(handle,opts.boundsIndices??indices,count,opts);\nreturn{bounds,counts:countInto(handle,indices,count,bounds)};\n}\nconst __default=facet;\n});\n__def(\"packages/core/src/compute/special.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"logGamma\",{enumerable:true,get:function(){return logGamma;}});\nObject.defineProperty(__exports,\"incompleteBeta\",{enumerable:true,get:function(){return incompleteBeta;}});\nObject.defineProperty(__exports,\"normalQuantile\",{enumerable:true,get:function(){return normalQuantile;}});\nObject.defineProperty(__exports,\"studentT\",{enumerable:true,get:function(){return studentT;}});\nObject.defineProperty(__exports,\"studentTQuantile\",{enumerable:true,get:function(){return studentTQuantile;}});\nconst LANCZOS=Object.freeze([\n676.5203681218851,-1259.1392167224028,771.32342877765313,\n-176.61502916214059,12.507343278686905,-0.13857109526572012,\n9.9843695780195716e-6,1.5056327351493116e-7,\n]);\nconst EPS=3e-12;\nconst TINY=1e-300;\nfunction logGamma(x){\nif(x<0.5)return Math.log(Math.PI/Math.sin(Math.PI*x))-logGamma(1-x);\nconst z=x-1;\nlet a=0.99999999999980993;\nconst t=z+7.5;\nfor(let i=0;i<LANCZOS.length;i++)a+=LANCZOS[i]/(z+i+1);\nreturn 0.5*Math.log(2*Math.PI)+(z+0.5)*Math.log(t)-t+Math.log(a);\n}\nfunction betaContinuedFraction(a,b,x){\nconst qab=a+b;\nconst qap=a+1;\nconst qam=a-1;\nlet c=1;\nlet d=1-(qab*x)/qap;\nif(Math.abs(d)<TINY)d=TINY;\nd=1/d;\nlet h=d;\nfor(let m=1;m<=300;m++){\nconst m2=2*m;\nlet aa=(m*(b-m)*x)/((qam+m2)*(a+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nh*=d*c;\naa=(-(a+m)*(qab+m)*x)/((a+m2)*(qap+m2));\nd=1+aa*d;\nif(Math.abs(d)<TINY)d=TINY;\nc=1+aa/c;\nif(Math.abs(c)<TINY)c=TINY;\nd=1/d;\nconst step=d*c;\nh*=step;\nif(Math.abs(step-1)<EPS)break;\n}\nreturn h;\n}\nfunction incompleteBeta(a,b,x){\nif(!(a>0)||!(b>0)||!Number.isFinite(x))return Number.NaN;\nif(x<=0)return 0;\nif(x>=1)return 1;\nconst front=Math.exp(\nlogGamma(a+b)-logGamma(a)-logGamma(b)+a*Math.log(x)+b*Math.log(1-x),\n);\nreturn x<(a+1)/(a+b+2)\n?(front*betaContinuedFraction(a,b,x))/a\n:1-(front*betaContinuedFraction(b,a,1-x))/b;\n}\nfunction normalQuantile(p){\nif(!(p>0)||!(p<1))return p===0?-Infinity:(p===1?Infinity:Number.NaN);\nconst a=[-3.969683028665376e+1,2.209460984245205e+2,-2.759285104469687e+2,\n1.383577518672690e+2,-3.066479806614716e+1,2.506628277459239];\nconst b=[-5.447609879822406e+1,1.615858368580409e+2,-1.556989798598866e+2,\n6.680131188771972e+1,-1.328068155288572e+1];\nconst c=[-7.784894002430293e-3,-3.223964580411365e-1,-2.400758277161838,\n-2.549732539343734,4.374664141464968,2.938163982698783];\nconst d=[7.784695709041462e-3,3.224671290700398e-1,2.445134137142996,\n3.754408661907416];\nconst low=0.02425;\nlet q;\nlet r;\nlet x;\nif(p<low){\nq=Math.sqrt(-2*Math.log(p));\nx=(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}else if(p<=1-low){\nq=p-0.5;\nr=q*q;\nx=((((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q)\n/ (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);\n}else{\nq=Math.sqrt(-2*Math.log(1-p));\nx=-(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5])\n/ ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);\n}\nconst e=0.5*erfc(-x/Math.SQRT2)-p;\nconst u=e*Math.sqrt(2*Math.PI)*Math.exp((x*x)/2);\nreturn x-u/(1+(x*u)/2);\n}\nfunction erfc(x){\nconst z=Math.abs(x);\nconst t=2/(2+z);\nconst ty=4*t-2;\nconst cof=[-1.3026537197817094,6.4196979235649026e-1,1.9476473204185836e-2,\n-9.561514786808631e-3,-9.46595344482036e-4,3.66839497852761e-4,\n4.2523324806907e-5,-2.0278578112534e-5,-1.624290004647e-6,\n1.303655835580e-6,1.5626441722e-8,-8.5238095915e-8,6.529054439e-9,\n5.059343495e-9,-9.91364156e-10,-2.27365122e-10,9.6467911e-11,\n2.394038e-12,-6.886027e-12,8.94487e-13,3.13092e-13,-1.12708e-13,\n3.81e-16,7.106e-15];\nlet dd=0;\nlet dv=0;\nlet tmp;\nfor(let j=cof.length-1;j>0;j--){\ntmp=dv;\ndv=ty*dv-dd+cof[j];\ndd=tmp;\n}\nconst ans=t*Math.exp(-z*z+0.5*(cof[0]+ty*dv)-dd);\nreturn x>=0?ans:2-ans;\n}\nfunction studentT(t,df){\nif(!(df>0)||!Number.isFinite(t))return Number.NaN;\nconst tail=0.5*incompleteBeta(df/2,0.5,df/(df+t*t));\nreturn t>0?1-tail:tail;\n}\nfunction studentTQuantile(p,df){\nif(!(p>0)||!(p<1)||!(df>0))return Number.NaN;\nif(df>1e7)return normalQuantile(p);\nlet lo=-1e4;\nlet hi=1e4;\nlet x=normalQuantile(p);\nconst logBeta=logGamma(df/2)+logGamma(0.5)-logGamma((df+1)/2);\nfor(let i=0;i<60;i++){\nconst cdf=studentT(x,df);\nif(cdf<p)lo=x;else hi=x;\nconst pdf=Math.exp(-((df+1)/2)*Math.log(1+(x*x)/df)-logBeta)\n/ Math.sqrt(df);\nconst step=pdf>0?(cdf-p)/pdf:0;\nif(Math.abs(step)<1e-12)break;\nconst next=x-step;\nx=next>lo&&next<hi&&Number.isFinite(next)?next:(lo+hi)/2;\nif(hi-lo<1e-12)break;\n}\nreturn x;\n}\n});\n__def(\"packages/core/src/compute/statistics.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KENDALL_LIMIT\",{enumerable:true,get:function(){return KENDALL_LIMIT;}});\nObject.defineProperty(__exports,\"MAINTENANCE\",{enumerable:true,get:function(){return MAINTENANCE;}});\nObject.defineProperty(__exports,\"numbers\",{enumerable:true,get:function(){return numbers;}});\nObject.defineProperty(__exports,\"frequencies\",{enumerable:true,get:function(){return frequencies;}});\nObject.defineProperty(__exports,\"herfindahl\",{enumerable:true,get:function(){return herfindahl;}});\nObject.defineProperty(__exports,\"entropy\",{enumerable:true,get:function(){return entropy;}});\nObject.defineProperty(__exports,\"evenness\",{enumerable:true,get:function(){return evenness;}});\nObject.defineProperty(__exports,\"topShare\",{enumerable:true,get:function(){return topShare;}});\nObject.defineProperty(__exports,\"gini\",{enumerable:true,get:function(){return gini;}});\nObject.defineProperty(__exports,\"moments\",{enumerable:true,get:function(){return moments;}});\nObject.defineProperty(__exports,\"quantileSorted\",{enumerable:true,get:function(){return quantileSorted;}});\nObject.defineProperty(__exports,\"quantile\",{enumerable:true,get:function(){return quantile;}});\nObject.defineProperty(__exports,\"STAT_FNS\",{enumerable:true,get:function(){return STAT_FNS;}});\nObject.defineProperty(__exports,\"STAT_LABELS\",{enumerable:true,get:function(){return STAT_LABELS;}});\nObject.defineProperty(__exports,\"weightedAverage\",{enumerable:true,get:function(){return weightedAverage;}});\nObject.defineProperty(__exports,\"extremeRow\",{enumerable:true,get:function(){return extremeRow;}});\nObject.defineProperty(__exports,\"correlation\",{enumerable:true,get:function(){return correlation;}});\nObject.defineProperty(__exports,\"trimmedMean\",{enumerable:true,get:function(){return trimmedMean;}});\nObject.defineProperty(__exports,\"winsorizedMean\",{enumerable:true,get:function(){return winsorizedMean;}});\nObject.defineProperty(__exports,\"modifiedZOutliers\",{enumerable:true,get:function(){return modifiedZOutliers;}});\nObject.defineProperty(__exports,\"jarqueBera\",{enumerable:true,get:function(){return jarqueBera;}});\nObject.defineProperty(__exports,\"weightedQuantile\",{enumerable:true,get:function(){return weightedQuantile;}});\nObject.defineProperty(__exports,\"pairs\",{enumerable:true,get:function(){return pairs;}});\nObject.defineProperty(__exports,\"covariance\",{enumerable:true,get:function(){return covariance;}});\nObject.defineProperty(__exports,\"regression\",{enumerable:true,get:function(){return regression;}});\nObject.defineProperty(__exports,\"spearman\",{enumerable:true,get:function(){return spearman;}});\nObject.defineProperty(__exports,\"kendall\",{enumerable:true,get:function(){return kendall;}});\nObject.defineProperty(__exports,\"seriesStats\",{enumerable:true,get:function(){return seriesStats;}});\nObject.defineProperty(__exports,\"D2_N2\",{enumerable:true,get:function(){return D2_N2;}});\nObject.defineProperty(__exports,\"D4_N2\",{enumerable:true,get:function(){return D4_N2;}});\nObject.defineProperty(__exports,\"movingRanges\",{enumerable:true,get:function(){return movingRanges;}});\nObject.defineProperty(__exports,\"withinSigma\",{enumerable:true,get:function(){return withinSigma;}});\nObject.defineProperty(__exports,\"capability\",{enumerable:true,get:function(){return capability;}});\nObject.defineProperty(__exports,\"controlLimits\",{enumerable:true,get:function(){return controlLimits;}});\nObject.defineProperty(__exports,\"westernElectricViolations\",{enumerable:true,get:function(){return westernElectricViolations;}});\nObject.defineProperty(__exports,\"nelsonViolations\",{enumerable:true,get:function(){return nelsonViolations;}});\nObject.defineProperty(__exports,\"CONTROL_RULE_SETS\",{enumerable:true,get:function(){return CONTROL_RULE_SETS;}});\nObject.defineProperty(__exports,\"controlViolations\",{enumerable:true,get:function(){return controlViolations;}});\nObject.defineProperty(__exports,\"countOutside\",{enumerable:true,get:function(){return countOutside;}});\nObject.defineProperty(__exports,\"histogram\",{enumerable:true,get:function(){return histogram;}});\nObject.defineProperty(__exports,\"DEFAULT_CONFIDENCE\",{enumerable:true,get:function(){return DEFAULT_CONFIDENCE;}});\nObject.defineProperty(__exports,\"meanInterval\",{enumerable:true,get:function(){return meanInterval;}});\nObject.defineProperty(__exports,\"proportionInterval\",{enumerable:true,get:function(){return proportionInterval;}});\nObject.defineProperty(__exports,\"slopeInterval\",{enumerable:true,get:function(){return slopeInterval;}});\nObject.defineProperty(__exports,\"capabilityInterval\",{enumerable:true,get:function(){return capabilityInterval;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst __m1=__req(\"packages/core/src/compute/special.js\");\nconst studentTQuantile=__m1[\"studentTQuantile\"];\nconst normalQuantile=__m1[\"normalQuantile\"];\nconst KENDALL_LIMIT=5000;\nconst MAINTENANCE=Object.freeze({\nvariance:'rescan',\nvarianceP:'rescan',\nstddev:'rescan',\nstddevP:'rescan',\nsumSquares:'rescan',\nweightedAvg:'rescan',\nmedian:'rescan',\np25:'rescan',\np75:'rescan',\np90:'rescan',\np95:'rescan',\np99:'rescan',\niqr:'rescan',\nmode:'rescan',\ndistinct:'rescan',\nrange:'rescan',\nskewness:'rescan',\nkurtosis:'rescan',\ngeomean:'rescan',\nharmean:'rescan',\nmad:'rescan',\nargmin:'rescan',\nargmax:'rescan',\nhhi:'rescan',\nentropy:'rescan',\nevenness:'rescan',\ntop3Share:'rescan',\ntop10Share:'rescan',\ngini:'rescan',\ntrimmedMean:'rescan',\nwinsorizedMean:'rescan',\nrobustOutliers:'rescan',\njarqueBera:'rescan',\n});\nfunction numbers(handle,indices){\nconst n=indices.length;\nconst out=new Float64Array(n);\nlet count=0;\nconst numeric=handle&&(handle.kind==='float64'||handle.kind==='int32');\nif(numeric){\nconst values=handle.values;\nconst present=presenceReader(handle);\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present&&present(row)!==1)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nconst v=typeof raw==='number'?raw:Number(raw);\nif(!Number.isFinite(v))continue;\nout[count++]=v;\n}\nreturn out.subarray(0,count);\n}\nfunction frequencies(handle,indices){\nconst seen=new Map();\nconst read=valueReader(handle);\nlet total=0;\nfor(let i=0;i<indices.length;i++){\nconst raw=read(indices[i]);\nif(raw===null||raw===undefined||raw==='')continue;\nif(typeof raw==='number'&&Number.isNaN(raw))continue;\nconst key=typeof raw==='object'?String(raw):raw;\nseen.set(key,(seen.get(key)||0)+1);\ntotal++;\n}\nconst counts=[...seen.values()].sort((a,b)=>b-a);\nreturn{counts,total,distinct:counts.length};\n}\nfunction sharesOf(freq){\nreturn freq.total>0?freq.counts.map((c)=>c/freq.total):[];\n}\nfunction herfindahl(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))sum+=share*share;\nreturn sum;\n}\nfunction entropy(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum;\n}\nfunction evenness(handle,indices){\nconst freq=frequencies(handle,indices);\nif(!freq.total||freq.distinct<2)return freq.total?1:null;\nlet sum=0;\nfor(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);\nreturn sum/Math.log2(freq.distinct);\n}\nfunction topShare(handle,indices,n=3){\nconst freq=frequencies(handle,indices);\nif(!freq.total)return null;\nconst take=Math.max(1,Math.floor(n));\nlet held=0;\nfor(let i=0;i<Math.min(take,freq.counts.length);i++)held+=freq.counts[i];\nreturn held/freq.total;\n}\nfunction gini(handle,indices){\nconst values=numbers(handle,indices);\nconst n=values.length;\nif(!n)return null;\nconst sorted=values.slice().sort();\nif(sorted[0]<0)return null;\nlet total=0;\nlet weighted=0;\nfor(let i=0;i<n;i++){\ntotal+=sorted[i];\nweighted+=(i+1)*sorted[i];\n}\nif(total===0)return 0;\nreturn(2*weighted)/(n*total)-(n+1)/n;\n}\nfunction moments(values){\nlet n=0;\nlet mean=0;\nlet m2=0;\nfor(let i=0;i<values.length;i++){\nconst x=values[i];\nn++;\nconst delta=x-mean;\nmean+=delta/n;\nm2+=delta*(x-mean);\n}\nreturn{n,mean,m2};\n}\nfunction quantileSorted(sorted,p){\nconst n=sorted.length;\nif(!n)return NaN;\nif(n===1)return sorted[0];\nconst h=(n-1)*Math.min(1,Math.max(0,p));\nconst lo=Math.floor(h);\nconst hi=Math.ceil(h);\nif(lo===hi)return sorted[lo];\nreturn sorted[lo]+(h-lo)*(sorted[hi]-sorted[lo]);\n}\nfunction quantile(values,p){\nif(!values.length)return NaN;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,p);\n}\nconst STAT_FNS=Object.freeze({\nhhi:(h,i)=>herfindahl(h,i),\nentropy:(h,i)=>entropy(h,i),\nevenness:(h,i)=>evenness(h,i),\ntop3Share:(h,i)=>topShare(h,i,3),\ntop10Share:(h,i)=>topShare(h,i,10),\ngini:(h,i)=>gini(h,i),\ntrimmedMean:(h,i)=>trimmedMean(numbers(h,i),0.1),\nwinsorizedMean:(h,i)=>winsorizedMean(numbers(h,i),0.1),\nrobustOutliers:(h,i)=>modifiedZOutliers(numbers(h,i),3.5),\njarqueBera:(h,i)=>jarqueBera(numbers(h,i)),\nvariance:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?m2/(n-1):null;\n},\nvarianceP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?m2/n:null;\n},\nstddev:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>1?Math.sqrt(m2/(n-1)):null;\n},\nstddevP:(h,i)=>{\nconst{n,m2}=moments(numbers(h,i));\nreturn n>0?Math.sqrt(m2/n):null;\n},\nmedian:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.5):null;\n},\np25:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.25):null;\n},\np75:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.75):null;\n},\np90:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.9):null;\n},\np95:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.95):null;\n},\np99:(h,i)=>{\nconst values=numbers(h,i);\nreturn values.length?quantile(values,0.99):null;\n},\niqr:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst sorted=values.slice().sort();\nreturn quantileSorted(sorted,0.75)-quantileSorted(sorted,0.25);\n},\nmad:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nconst middle=quantile(values,0.5);\nconst deviations=new Float64Array(values.length);\nfor(let k=0;k<values.length;k++)deviations[k]=Math.abs(values[k]-middle);\nreturn quantile(deviations,0.5);\n},\nrange:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet lo=Infinity;\nlet hi=-Infinity;\nfor(let k=0;k<values.length;k++){\nif(values[k]<lo)lo=values[k];\nif(values[k]>hi)hi=values[k];\n}\nreturn hi-lo;\n},\ndistinct:(h,i)=>{\nconst read=valueReader(h);\nconst seen=new Set();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nseen.add(v instanceof Date?v.getTime():v);\n}\nreturn seen.size;\n},\nmode:(h,i)=>{\nconst read=valueReader(h);\nconst counts=new Map();\nfor(let k=0;k<i.length;k++){\nconst v=read(i[k]);\nif(v===null||v===undefined||v==='')continue;\nconst id=v instanceof Date?v.getTime():v;\ncounts.set(id,(counts.get(id)||0)+1);\n}\nlet best=null;\nlet most=1;\nfor(const[value,times]of counts){\nif(times>most){\nmost=times;\nbest=value;\n}\n}\nreturn best;\n},\nskewness:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<3||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**3;\nreturn(n/((n-1)*(n-2)))*sum;\n},\nkurtosis:(h,i)=>{\nconst values=numbers(h,i);\nconst{n,mean,m2}=moments(values);\nif(n<4||m2<=0)return null;\nconst sd=Math.sqrt(m2/(n-1));\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=((values[k]-mean)/sd)**4;\nconst a=(n*(n+1))/((n-1)*(n-2)*(n-3));\nconst b=(3*(n-1)**2)/((n-2)*(n-3));\nreturn a*sum-b;\n},\ngeomean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]<=0)return null;\nsum+=Math.log(values[k]);\n}\nreturn Math.exp(sum/values.length);\n},\nharmean:(h,i)=>{\nconst values=numbers(h,i);\nif(!values.length)return null;\nlet sum=0;\nfor(let k=0;k<values.length;k++){\nif(values[k]===0)return null;\nsum+=1/values[k];\n}\nreturn values.length/sum;\n},\nsumSquares:(h,i)=>{\nconst values=numbers(h,i);\nlet sum=0;\nfor(let k=0;k<values.length;k++)sum+=values[k]*values[k];\nreturn sum;\n},\n});\nconst STAT_LABELS=Object.freeze({\nhhi:'Concentration (HHI)',\nentropy:'Entropy',\nevenness:'Evenness',\ntop3Share:'Top 3 share',\ntop10Share:'Top 10 share',\ngini:'Gini coefficient',\ntrimmedMean:'Trimmed mean',\nwinsorizedMean:'Winsorized mean',\nrobustOutliers:'Outliers (robust)',\njarqueBera:'Jarque–Bera',\nmedian:'Median',\np25:'25th percentile',\np75:'75th percentile',\np90:'90th percentile',\np95:'95th percentile',\np99:'99th percentile',\niqr:'Interquartile range',\nmad:'Median absolute deviation',\nvariance:'Variance',\nvarianceP:'Variance (population)',\nstddev:'Standard deviation',\nstddevP:'Standard deviation (population)',\nrange:'Range',\ndistinct:'Distinct',\nmode:'Mode',\nskewness:'Skewness',\nkurtosis:'Kurtosis',\ngeomean:'Geometric mean',\nharmean:'Harmonic mean',\nsumSquares:'Sum of squares',\nweightedAvg:'Weighted average',\nargmin:'Lowest by',\nargmax:'Highest by',\n});\nfunction weightedAverage(handle,weights,indices){\nconst readValue=valueReader(handle);\nconst readWeight=valueReader(weights);\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(readValue(row));\nconst weight=Number(readWeight(row));\nif(!Number.isFinite(value)||!Number.isFinite(weight))continue;\ntop+=value*weight;\nbottom+=weight;\n}\nreturn bottom===0?null:top/bottom;\n}\nfunction extremeRow(handle,indices,largest){\nconst read=valueReader(handle);\nlet best=null;\nlet bestValue=largest?-Infinity:Infinity;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst value=Number(read(row));\nif(!Number.isFinite(value))continue;\nif(largest?value>bestValue:value<bestValue){\nbestValue=value;\nbest=row;\n}\n}\nreturn best;\n}\nfunction correlation(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nlet n=0;\nlet sx=0;\nlet sy=0;\nlet sxx=0;\nlet syy=0;\nlet sxy=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nn++;\nsx+=x;\nsy+=y;\nsxx+=x*x;\nsyy+=y*y;\nsxy+=x*y;\n}\nif(n<2)return null;\nconst top=n*sxy-sx*sy;\nconst bottom=Math.sqrt((n*sxx-sx*sx)*(n*syy-sy*sy));\nif(bottom===0)return null;\nconst r=top/bottom;\nreturn Math.max(-1,Math.min(1,r));\n}\nfunction trimmedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst kept=sorted.slice(cut,n-cut);\nif(!kept.length)return quantileSorted(sorted,0.5);\nlet sum=0;\nfor(const v of kept)sum+=v;\nreturn sum/kept.length;\n}\nfunction winsorizedMean(values,share=0.1){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));\nconst low=sorted[cut];\nconst high=sorted[n-1-cut];\nlet sum=0;\nfor(const v of sorted)sum+=Math.min(high,Math.max(low,v));\nreturn sum/n;\n}\nfunction modifiedZOutliers(values,threshold=3.5){\nconst n=values.length;\nif(!n)return null;\nconst sorted=Array.from(values).sort((a,b)=>a-b);\nconst middle=quantileSorted(sorted,0.5);\nconst deviations=sorted.map((v)=>Math.abs(v-middle)).sort((a,b)=>a-b);\nconst mad=quantileSorted(deviations,0.5);\nif(mad===0)return null;\nlet count=0;\nfor(const v of sorted)if(Math.abs((0.6745*(v-middle))/mad)>threshold)count++;\nreturn count;\n}\nfunction jarqueBera(values){\nconst n=values.length;\nif(n<8)return null;\nlet mean=0;\nfor(const v of values)mean+=v;\nmean/=n;\nlet m2=0;\nlet m3=0;\nlet m4=0;\nfor(const v of values){\nconst d=v-mean;\nm2+=d*d;\nm3+=d*d*d;\nm4+=d*d*d*d;\n}\nm2/=n;\nm3/=n;\nm4/=n;\nif(m2===0)return null;\nconst skew=m3/m2**1.5;\nconst excess=m4/(m2*m2)-3;\nreturn(n/6)*(skew*skew+(excess*excess)/4);\n}\nfunction weightedQuantile(values,weights,p){\nconst paired=[];\nlet total=0;\nfor(let i=0;i<values.length;i++){\nconst v=Number(values[i]);\nconst w=Number(weights[i]);\nif(!Number.isFinite(v)||!Number.isFinite(w)||w<=0)continue;\npaired.push([v,w]);\ntotal+=w;\n}\nif(!paired.length||total<=0)return null;\npaired.sort((a,b)=>a[0]-b[0]);\nif(paired.length===1)return paired[0][0];\nconst at=[];\nlet seen=0;\nfor(const[,w]of paired){\nat.push((seen+w/2)/total);\nseen+=w;\n}\nconst target=Math.max(0,Math.min(1,p));\nif(target<=at[0])return paired[0][0];\nif(target>=at[at.length-1])return paired[paired.length-1][0];\nfor(let i=1;i<at.length;i++){\nif(target>at[i])continue;\nconst span=at[i]-at[i-1];\nconst within=span>0?(target-at[i-1])/span:0;\nreturn paired[i-1][0]+(paired[i][0]-paired[i-1][0])*within;\n}\nreturn paired[paired.length-1][0];\n}\nfunction pairs(a,b,indices){\nconst readA=valueReader(a);\nconst readB=valueReader(b);\nconst xs=new Float64Array(indices.length);\nconst ys=new Float64Array(indices.length);\nlet n=0;\nfor(let i=0;i<indices.length;i++){\nconst row=indices[i];\nconst x=Number(readA(row));\nconst y=Number(readB(row));\nif(!Number.isFinite(x)||!Number.isFinite(y))continue;\nxs[n]=x;\nys[n]=y;\nn++;\n}\nreturn{xs:xs.subarray(0,n),ys:ys.subarray(0,n),n};\n}\nfunction covariance(a,b,indices,population=false){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=(xs[i]-mx)*(ys[i]-my);\nreturn sum/(population?n:n-1);\n}\nfunction regression(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}\nmx/=n;\nmy/=n;\nlet sxx=0;\nlet sxy=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=xs[i]-mx;\nconst dy=ys[i]-my;\nsxx+=dx*dx;\nsxy+=dx*dy;\nsyy+=dy*dy;\n}\nif(sxx===0)return null;\nconst slope=sxy/sxx;\nconst intercept=my-slope*mx;\nconst r2=syy===0?1:Math.max(0,Math.min(1,(sxy*sxy)/(sxx*syy)));\nconst residual=Math.max(0,syy-slope*sxy);\nconst stdError=n>2?Math.sqrt(residual/(n-2)/sxx):0;\nreturn{slope,intercept,r2,stdError,n};\n}\nfunction ranksOf(values){\nconst n=values.length;\nconst order=Array.from({length:n},(unused,i)=>i)\n.sort((i,j)=>values[i]-values[j]);\nconst ranks=new Float64Array(n);\nlet i=0;\nwhile(i<n){\nlet j=i;\nwhile(j+1<n&&values[order[j+1]]===values[order[i]])j++;\nconst shared=(i+j)/2+1;\nfor(let k=i;k<=j;k++)ranks[order[k]]=shared;\ni=j+1;\n}\nreturn ranks;\n}\nfunction spearman(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2)return null;\nconst rx=ranksOf(xs);\nconst ry=ranksOf(ys);\nlet mx=0;\nlet my=0;\nfor(let i=0;i<n;i++){mx+=rx[i];my+=ry[i];}\nmx/=n;\nmy/=n;\nlet sxy=0;\nlet sxx=0;\nlet syy=0;\nfor(let i=0;i<n;i++){\nconst dx=rx[i]-mx;\nconst dy=ry[i]-my;\nsxy+=dx*dy;\nsxx+=dx*dx;\nsyy+=dy*dy;\n}\nif(sxx===0||syy===0)return null;\nreturn Math.max(-1,Math.min(1,sxy/Math.sqrt(sxx*syy)));\n}\nfunction kendall(a,b,indices){\nconst{xs,ys,n}=pairs(a,b,indices);\nif(n<2||n>KENDALL_LIMIT)return null;\nlet concordant=0;\nlet discordant=0;\nlet tiedXOnly=0;\nlet tiedYOnly=0;\nfor(let i=0;i<n;i++){\nfor(let j=i+1;j<n;j++){\nconst dx=Math.sign(xs[i]-xs[j]);\nconst dy=Math.sign(ys[i]-ys[j]);\nconst product=dx*dy;\nif(product>0)concordant++;\nelse if(product<0)discordant++;\nelse if(dx===0&&dy===0){}\nelse if(dx===0)tiedXOnly++;\nelse tiedYOnly++;\n}\n}\nconst orderedByX=concordant+discordant+tiedYOnly;\nconst orderedByY=concordant+discordant+tiedXOnly;\nif(orderedByX===0||orderedByY===0)return null;\nreturn(concordant-discordant)/Math.sqrt(orderedByX*orderedByY);\n}\nfunction seriesStats(ordered,opts={}){\nconst n=ordered.length;\nif(n<2)return null;\nconst first=ordered[0];\nconst last=ordered[n-1];\nconst returns=[];\nfor(let i=1;i<n;i++){\nconst previous=ordered[i-1];\nif(previous===0)continue;\nreturns.push((ordered[i]-previous)/Math.abs(previous));\n}\nlet volatility=null;\nif(returns.length>1){\nlet mean=0;\nfor(const r of returns)mean+=r;\nmean/=returns.length;\nlet m2=0;\nfor(const r of returns)m2+=(r-mean)**2;\nvolatility=Math.sqrt(m2/(returns.length-1));\n}\nconst periods=Number(opts.periodsPerYear)>0?Number(opts.periodsPerYear):null;\nlet peak=ordered[0];\nlet peakAt=0;\nlet worst=0;\nlet worstFrom=0;\nlet worstTo=0;\nfor(let i=1;i<n;i++){\nif(ordered[i]>peak){peak=ordered[i];peakAt=i;continue;}\nif(peak<=0)continue;\nconst fall=(peak-ordered[i])/peak;\nif(fall>worst){worst=fall;worstFrom=peakAt;worstTo=i;}\n}\nlet autocorrelation=null;\nif(n>2){\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet top=0;\nlet bottom=0;\nfor(let i=0;i<n;i++){\nconst d=ordered[i]-mean;\nbottom+=d*d;\nif(i>0)top+=d*(ordered[i-1]-mean);\n}\nautocorrelation=bottom>0?top/bottom:null;\n}\nlet up=0;\nlet down=0;\nfor(const r of returns){if(r>0)up++;else if(r<0)down++;}\nlet growth=null;\nif(first>0&&last>0){\nconst perPeriod=(last/first)**(1/(n-1))-1;\ngrowth=periods?(1+perPeriod)**periods-1:perPeriod;\n}\nreturn{\nn,\nfirst,\nlast,\nchange:last-first,\nchangePercent:first===0?null:((last-first)/Math.abs(first))*100,\nvolatility,\nannualisedVolatility:volatility!==null&&periods?volatility*Math.sqrt(periods):null,\ngrowth,\nmaxDrawdown:worst,\nmaxDrawdownFrom:worstFrom,\nmaxDrawdownTo:worstTo,\nautocorrelation,\nupDays:up,\ndownDays:down,\n};\n}\nconst D2_N2=1.128;\nconst D4_N2=3.267;\nfunction movingRanges(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst ranges=[];\nfor(let i=1;i<n;i++)ranges.push(Math.abs(ordered[i]-ordered[i-1]));\nconst centre=ranges.reduce((t,r)=>t+r,0)/ranges.length;\nreturn{ranges,centre,upper:D4_N2*centre,lower:0};\n}\nfunction withinSigma(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nlet total=0;\nfor(let i=1;i<n;i++)total+=Math.abs(ordered[i]-ordered[i-1]);\nconst meanRange=total/(n-1);\nreturn{sigma:meanRange/D2_N2,meanRange};\n}\nfunction capability(ordered,spec){\nconst n=ordered.length;\nif(n<2||!spec)return null;\nconst lower=Number.isFinite(Number(spec.lower))?Number(spec.lower):null;\nconst upper=Number.isFinite(Number(spec.upper))?Number(spec.upper):null;\nif(lower===null&&upper===null)return null;\nlet mean=0;\nfor(let i=0;i<n;i++)mean+=ordered[i];\nmean/=n;\nlet m2=0;\nfor(let i=0;i<n;i++)m2+=(ordered[i]-mean)**2;\nconst overall=Math.sqrt(m2/(n-1));\nconst within=withinSigma(ordered);\nconst sigmaWithin=within?within.sigma:null;\nconst indices=(sigma)=>{\nif(!sigma||sigma<=0)return{index:null,k:null};\nconst both=lower!==null&&upper!==null;\nconst index=both?(upper-lower)/(6*sigma):null;\nconst upperSide=upper!==null?(upper-mean)/(3*sigma):Infinity;\nconst lowerSide=lower!==null?(mean-lower)/(3*sigma):Infinity;\nreturn{index,k:Math.min(upperSide,lowerSide)};\n};\nconst short=indices(sigmaWithin);\nconst long=indices(overall);\nlet outOfSpec=0;\nfor(let i=0;i<n;i++){\nif(lower!==null&&ordered[i]<lower){outOfSpec++;continue;}\nif(upper!==null&&ordered[i]>upper)outOfSpec++;\n}\nreturn{\nn,\nmean,\nlower,\nupper,\ntarget:Number.isFinite(Number(spec.target))?Number(spec.target):null,\nsigmaWithin,\nsigmaOverall:overall,\ncp:short.index,\ncpk:short.k,\npp:long.index,\nppk:long.k,\noutOfSpec,\ndefectRate:n?outOfSpec/n:null,\n};\n}\nfunction controlLimits(ordered){\nconst n=ordered.length;\nif(n<2)return null;\nconst within=withinSigma(ordered);\nif(!within||!(within.sigma>0))return null;\nlet centre=0;\nfor(let i=0;i<n;i++)centre+=ordered[i];\ncentre/=n;\nreturn{\ncentre,\nsigma:within.sigma,\nupper:centre+3*within.sigma,\nlower:centre-3*within.sigma,\n};\n}\nfunction westernElectricViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3){\nout.push({index:i,rule:1,description:'beyond three sigma'});\n}\nif(i>=2){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-2;k<=i;k++)if(z(k)*side>2)hits++;\nif(hits>=2){\nout.push({index:i,rule:2,description:'two of three past two sigma'});\nbreak;\n}\n}\n}\nif(i>=4){\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=i-4;k<=i;k++)if(z(k)*side>1)hits++;\nif(hits>=4){\nout.push({index:i,rule:3,description:'four of five past one sigma'});\nbreak;\n}\n}\n}\nif(i>=7){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-7;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){\nout.push({index:i,rule:4,description:'eight in a row on one side'});\nbreak;\n}\n}\n}\n}\nreturn out;\n}\nfunction nelsonViolations(ordered,limits){\nif(!limits||!(limits.sigma>0))return[];\nconst n=ordered.length;\nconst{centre,sigma}=limits;\nconst z=(i)=>(ordered[i]-centre)/sigma;\nconst oneSide=(from,to,past,need)=>{\nfor(const side of[1,-1]){\nlet hits=0;\nfor(let k=from;k<=to;k++)if(z(k)*side>past)hits++;\nif(hits>=need)return true;\n}\nreturn false;\n};\nconst out=[];\nfor(let i=0;i<n;i++){\nif(Math.abs(z(i))>3)out.push({index:i,rule:1,description:'beyond three sigma'});\nif(i>=8){\nfor(const side of[1,-1]){\nlet all=true;\nfor(let k=i-8;k<=i;k++)if(z(k)*side<=0){all=false;break;}\nif(all){out.push({index:i,rule:2,description:'nine in a row on one side'});break;}\n}\n}\nif(i>=5){\nfor(const dir of[1,-1]){\nlet all=true;\nfor(let k=i-4;k<=i;k++){\nif((ordered[k]-ordered[k-1])*dir<=0){all=false;break;}\n}\nif(all){\nout.push({index:i,rule:3,description:dir>0?'six rising':'six falling'});\nbreak;\n}\n}\n}\nif(i>=13){\nlet alternating=true;\nfor(let k=i-12;k<=i;k++){\nconst a=ordered[k]-ordered[k-1];\nconst b=ordered[k+1<=i?k+1:k]-ordered[k];\nif(k+1>i)break;\nif(a===0||b===0||(a>0)===(b>0)){alternating=false;break;}\n}\nif(alternating)out.push({index:i,rule:4,description:'fourteen alternating'});\n}\nif(i>=2&&oneSide(i-2,i,2,2)){\nout.push({index:i,rule:5,description:'two of three past two sigma'});\n}\nif(i>=4&&oneSide(i-4,i,1,4)){\nout.push({index:i,rule:6,description:'four of five past one sigma'});\n}\nif(i>=14){\nlet inside=true;\nfor(let k=i-14;k<=i;k++)if(Math.abs(z(k))>=1){inside=false;break;}\nif(inside)out.push({index:i,rule:7,description:'fifteen within one sigma'});\n}\nif(i>=7){\nlet outside=true;\nfor(let k=i-7;k<=i;k++)if(Math.abs(z(k))<=1){outside=false;break;}\nif(outside)out.push({index:i,rule:8,description:'eight beyond one sigma'});\n}\n}\nreturn out;\n}\nconst CONTROL_RULE_SETS=Object.freeze(['westernElectric','nelson']);\nfunction controlViolations(ordered,limits,ruleSet='westernElectric'){\nreturn String(ruleSet)==='nelson'\n?nelsonViolations(ordered,limits)\n:westernElectricViolations(ordered,limits);\n}\nfunction countOutside(values,low,high){\nlet count=0;\nfor(let i=0;i<values.length;i++){\nif(values[i]<low||values[i]>high)count++;\n}\nreturn count;\n}\nfunction histogram(sorted,q1,q3,cap=20){\nconst n=sorted.length;\nif(!n)return[];\nconst min=sorted[0];\nconst max=sorted[n-1];\nif(max===min)return[{from:min,to:max,count:n}];\nconst iqr=q3-q1;\nconst fence=1.5*iqr;\nlet lo=iqr>0?Math.max(min,q1-fence):min;\nlet hi=iqr>0?Math.min(max,q3+fence):max;\nif(!(hi>lo)){lo=min;hi=max;}\nconst width=iqr>0?(2*iqr)/Math.cbrt(n):(hi-lo)/(Math.ceil(Math.log2(n))+1);\nconst count=width>0\n?Math.min(cap,Math.max(1,Math.ceil((hi-lo)/width)))\n:1;\nconst step=(hi-lo)/count;\nconst bins=[];\nfor(let i=0;i<count;i++){\nbins.push({from:lo+i*step,to:lo+(i+1)*step,count:0});\n}\nfor(let i=0;i<n;i++){\nconst at=Math.min(count-1,Math.max(0,Math.floor((sorted[i]-lo)/step)));\nbins[at].count++;\n}\nbins[0].from=min;\nbins[count-1].to=max;\nreturn bins;\n}\nconst DEFAULT_CONFIDENCE=0.95;\nfunction level(conf){\nconst c=Number(conf);\nreturn Number.isFinite(c)&&c>0&&c<1?c:DEFAULT_CONFIDENCE;\n}\nfunction meanInterval(values,conf=DEFAULT_CONFIDENCE){\nconst n=values.length;\nif(n<2)return null;\nlet sum=0;\nfor(let i=0;i<n;i++)sum+=values[i];\nconst mean=sum/n;\nlet ss=0;\nfor(let i=0;i<n;i++){const d=values[i]-mean;ss+=d*d;}\nconst sd=Math.sqrt(ss/(n-1));\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,n-1);\nconst margin=(t*sd)/Math.sqrt(n);\nreturn{mean,lower:mean-margin,upper:mean+margin,margin,n,confidence:c};\n}\nfunction proportionInterval(successes,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(successes);\nconst total=Number(n);\nif(!(total>0)||!(k>=0)||k>total)return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst p=k/total;\nconst z2=z*z;\nconst denominator=1+z2/total;\nconst centre=(p+z2/(2*total))/denominator;\nconst half=(z/denominator)\n*Math.sqrt((p*(1-p))/total+z2/(4*total*total));\nreturn{\nproportion:p,\nlower:Math.max(0,centre-half),\nupper:Math.min(1,centre+half),\nn:total,\nconfidence:c,\n};\n}\nfunction slopeInterval(fit,conf=DEFAULT_CONFIDENCE){\nif(!fit||!(fit.n>2)||!Number.isFinite(fit.stdError))return null;\nconst c=level(conf);\nconst t=studentTQuantile(1-(1-c)/2,fit.n-2);\nconst margin=t*fit.stdError;\nreturn{\nslope:fit.slope,\nlower:fit.slope-margin,\nupper:fit.slope+margin,\nmargin,\nconfidence:c,\n};\n}\nfunction capabilityInterval(index,n,conf=DEFAULT_CONFIDENCE){\nconst k=Number(index);\nconst count=Number(n);\nif(!Number.isFinite(k)||!(count>1))return null;\nconst c=level(conf);\nconst z=normalQuantile(1-(1-c)/2);\nconst margin=z*Math.sqrt(1/(9*count)+(k*k)/(2*(count-1)));\nreturn{index:k,lower:k-margin,upper:k+margin,margin,n:count,confidence:c};\n}\n});\n__def(\"packages/core/src/compute/total.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return TOTAL_FNS;}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return TOTAL_LABELS;}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return totalLabel;}});\nObject.defineProperty(__exports,\"aggregatesFor\",{enumerable:true,get:function(){return aggregatesFor;}});\nObject.defineProperty(__exports,\"aggregateAllowed\",{enumerable:true,get:function(){return aggregateAllowed;}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return collectValues;}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return total;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst isFunction=__m0[\"isFunction\"];\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m1[\"presenceReader\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst valueReader=__m1[\"valueReader\"];\nconst __m2=__req(\"packages/core/src/compute/statistics.js\");\nconst STAT_FNS=__m2[\"STAT_FNS\"];\nconst STAT_LABELS=__m2[\"STAT_LABELS\"];\nfunction isNumericBacking(handle){\nreturn!!handle&&(handle.kind==='float64'||handle.kind==='int32');\n}\nfunction sum(handle,indices){\nconst n=indices.length;\nlet acc=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(!Number.isNaN(v))acc+=v;\n}\nreturn acc;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1){\nconst v=values[row];\nif(!Number.isNaN(v))acc+=v;\n}\n}\nreturn acc;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=numberOf(read(indices[i]));\nif(v!==null)acc+=v;\n}\nreturn acc;\n}\nsum.kernel=true;\nfunction countValues(handle,indices){\nconst n=indices.length;\nlet count=0;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nif(!present){\nfor(let i=0;i<n;i++)if(!Number.isNaN(values[indices[i]]))count++;\nreturn count;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===1&&!Number.isNaN(values[row]))count++;\n}\nreturn count;\n}\nconst read=valueReader(handle);\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v!==null&&v!==undefined&&!(typeof v==='number'&&Number.isNaN(v)))count++;\n}\nreturn count;\n}\ncountValues.kernel=true;\nfunction count(handle,indices){\nreturn indices.length;\n}\ncount.kernel=true;\nfunction avg(handle,indices){\nconst values=countValues(handle,indices);\nif(values===0)return null;\nreturn sum(handle,indices)/values;\n}\navg.kernel=true;\nfunction extreme(handle,indices,direction,locale){\nconst n=indices.length;\nif(isNumericBacking(handle)){\nconst values=handle.values;\nconst present=presenceReader(handle);\nlet best=null;\nif(!present){\nfor(let i=0;i<n;i++){\nconst v=values[indices[i]];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nfor(let i=0;i<n;i++){\nconst row=indices[i];\nif(present(row)===0)continue;\nconst v=values[row];\nif(Number.isNaN(v))continue;\nif(best===null||(direction<0?v<best:v>best))best=v;\n}\nreturn best;\n}\nconst read=valueReader(handle);\nconst cmp=valueComparator(locale);\nlet best=null;\nfor(let i=0;i<n;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v)))continue;\nif(best===null||(direction<0?cmp(v,best)<0:cmp(v,best)>0))best=v;\n}\nreturn best;\n}\nfunction min(handle,indices,ctx){\nreturn extreme(handle,indices,-1,ctx&&ctx.locale);\n}\nmin.kernel=true;\nfunction max(handle,indices,ctx){\nreturn extreme(handle,indices,1,ctx&&ctx.locale);\n}\nmax.kernel=true;\nfunction first(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[0]);\n}\nfirst.kernel=true;\nfunction last(handle,indices){\nif(indices.length===0)return null;\nreturn valueReader(handle)(indices[indices.length-1]);\n}\nlast.kernel=true;\nfunction numberOf(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nconst TOTAL_FNS={\nsum,min,max,avg,count,first,last,countValues,\n...STAT_FNS,\n};\nconst TOTAL_LABELS=Object.freeze({\n...STAT_LABELS,\nsum:'Sum',\navg:'Average',\nmin:'Min',\nmax:'Max',\ncount:'Count',\ncountValues:'Count of values',\nfirst:'First',\nlast:'Last',\n});\nfunction totalLabel(fn){\nif(!fn)return'';\nif(typeof fn==='string')return TOTAL_LABELS[fn]||fn;\nreturn'Total';\n}\nconst CHOOSER_ORDER=Object.freeze([\n'sum','avg','min','max','count','countValues','first','last',\n]);\nfunction aggregatesFor(column){\nconst supported=column&&column.dataType\n&&column.dataType.totals&&column.dataType.totals.supported;\nif(Array.isArray(supported))return supported.slice();\nconst named=CHOOSER_ORDER.filter((name)=>name in TOTAL_FNS);\nfor(const name of Object.keys(TOTAL_FNS))if(!named.includes(name))named.push(name);\nreturn named;\n}\nfunction aggregateAllowed(column,name){\nif(typeof name!=='string')return true;\nreturn aggregatesFor(column).includes(name);\n}\nfunction collectValues(handle,indices){\nconst read=valueReader(handle);\nconst out=[];\nfor(let i=0;i<indices.length;i++){\nconst v=read(indices[i]);\nif(v===null||v===undefined)continue;\nout.push(v);\n}\nreturn out;\n}\nfunction total(handle,indices,fn,ctx){\nconst list=indices||[];\nif(typeof fn==='string'){\nconst kernel=TOTAL_FNS[fn];\nif(!kernel){\nwarnOnce(`total:${fn}`,`unknown total function \"${fn}\"; register it in config.totalFns`);\nreturn null;\n}\nreturn kernel(handle,list,ctx);\n}\nif(isFunction(fn)){\nif(fn.kernel===true)return fn(handle,list,ctx);\nreturn fn(collectValues(handle,list),ctx||{});\n}\nreturn null;\n}\n});\n__def(\"packages/core/src/compute/pivot.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return KEY_DELIMITER;}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return DEFAULT_PATH_SEPARATOR;}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return DEFAULT_MAX_COLUMNS;}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return pivotKey;}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return joinPath;}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return resolvePivotKeys;}});\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return pivot;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst warnOnce=__m0[\"warnOnce\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nconst packKeys=__m2[\"packKeys\"];\nconst __m3=__req(\"packages/core/src/compute/total.js\");\nconst total=__m3[\"total\"];\nconst KEY_DELIMITER='|';\nconst DEFAULT_PATH_SEPARATOR='/';\nconst DEFAULT_MAX_COLUMNS=2000;\nfunction pivotKey(groupPath,pivotPath,colId){\nreturn`${groupPath}${KEY_DELIMITER}${pivotPath}${KEY_DELIMITER}${colId}`;\n}\nfunction joinPath(parts,separator){\nlet out='';\nfor(let i=0;i<parts.length;i++){\nconst v=parts[i];\nout+=(i===0?'':separator)+(v===null||v===undefined?'':String(v));\n}\nreturn out;\n}\nfunction resolvePivotKeys(handles,order,opts={}){\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst n=order.length;\nconst{keyOf,readers}=packKeys(handles,order,0);\nconst seen=new Map();\nconst tuples=[];\nconst rawKeys=[];\nfor(let i=0;i<n;i++){\nconst row=order[i];\nconst key=keyOf(row);\nif(seen.has(key))continue;\nseen.set(key,tuples.length);\nrawKeys.push(key);\nconst tuple=new Array(readers.length);\nfor(let j=0;j<readers.length;j++)tuple[j]=readers[j](row);\ntuples.push(tuple);\n}\nconst cmp=valueComparator(opts.locale);\nconst rank=tuples.map((_,i)=>i);\nrank.sort((a,b)=>{\nconst ta=tuples[a];\nconst tb=tuples[b];\nfor(let j=0;j<ta.length;j++){\nconst c=compareNullable(ta[j],tb[j],cmp);\nif(c!==0)return c;\n}\nreturn a-b;\n});\nconst keys=new Array(rank.length);\nconst paths=new Array(rank.length);\nconst idByKey=new Map();\nfor(let position=0;position<rank.length;position++){\nconst from=rank[position];\nkeys[position]=tuples[from];\npaths[position]=joinPath(tuples[from],separator);\nidByKey.set(rawKeys[from],position);\n}\nconst idOf=(row)=>{\nconst id=idByKey.get(keyOf(row));\nreturn id===undefined?-1:id;\n};\nreturn{keys,paths,idOf};\n}\nfunction compareNullable(a,b,cmp){\nconst na=a===null||a===undefined;\nconst nb=b===null||b===undefined;\nif(na||nb)return na&&nb?0:na?1:-1;\nreturn cmp(a,b);\n}\nfunction resolveValueColumns(opts){\nconst declared=opts.values||opts.totals||[];\nif(declared.length&&typeof declared[0]==='object'&&declared[0]!==null){\nreturn declared.filter((entry)=>entry&&entry.handle);\n}\nconst resolve=typeof opts.handle==='function'?opts.handle:null;\nif(!resolve){\nif(declared.length){\nwarnOnce('pivot:handles',\n'pivot was given total column ids but no handle(colId) resolver, so no cell values were reduced. Pass values: [{ colId, handle, fn }] or opts.handle.');\n}\nreturn[];\n}\nconst totalOf=typeof opts.totalOf==='function'?opts.totalOf:null;\nconst out=[];\nfor(const colId of declared){\nconst handle=resolve(colId);\nif(!handle)continue;\nout.push({colId,handle,fn:totalOf?totalOf(colId):'sum'});\n}\nreturn out;\n}\nfunction normaliseArgs(a,b,c){\nif(Array.isArray(a)){\nconst opts=c||{};\nreturn{...opts,pivotHandles:a,order:b||null,groups:opts.groups||null};\n}\nreturn a||{};\n}\nfunction pivot(input,orderArg,optsArg){\nconst opts=normaliseArgs(input,orderArg,optsArg);\nconst separator=opts.separator||DEFAULT_PATH_SEPARATOR;\nconst valueColumns=resolveValueColumns(opts);\nconst maxColumns=opts.maxColumns===undefined?DEFAULT_MAX_COLUMNS:opts.maxColumns;\nconst groups=opts.groups&&opts.groups.buckets?opts.groups:null;\nconst buckets=groups?groups.buckets:[opts.order||new Uint32Array(0)];\nconst groupPaths=opts.groupPaths\n||(groups?groups.keys.map((tuple)=>joinPath(tuple,separator)):['']);\nconst scope=concatIndices(buckets);\nconst{keys,paths,idOf}=resolvePivotKeys(opts.pivotHandles||[],scope,opts);\nconst columns=paths.length*Math.max(1,valueColumns.length);\nconst fields=derivedFields(paths,valueColumns,separator);\nif(maxColumns&&columns>maxColumns){\nconst empty=new Map();\nreturn{\nkeys,\npaths,\nfields,\ngroupPaths,\ncolumns,\nvalues:empty,\ncells:empty,\nerror:{\ncode:'pivot-max-columns',\nmessage:`[lattice] pivot would generate ${columns} columns, above pivot.maxColumns of ${maxColumns}. Narrow the pivot columns or raise the limit.`,\ncolumns,\nmaxColumns,\n},\n};\n}\nconst cells=new Map();\nconst keyCount=paths.length;\nfor(let g=0;g<buckets.length;g++){\nconst bucket=buckets[g];\nconst groupPath=groupPaths[g]===undefined?'':groupPaths[g];\nconst n=bucket.length;\nif(n===0)continue;\nconst ids=new Int32Array(n);\nconst counts=new Uint32Array(keyCount+1);\nfor(let i=0;i<n;i++){\nconst id=idOf(bucket[i]);\nids[i]=id;\nif(id>=0)counts[id+1]++;\n}\nfor(let k=0;k<keyCount;k++)counts[k+1]+=counts[k];\nconst scattered=new Uint32Array(n);\nconst cursor=counts.slice(0,keyCount);\nfor(let i=0;i<n;i++){\nconst id=ids[i];\nif(id>=0)scattered[cursor[id]++]=bucket[i];\n}\nfor(let k=0;k<keyCount;k++){\nconst from=counts[k];\nconst to=counts[k+1];\nif(to===from)continue;\nconst slice=scattered.subarray(from,to);\nfor(let c=0;c<valueColumns.length;c++){\nconst column=valueColumns[c];\nconst result=total(column.handle,slice,column.fn,opts.totalContext||{locale:opts.locale});\ncells.set(pivotKey(groupPath,paths[k],column.colId),result);\n}\n}\n}\nreturn{keys,paths,fields,groupPaths,columns,values:cells,cells,error:null};\n}\nfunction derivedFields(paths,valueColumns,separator){\nif(valueColumns.length===0)return paths.slice();\nconst out=[];\nfor(const path of paths){\nfor(const column of valueColumns)out.push(`${path}${separator}${column.colId}`);\n}\nreturn out;\n}\nfunction concatIndices(buckets){\nif(buckets.length===1)return buckets[0]||new Uint32Array(0);\nlet n=0;\nfor(const b of buckets)n+=b?b.length:0;\nconst out=new Uint32Array(n);\nlet at=0;\nfor(const b of buckets){\nif(!b||b.length===0)continue;\nout.set(b,at);\nat+=b.length;\n}\nreturn out;\n}\n});\n__def(\"packages/core/src/compute/reference.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return referenceValue;}});\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return referenceSort;}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return referenceFilter;}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return referencePasses;}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return referenceGroup;}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return referenceTotal;}});\nconst __m0=__req(\"packages/core/src/internal/util.js\");\nconst getPath=__m0[\"getPath\"];\nconst __m1=__req(\"packages/core/src/compute/handle.js\");\nconst isMissing=__m1[\"isMissing\"];\nconst valueComparator=__m1[\"valueComparator\"];\nconst __m2=__req(\"packages/core/src/compute/filter.js\");\nconst testValue=__m2[\"testValue\"];\nconst KEY_SEPARATOR=String.fromCharCode(0x1f);\nconst NULL_MARKER=String.fromCharCode(0x00);\nfunction referenceValue(row,col){\nconst v=col.includes('.')?getPath(row,col):(row==null?undefined:row[col]);\nreturn v===undefined?null:v;\n}\nfunction referenceSort(rows,entries,opts={}){\nconst list=entries||[];\nlet order=rows.map((_,i)=>i);\nif(list.length===0)return order;\nfor(let e=list.length-1;e>=0;e--){\norder=referenceSortOne(rows,order,list[e],opts);\n}\nreturn order;\n}\nfunction referenceSortOne(rows,order,entry,opts){\nconst locale=entry.locale!==undefined?entry.locale:opts.locale;\nconst base=valueComparator(locale);\nconst descending=entry.descending!==undefined?!!entry.descending:entry.dir==='desc';\nconst present=[];\nconst absent=[];\nfor(const i of order){\nconst v=referenceValue(rows[i],entry.col);\nif(isMissing(v))absent.push(i);else present.push(i);\n}\nconst position=new Map();\nfor(let p=0;p<present.length;p++)position.set(present[p],p);\nconst compare=(a,b)=>{\nconst va=referenceValue(rows[a],entry.col);\nconst vb=referenceValue(rows[b],entry.col);\nlet c;\nif(typeof entry.compare==='function'){\nc=entry.compare(va,vb,rows[a],rows[b],descending);\nif(descending)c=-c;\n}else{\nc=descending?base(vb,va):base(va,vb);\n}\nreturn c!==0?c:position.get(a)-position.get(b);\n};\npresent.sort(compare);\nreturn entry.nullsFirst?absent.concat(present):present.concat(absent);\n}\nfunction referenceFilter(rows,filters,opts={}){\nconst out=[];\nfor(let i=0;i<rows.length;i++){\nif(referencePasses(rows[i],filters,opts,i))out.push(i);\n}\nreturn out;\n}\nfunction referencePasses(row,node,opts,index){\nif(!node)return true;\nif(Array.isArray(node.conditions)){\nconst children=node.conditions.filter((c)=>c!=null);\nif(children.length===0)return true;\nif(node.op==='or')return children.some((c)=>referencePasses(row,c,opts,index));\nconst all=children.every((c)=>referencePasses(row,c,opts,index));\nreturn node.op==='not'?!all:all;\n}\nif(node.col===undefined&&typeof opts.custom==='function')return!!opts.custom(node,row,index);\nreturn testValue(referenceValue(row,node.col),node,opts.locale);\n}\nfunction referenceGroup(rows,cols,order){\nconst source=order||rows.map((_,i)=>i);\nconst seen=new Map();\nconst keys=[];\nconst buckets=[];\nfor(const i of source){\nconst tuple=cols.map((col)=>referenceValue(rows[i],col));\nconst key=tuple\n.map((v)=>(v===null||v===undefined?NULL_MARKER:String(v)))\n.join(KEY_SEPARATOR);\nlet at=seen.get(key);\nif(at===undefined){\nat=keys.length;\nseen.set(key,at);\nkeys.push(tuple);\nbuckets.push([]);\n}\nbuckets[at].push(i);\n}\nreturn{keys,buckets};\n}\nfunction referenceTotal(values,fn,opts={}){\nconst cmp=valueComparator(opts.locale);\nconst live=values.filter((v)=>!isMissing(v));\nconst numbers=live.map(toNumberOrNull).filter((v)=>v!==null);\nswitch(fn){\ncase'count':return values.length;\ncase'countValues':return live.length;\ncase'sum':return numbers.reduce((a,b)=>a+b,0);\ncase'avg':return live.length===0?null:numbers.reduce((a,b)=>a+b,0)/live.length;\ncase'min':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)<0?b:a));\ncase'max':return live.length===0?null:live.reduce((a,b)=>(cmp(b,a)>0?b:a));\ncase'first':return values.length===0?null:normaliseNull(values[0]);\ncase'last':return values.length===0?null:normaliseNull(values[values.length-1]);\ndefault:return null;\n}\n}\nfunction toNumberOrNull(v){\nif(typeof v==='number')return Number.isNaN(v)?null:v;\nif(v===null||v===undefined||v===''||typeof v==='boolean')return null;\nif(v instanceof Date)return v.getTime();\nconst n=Number(v);\nreturn Number.isNaN(n)?null:n;\n}\nfunction normaliseNull(v){\nreturn v===undefined?null:v;\n}\n});\n__def(\"packages/core/src/compute/index.js\",function(__exports,__req){\n'use strict';\nconst __m0=__req(\"packages/core/src/compute/sort.js\");\nObject.defineProperty(__exports,\"sortColumn\",{enumerable:true,get:function(){return __m0[\"sortColumn\"];}});\nObject.defineProperty(__exports,\"sortMulti\",{enumerable:true,get:function(){return __m0[\"sortMulti\"];}});\nObject.defineProperty(__exports,\"radixSortFloat64\",{enumerable:true,get:function(){return __m0[\"radixSortFloat64\"];}});\nObject.defineProperty(__exports,\"radixSortInt32\",{enumerable:true,get:function(){return __m0[\"radixSortInt32\"];}});\nObject.defineProperty(__exports,\"rankSortDictionary\",{enumerable:true,get:function(){return __m0[\"rankSortDictionary\"];}});\nObject.defineProperty(__exports,\"mergeSortComparator\",{enumerable:true,get:function(){return __m0[\"mergeSortComparator\"];}});\nconst __m1=__req(\"packages/core/src/compute/filter.js\");\nObject.defineProperty(__exports,\"evaluateFilters\",{enumerable:true,get:function(){return __m1[\"evaluateFilters\"];}});\nObject.defineProperty(__exports,\"evaluateCondition\",{enumerable:true,get:function(){return __m1[\"evaluateCondition\"];}});\nObject.defineProperty(__exports,\"compact\",{enumerable:true,get:function(){return __m1[\"compact\"];}});\nObject.defineProperty(__exports,\"testValue\",{enumerable:true,get:function(){return __m1[\"testValue\"];}});\nObject.defineProperty(__exports,\"compilePredicate\",{enumerable:true,get:function(){return __m1[\"compilePredicate\"];}});\nObject.defineProperty(__exports,\"releaseMask\",{enumerable:true,get:function(){return __m1[\"releaseMask\"];}});\nObject.defineProperty(__exports,\"pruneColumn\",{enumerable:true,get:function(){return __m1[\"pruneColumn\"];}});\nObject.defineProperty(__exports,\"mentionsColumn\",{enumerable:true,get:function(){return __m1[\"mentionsColumn\"];}});\nconst __m2=__req(\"packages/core/src/compute/group.js\");\nObject.defineProperty(__exports,\"groupByColumns\",{enumerable:true,get:function(){return __m2[\"groupByColumns\"];}});\nObject.defineProperty(__exports,\"packKeys\",{enumerable:true,get:function(){return __m2[\"packKeys\"];}});\nconst __m3=__req(\"packages/core/src/compute/facet.js\");\nObject.defineProperty(__exports,\"facet\",{enumerable:true,get:function(){return __m3[\"facet\"];}});\nObject.defineProperty(__exports,\"computeBounds\",{enumerable:true,get:function(){return __m3[\"computeBounds\"];}});\nObject.defineProperty(__exports,\"countInto\",{enumerable:true,get:function(){return __m3[\"countInto\"];}});\nObject.defineProperty(__exports,\"bucketOf\",{enumerable:true,get:function(){return __m3[\"bucketOf\"];}});\nObject.defineProperty(__exports,\"facetKind\",{enumerable:true,get:function(){return __m3[\"facetKind\"];}});\nObject.defineProperty(__exports,\"cardinalityOf\",{enumerable:true,get:function(){return __m3[\"cardinalityOf\"];}});\nObject.defineProperty(__exports,\"pickGranularity\",{enumerable:true,get:function(){return __m3[\"pickGranularity\"];}});\nObject.defineProperty(__exports,\"floorTo\",{enumerable:true,get:function(){return __m3[\"floorTo\"];}});\nObject.defineProperty(__exports,\"advance\",{enumerable:true,get:function(){return __m3[\"advance\"];}});\nObject.defineProperty(__exports,\"STRATEGIES\",{enumerable:true,get:function(){return __m3[\"STRATEGIES\"];}});\nObject.defineProperty(__exports,\"GRANULARITIES\",{enumerable:true,get:function(){return __m3[\"GRANULARITIES\"];}});\nObject.defineProperty(__exports,\"DEFAULT_BUCKETS\",{enumerable:true,get:function(){return __m3[\"DEFAULT_BUCKETS\"];}});\nObject.defineProperty(__exports,\"DEFAULT_CARDINALITY_LIMIT\",{enumerable:true,get:function(){return __m3[\"DEFAULT_CARDINALITY_LIMIT\"];}});\nObject.defineProperty(__exports,\"QUANTILE_SAMPLE\",{enumerable:true,get:function(){return __m3[\"QUANTILE_SAMPLE\"];}});\nconst __m4=__req(\"packages/core/src/compute/total.js\");\nObject.defineProperty(__exports,\"TOTAL_FNS\",{enumerable:true,get:function(){return __m4[\"TOTAL_FNS\"];}});\nObject.defineProperty(__exports,\"TOTAL_LABELS\",{enumerable:true,get:function(){return __m4[\"TOTAL_LABELS\"];}});\nObject.defineProperty(__exports,\"totalLabel\",{enumerable:true,get:function(){return __m4[\"totalLabel\"];}});\nObject.defineProperty(__exports,\"total\",{enumerable:true,get:function(){return __m4[\"total\"];}});\nObject.defineProperty(__exports,\"collectValues\",{enumerable:true,get:function(){return __m4[\"collectValues\"];}});\nconst __m5=__req(\"packages/core/src/compute/pivot.js\");\nObject.defineProperty(__exports,\"pivot\",{enumerable:true,get:function(){return __m5[\"pivot\"];}});\nObject.defineProperty(__exports,\"resolvePivotKeys\",{enumerable:true,get:function(){return __m5[\"resolvePivotKeys\"];}});\nObject.defineProperty(__exports,\"pivotKey\",{enumerable:true,get:function(){return __m5[\"pivotKey\"];}});\nObject.defineProperty(__exports,\"joinPath\",{enumerable:true,get:function(){return __m5[\"joinPath\"];}});\nObject.defineProperty(__exports,\"KEY_DELIMITER\",{enumerable:true,get:function(){return __m5[\"KEY_DELIMITER\"];}});\nObject.defineProperty(__exports,\"DEFAULT_PATH_SEPARATOR\",{enumerable:true,get:function(){return __m5[\"DEFAULT_PATH_SEPARATOR\"];}});\nObject.defineProperty(__exports,\"DEFAULT_MAX_COLUMNS\",{enumerable:true,get:function(){return __m5[\"DEFAULT_MAX_COLUMNS\"];}});\nconst __m6=__req(\"packages/core/src/compute/reference.js\");\nObject.defineProperty(__exports,\"referenceSort\",{enumerable:true,get:function(){return __m6[\"referenceSort\"];}});\nObject.defineProperty(__exports,\"referenceFilter\",{enumerable:true,get:function(){return __m6[\"referenceFilter\"];}});\nObject.defineProperty(__exports,\"referenceGroup\",{enumerable:true,get:function(){return __m6[\"referenceGroup\"];}});\nObject.defineProperty(__exports,\"referenceTotal\",{enumerable:true,get:function(){return __m6[\"referenceTotal\"];}});\nObject.defineProperty(__exports,\"referencePasses\",{enumerable:true,get:function(){return __m6[\"referencePasses\"];}});\nObject.defineProperty(__exports,\"referenceValue\",{enumerable:true,get:function(){return __m6[\"referenceValue\"];}});\nconst __m7=__req(\"packages/core/src/compute/handle.js\");\nObject.defineProperty(__exports,\"identity\",{enumerable:true,get:function(){return __m7[\"identity\"];}});\nObject.defineProperty(__exports,\"rowCount\",{enumerable:true,get:function(){return __m7[\"rowCount\"];}});\nObject.defineProperty(__exports,\"presenceReader\",{enumerable:true,get:function(){return __m7[\"presenceReader\"];}});\nObject.defineProperty(__exports,\"bitReader\",{enumerable:true,get:function(){return __m7[\"bitReader\"];}});\nObject.defineProperty(__exports,\"valueReader\",{enumerable:true,get:function(){return __m7[\"valueReader\"];}});\nObject.defineProperty(__exports,\"valueComparator\",{enumerable:true,get:function(){return __m7[\"valueComparator\"];}});\nObject.defineProperty(__exports,\"numericTotalOrder\",{enumerable:true,get:function(){return __m7[\"numericTotalOrder\"];}});\nObject.defineProperty(__exports,\"dictRanks\",{enumerable:true,get:function(){return __m7[\"dictRanks\"];}});\nObject.defineProperty(__exports,\"dictSize\",{enumerable:true,get:function(){return __m7[\"dictSize\"];}});\nObject.defineProperty(__exports,\"dictValue\",{enumerable:true,get:function(){return __m7[\"dictValue\"];}});\nObject.defineProperty(__exports,\"multiValue\",{enumerable:true,get:function(){return __m7[\"multiValue\"];}});\nObject.defineProperty(__exports,\"isMissing\",{enumerable:true,get:function(){return __m7[\"isMissing\"];}});\n});\n__def(\"packages/worker/src/kernel.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"loadCompute\",{enumerable:true,get:function(){return loadCompute;}});\nObject.defineProperty(__exports,\"setCompute\",{enumerable:true,get:function(){return setCompute;}});\nObject.defineProperty(__exports,\"dispatch\",{enumerable:true,get:function(){return dispatch;}});\nObject.defineProperty(__exports,\"handleMessage\",{enumerable:true,get:function(){return handleMessage;}});\nObject.defineProperty(__exports,\"installKernel\",{enumerable:true,get:function(){return installKernel;}});\nconst __m0=__req(\"packages/worker/src/transport.js\");\nconst PROTOCOL=__m0[\"PROTOCOL\"];\nconst OPS=__m0[\"OPS\"];\nconst CONTROL=__m0[\"CONTROL\"];\nconst ERRORS=__m0[\"ERRORS\"];\nconst unpackHandle=__m0[\"unpackHandle\"];\nconst unpackHandles=__m0[\"unpackHandles\"];\nconst createMaskPool=__m0[\"createMaskPool\"];\nconst collectTransfers=__m0[\"collectTransfers\"];\nconst __m1=__req(\"packages/core/src/store/columnpack.js\");\nconst packChunk=__m1[\"packChunk\"];\nconst packedTransfers=__m1[\"packedTransfers\"];\nlet computeModule=null;\nlet computePromise=null;\nlet computeError=null;\nasync function loadCompute(loader){\nif(computeModule)return computeModule;\nif(!computePromise){\nconst load=loader||(()=>Promise.resolve(__req(\"packages/core/src/compute/index.js\")));\ncomputePromise=Promise.resolve()\n.then(load)\n.then((mod)=>{computeModule=mod;return mod;})\n.catch((err)=>{\ncomputeError=err;\ncomputeModule=null;\nreturn null;\n});\n}\nreturn computePromise;\n}\nfunction setCompute(mod){\ncomputeModule=mod;\ncomputePromise=mod?Promise.resolve(mod):null;\ncomputeError=mod?null:computeError;\n}\nfunction filterContext(handles,count,locale){\nconst byId=new Map();\nfor(const h of handles)if(h)byId.set(h.id,h);\nreturn{\nhandle(colId){return byId.get(colId);},\ncount,\npool:createMaskPool(),\nlocale,\n};\n}\nfunction dispatch(request,compute){\nconst{op,args}=request;\nif(op===OPS.COLUMNIZE){\nreturn packChunk(args.schema||[],args.rows||[],args.opts||{});\n}\nconst fn=compute[op];\nif(typeof fn!=='function'){\nconst err=new Error(`[lattice] compute kernel '${op}' is not exported`);\n(err).code=ERRORS.NO_KERNEL;\nthrow err;\n}\nswitch(op){\ncase OPS.SORT_COLUMN:\nreturn fn(unpackHandle(args.handle),args.order??null,args.opts||{});\ncase OPS.SORT_MULTI:{\nconst handles=unpackHandles(args.handles||[]);\nconst entries=(args.entries||[]).map((e)=>({\n...e,\nhandle:handles[e.index],\n}));\nreturn fn(handles,entries,args.order??null);\n}\ncase OPS.EVALUATE_FILTERS:\nreturn fn(args.filters,filterContext(unpackHandles(args.handles||[]),args.count,args.locale));\ncase OPS.COMPACT:\nreturn fn(args.mask,args.count,undefined);\ncase OPS.GROUP_BY_COLUMNS:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.TOTAL:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.fn);\ncase OPS.PIVOT:\nreturn fn(unpackHandles(args.handles||[]),args.order??null,args.opts||{});\ncase OPS.FACET:\nreturn fn(unpackHandle(args.handle),args.indices??null,args.count,args.opts||{});\ndefault:{\nconst err=new Error(`[lattice] unknown worker op '${op}'`);\n(err).code=ERRORS.PROTOCOL;\nthrow err;\n}\n}\n}\nasync function handleMessage(message,opts={}){\nif(!message||message.lattice!==PROTOCOL)return null;\nconst{id,op}=message;\nif(op===CONTROL.CANCEL){\nopts.cancelled?.add(message.target);\nreturn null;\n}\nif(op===CONTROL.PING){\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result:'pong'},transfer:[]};\n}\nif(op===OPS.COLUMNIZE){\nif(opts.cancelled?.has(id)){opts.cancelled.delete(id);return null;}\ntry{\nconst result=packChunk(message.args.schema||[],message.args.rows||[],message.args.opts||{});\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:packedTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{lattice:PROTOCOL,id,ok:false,error:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack}},\ntransfer:[],\n};\n}\n}\nconst compute=await loadCompute(opts.loader);\nif(!compute){\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{\ncode:ERRORS.NO_COMPUTE,\nmessage:`[lattice] compute kernels unavailable in worker: ${computeError?computeError.message:'module not found'}`,\n},\n},\ntransfer:[],\n};\n}\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\ntry{\nconst result=dispatch(message,compute);\nif(opts.cancelled?.has(id)){\nopts.cancelled.delete(id);\nreturn{reply:{lattice:PROTOCOL,id,ok:false,error:{code:ERRORS.ABORTED,message:'[lattice] request superseded'}},transfer:[]};\n}\nreturn{reply:{lattice:PROTOCOL,id,ok:true,result},transfer:collectTransfers(result)};\n}catch(err){\nconst e=(err);\nreturn{\nreply:{\nlattice:PROTOCOL,\nid,\nok:false,\nerror:{code:e.code||ERRORS.KERNEL,message:e.message||String(err),stack:e.stack},\n},\ntransfer:[],\n};\n}\n}\nfunction installKernel(scope,opts={}){\nconst cancelled=new Set();\nconst onMessage=async(event)=>{\nconst outcome=await handleMessage(event.data,{loader:opts.loader,cancelled});\nif(!outcome)return;\nscope.postMessage(outcome.reply,outcome.transfer);\n};\nscope.addEventListener('message',onMessage);\nloadCompute(opts.loader).then((mod)=>{\nscope.postMessage({lattice:PROTOCOL,id:0,op:CONTROL.READY,compute:!!mod});\n});\nreturn()=>scope.removeEventListener('message',onMessage);\n}\n});\nvar __entry=__req(\"packages/worker/src/kernel.js\");\nroot[\"__latticeKernel\"]=__entry;\n})(typeof globalThis!=='undefined'?globalThis:this);\n__latticeKernel.installKernel(self);\n",{type:'classic'});
67870
69197
  }catch(err){}
67871
69198
  const __entry=__req("packages/dom/src/index.js");
67872
69199
  export const