@toclocoinc/lattice-grid 1.8.0 → 1.9.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.8.0 — core + DOM renderer
2
+ * Lattice Grid 1.9.0 — core + DOM renderer
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -51,7 +51,7 @@ Object.defineProperty(__exports,"cancelFrame",{enumerable:true,get:function(){re
51
51
  Object.defineProperty(__exports,"frameBatched",{enumerable:true,get:function(){return frameBatched;}});
52
52
  Object.defineProperty(__exports,"whenIdle",{enumerable:true,get:function(){return whenIdle;}});
53
53
  Object.defineProperty(__exports,"uid",{enumerable:true,get:function(){return uid;}});
54
- const VERSION='1.8.0';
54
+ const VERSION='1.9.0';
55
55
  const warned=new Set();
56
56
  const reported=[];
57
57
  const REPORT_LIMIT=500;
@@ -3396,9 +3396,65 @@ other:'{count} cells updated',
3396
3396
  'panel.quickFilter':'Quick filter',
3397
3397
  'panel.formatting':'Formatting',
3398
3398
  'panel.statistics':'Statistics',
3399
+ 'panel.compare':'Compare',
3400
+ 'compare.first':'First column',
3401
+ 'compare.second':'Second column',
3402
+ 'compare.needTwo':'Two numeric columns are needed to compare',
3403
+ 'compare.noPairs':'No rows have a value in both',
3404
+ 'compare.pairs':'{count} pairs',
3405
+ 'compare.pearson':'Correlation (Pearson)',
3406
+ 'compare.spearman':'Rank correlation (Spearman)',
3407
+ 'compare.kendall':'Kendall’s tau',
3408
+ 'compare.covariance':'Covariance',
3409
+ 'compare.slope':'Slope',
3410
+ 'compare.intercept':'Intercept',
3411
+ 'compare.r2':'R²',
3412
+ 'compare.stdError':'Standard error',
3413
+ 'compare.weighted':'Weighted average',
3399
3414
  'panel.zone.group':'row groups',
3400
3415
  'panel.zone.values':'values',
3401
3416
  'panel.zone.pivot':'pivot columns',
3417
+ 'total.sum':'Sum',
3418
+ 'total.avg':'Average',
3419
+ 'total.min':'Min',
3420
+ 'total.max':'Max',
3421
+ 'total.count':'Count',
3422
+ 'total.countValues':'Count of values',
3423
+ 'total.first':'First',
3424
+ 'total.last':'Last',
3425
+ 'total.median':'Median',
3426
+ 'total.p25':'25th percentile',
3427
+ 'total.p75':'75th percentile',
3428
+ 'total.p90':'90th percentile',
3429
+ 'total.p95':'95th percentile',
3430
+ 'total.p99':'99th percentile',
3431
+ 'total.iqr':'Interquartile range',
3432
+ 'total.mad':'Median absolute deviation',
3433
+ 'total.variance':'Variance',
3434
+ 'total.varianceP':'Variance (population)',
3435
+ 'total.stddev':'Standard deviation',
3436
+ 'total.stddevP':'Standard deviation (population)',
3437
+ 'total.range':'Range',
3438
+ 'total.distinct':'Distinct',
3439
+ 'total.mode':'Mode',
3440
+ 'total.skewness':'Skewness',
3441
+ 'total.kurtosis':'Kurtosis',
3442
+ 'total.geomean':'Geometric mean',
3443
+ 'total.harmean':'Harmonic mean',
3444
+ 'total.sumSquares':'Sum of squares',
3445
+ 'total.weightedAvg':'Weighted average',
3446
+ 'total.argmin':'Lowest by',
3447
+ 'total.argmax':'Highest by',
3448
+ 'total.hhi':'Concentration (HHI)',
3449
+ 'total.entropy':'Entropy',
3450
+ 'total.evenness':'Evenness',
3451
+ 'total.top3Share':'Top 3 share',
3452
+ 'total.top10Share':'Top 10 share',
3453
+ 'total.gini':'Gini coefficient',
3454
+ 'total.trimmedMean':'Trimmed mean',
3455
+ 'total.winsorizedMean':'Winsorized mean',
3456
+ 'total.robustOutliers':'Outliers (robust)',
3457
+ 'total.jarqueBera':'Jarque–Bera',
3402
3458
  'stats.column':'Column',
3403
3459
  'stats.choose':'Choose a column to profile',
3404
3460
  'stats.noColumns':'No numeric columns to profile',
@@ -3418,6 +3474,15 @@ other:'{count} cells updated',
3418
3474
  'stats.outliers':'Outliers',
3419
3475
  'stats.distribution':'Distribution',
3420
3476
  'stats.bin':'{count} between {from} and {to}',
3477
+ 'stats.section.shape':'Shape',
3478
+ 'stats.section.robust':'Robust',
3479
+ 'stats.section.concentration':'Concentration',
3480
+ 'stats.section.capability':'Capability',
3481
+ 'stats.cp':'Cp',
3482
+ 'stats.cpk':'Cpk',
3483
+ 'stats.pp':'Pp',
3484
+ 'stats.ppk':'Ppk',
3485
+ 'stats.outOfSpec':'Out of specification',
3421
3486
  'stats.filtered':'Over the {count} filtered rows',
3422
3487
  'menu.sortAscending':'Sort ascending',
3423
3488
  'menu.sortDescending':'Sort descending',
@@ -4184,6 +4249,69 @@ unit('gon',Math.PI/200,['grad','gradian','gradians'],{auto:false}),
4184
4249
  unit('rad',1,['radian','radians']),
4185
4250
  unit('turn',2*Math.PI,['rev','revolution','revolutions'],{auto:false}),
4186
4251
  ]),
4252
+ angularVelocity:Object.freeze([
4253
+ unit('°/s',Math.PI/180,['degps','deg/s','degrees/s'],{auto:false}),
4254
+ unit('rad/s',1,['radps','radians/s']),
4255
+ unit('rpm',(2*Math.PI)/60,['rev/min','r/min','revolutions/min'],{auto:false}),
4256
+ unit('rps',2*Math.PI,['rev/s','r/s','revolutions/s'],{auto:false}),
4257
+ ]),
4258
+ fraction:Object.freeze([
4259
+ unit('ppt',1e-12,['partspertrillion'],{auto:false}),
4260
+ unit('ppb',1e-9,['partsperbillion']),
4261
+ unit('ppm',1e-6,['partspermillion']),
4262
+ unit('bp',1e-4,['bps-finance','basispoint','basispoints','bips'],{auto:false}),
4263
+ unit('‰',1e-3,['permille','permil'],{auto:false}),
4264
+ unit('%',1e-2,['pct','percent']),
4265
+ unit('×',1,['x','ratio','times']),
4266
+ ]),
4267
+ molarity:Object.freeze([
4268
+ unit('pM',1e-12,['picomolar','picomolarity']),
4269
+ unit('nM',1e-9,['nanomolar','nanomolarity']),
4270
+ unit('µM',1e-6,['um-molar','micromolar','micromolarity']),
4271
+ unit('mM',1e-3,['millimolar','millimolarity']),
4272
+ unit('M',1,['molar','mol/l','mol/L','molarity']),
4273
+ unit('mol/m³',1e-3,['mol/m3'],{auto:false}),
4274
+ ]),
4275
+ massFlow:Object.freeze([
4276
+ unit('mg/s',1e-6,['milligrams/s']),
4277
+ unit('g/s',1e-3,['grams/s']),
4278
+ unit('kg/h',1/3600,['kilograms/h','kgph'],{auto:false}),
4279
+ unit('kg/s',1,['kilograms/s','kgps']),
4280
+ unit('t/h',1000/3600,['tonnes/h','tph'],{auto:false}),
4281
+ unit('lb/h',0.45359237/3600,['pounds/h','pph'],{auto:false}),
4282
+ unit('t/s',1000,['tonnes/s'],{auto:false}),
4283
+ ]),
4284
+ viscosity:Object.freeze([
4285
+ unit('µPa·s',1e-6,['upas','micropascalsecond']),
4286
+ unit('cP',1e-3,['centipoise'],{auto:false}),
4287
+ unit('mPa·s',1e-3,['mpas','millipascalsecond']),
4288
+ unit('P',0.1,['poise'],{auto:false}),
4289
+ unit('Pa·s',1,['pas','pascalsecond']),
4290
+ ]),
4291
+ kinematicViscosity:Object.freeze([
4292
+ unit('cSt',1e-6,['centistokes','centistoke']),
4293
+ unit('mm²/s',1e-6,['mm2/s'],{auto:false}),
4294
+ unit('St',1e-4,['stokes','stoke'],{auto:false}),
4295
+ unit('m²/s',1,['m2/s']),
4296
+ ]),
4297
+ thermalConductivity:Object.freeze([
4298
+ unit('mW/(m·K)',1e-3,['mw/mk']),
4299
+ unit('W/(m·K)',1,['w/mk','wmk']),
4300
+ unit('kW/(m·K)',1e3,['kw/mk'],{auto:false}),
4301
+ unit('BTU/(hr·ft·°F)',1.730734666,['btu/hrftf'],{auto:false}),
4302
+ ]),
4303
+ specificHeat:Object.freeze([
4304
+ unit('J/(kg·K)',1,['j/kgk','jkgk']),
4305
+ unit('kJ/(kg·K)',1e3,['kj/kgk']),
4306
+ unit('cal/(g·°C)',4184,['cal/gc'],{auto:false}),
4307
+ ]),
4308
+ doseRate:Object.freeze([
4309
+ unit('nSv/h',1e-9,['nsvh']),
4310
+ unit('µSv/h',1e-6,['usv/h','usvh']),
4311
+ unit('mSv/h',1e-3,['msvh']),
4312
+ unit('Sv/h',1,['svh']),
4313
+ unit('mSv/a',1e-3/8766,['msv/year','msvpa'],{auto:false}),
4314
+ ]),
4187
4315
  });
4188
4316
  const AMBIGUOUS=Symbol('ambiguous');
4189
4317
  const indexes=new Map();
@@ -4304,6 +4432,7 @@ return out;
4304
4432
  }
4305
4433
  const SPACES=/[\s   ]/g;
4306
4434
  const NUMBER_HEAD=/^[+-]?[\d   '’ .,]*(?:[eE][+-]?\d+)?/;
4435
+ const LEADING_SYMBOL=/^[^\d+\-(.,\s]+\s*/;
4307
4436
  const PLAIN_NUMBER=/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/;
4308
4437
  function parseLocaleNumber(text,locale){
4309
4438
  const{group,decimal}=localeSeparators(locale);
@@ -4343,11 +4472,18 @@ let s=String(text).trim();
4343
4472
  if(s==='')return null;
4344
4473
  let negative=false;
4345
4474
  if(s.startsWith('(')&&s.endsWith(')')){negative=true;s=s.slice(1,-1).trim();}
4475
+ let leading=null;
4476
+ const front=LEADING_SYMBOL.exec(s);
4477
+ if(front&&front[0]){
4478
+ const candidate=resolveToken(front[0].trim(),ctx.index,ctx.binary);
4479
+ if(candidate){leading=candidate;s=s.slice(front[0].length).trim();}
4480
+ }
4346
4481
  const head=NUMBER_HEAD.exec(s)[0];
4347
4482
  const n=parseLocaleNumber(head,opts&&opts.locale);
4348
4483
  if(n===null)return null;
4349
4484
  const suffix=s.slice(head.length).trim();
4350
- const from=suffix===''?ctx.base:resolveToken(suffix,ctx.index,ctx.binary);
4485
+ if(leading&&suffix!=='')return null;
4486
+ const from=leading||(suffix===''?ctx.base:resolveToken(suffix,ctx.index,ctx.binary));
4351
4487
  if(!from)return null;
4352
4488
  const value=convert(n,from,ctx.base);
4353
4489
  return negative?-value:value;
@@ -4427,7 +4563,10 @@ min=significantDecimals(shown,figures);
4427
4563
  max=min;
4428
4564
  }
4429
4565
  const text=numberFormat(cfg.locale,min,max,cfg.group!==false).format(shown);
4430
- return`${text}${cfg.space??' '}${target.symbol}`;
4566
+ const gap=cfg.space??' ';
4567
+ return cfg.placement==='prefix'
4568
+ ?`${target.symbol}${cfg.space??''}${text}`
4569
+ :`${text}${gap}${target.symbol}`;
4431
4570
  }
4432
4571
  function compareUnit(a,b){
4433
4572
  const an=isNil(a)||Number.isNaN(a)?null:Number(a);
@@ -4555,6 +4694,21 @@ system:'angle',unit:'rad',maxDecimals:4,totals:angularTotals(2*Math.PI),
4555
4694
  degrees:createUnitType({
4556
4695
  system:'angle',unit:'°',maxDecimals:2,totals:angularTotals(360),
4557
4696
  }),
4697
+ rpm:createUnitType({system:'angularVelocity',unit:'rpm',maxDecimals:0}),
4698
+ angularVelocity:createUnitType({system:'angularVelocity',unit:'rad/s',maxDecimals:3}),
4699
+ ppm:createUnitType({system:'fraction',unit:'ppm',maxDecimals:2}),
4700
+ ppb:createUnitType({system:'fraction',unit:'ppb',maxDecimals:2}),
4701
+ basisPoints:createUnitType({system:'fraction',unit:'bp',maxDecimals:1}),
4702
+ molarity:createUnitType({system:'molarity',unit:'M',display:'auto',maxDecimals:3}),
4703
+ massFlow:createUnitType({system:'massFlow',unit:'kg/s',maxDecimals:3}),
4704
+ tonnesPerHour:createUnitType({system:'massFlow',unit:'t/h',maxDecimals:2}),
4705
+ viscosity:createUnitType({system:'viscosity',unit:'Pa·s',display:'auto',maxDecimals:3}),
4706
+ kinematicViscosity:createUnitType({system:'kinematicViscosity',unit:'cSt',maxDecimals:2}),
4707
+ thermalConductivity:createUnitType({
4708
+ system:'thermalConductivity',unit:'W/(m·K)',maxDecimals:3,
4709
+ }),
4710
+ specificHeat:createUnitType({system:'specificHeat',unit:'J/(kg·K)',maxDecimals:1}),
4711
+ doseRate:createUnitType({system:'doseRate',unit:'µSv/h',display:'auto',maxDecimals:2}),
4558
4712
  });
4559
4713
  });
4560
4714
  __def("packages/core/src/columns/types/si.js",function(__exports,__req){
@@ -4651,6 +4805,7 @@ extra:[defineUnit('G',1e-4,['gauss'],{auto:false})],
4651
4805
  }),
4652
4806
  luminousFlux:createSiType('luminousFlux',{base:'lm',name:'lumen',prefixes:['m','','k']}),
4653
4807
  illuminance:createSiType('illuminance',{base:'lx',name:'lux',prefixes:['m','','k']}),
4808
+ luminousIntensity:createSiType('luminousIntensity',{base:'cd',name:'candela',prefixes:['m','','k']}),
4654
4809
  substance:createSiType('substance',{
4655
4810
  base:'mol',name:'mole',prefixes:['n','µ','m','','k'],
4656
4811
  }),
@@ -6550,7 +6705,22 @@ compute:(deps,ctx)=>{
6550
6705
  const api=ctx.grid&&ctx.grid.statistics;
6551
6706
  if(!api)return null;
6552
6707
  const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6553
- return key?api.shadow(watched,spec.kind,key):null;
6708
+ return key?api.shadow(watched,spec.kind,key,spec.scope):null;
6709
+ },
6710
+ };
6711
+ }
6712
+ if(def.running&&!isFunction(m.value&&m.value.compute)){
6713
+ const spec=typeof def.running==='string'?{kind:def.running}:def.running;
6714
+ const source=spec.of||def.field||id;
6715
+ m.value={
6716
+ ...(m.value||{}),
6717
+ deps:[source],
6718
+ pure:false,
6719
+ compute:(deps,ctx)=>{
6720
+ const api=ctx.grid&&ctx.grid.statistics;
6721
+ if(!api||!isFunction(api.running))return null;
6722
+ const key=(ctx.row&&ctx.row.key)||api.keyOf(ctx.data);
6723
+ return key?api.running(source,spec.kind||'total',key):null;
6554
6724
  },
6555
6725
  };
6556
6726
  }
@@ -6560,7 +6730,9 @@ const column={
6560
6730
  id,
6561
6731
  field,
6562
6732
  shadow:def.shadow||null,
6563
- volatile:!!def.shadow,
6733
+ running:def.running||null,
6734
+ spec:def.spec||null,
6735
+ volatile:!!(def.shadow||def.running),
6564
6736
  title:m.title??humanise(field||id),
6565
6737
  type:typeName,
6566
6738
  dataType:type,
@@ -7196,6 +7368,7 @@ class ShadowTracker{
7196
7368
  #max;
7197
7369
  #now;
7198
7370
  #summary=null;
7371
+ #filtered=null;
7199
7372
  constructor(opts){
7200
7373
  this.#colId=opts.colId;
7201
7374
  this.#depth=Math.max(2,opts.depth||DEFAULT_DEPTH);
@@ -7210,6 +7383,7 @@ const value=toNumber(raw);
7210
7383
  if(value===null)return;
7211
7384
  if(!this.#latest.has(key)){
7212
7385
  this.#summary=null;
7386
+ this.#filtered=null;
7213
7387
  this.#evictIfFull();
7214
7388
  this.#baseline.set(key,value);
7215
7389
  this.#latest.set(key,value);
@@ -7222,6 +7396,7 @@ return;
7222
7396
  const previous=this.#latest.get(key);
7223
7397
  if(previous===value)return;
7224
7398
  this.#summary=null;
7399
+ this.#filtered=null;
7225
7400
  this.#latest.set(key,value);
7226
7401
  this.#counts.set(key,(this.#counts.get(key)||0)+1);
7227
7402
  this.#stamps.set(key,this.#now());
@@ -7248,6 +7423,7 @@ this.#forgotten++;
7248
7423
  rebase(){
7249
7424
  for(const[key,value]of this.#latest)this.#baseline.set(key,value);
7250
7425
  this.#summary=null;
7426
+ this.#filtered=null;
7251
7427
  }
7252
7428
  reset(){
7253
7429
  this.#baseline.clear();
@@ -7258,6 +7434,7 @@ this.#history.clear();
7258
7434
  this.#streaks.clear();
7259
7435
  this.#forgotten=0;
7260
7436
  this.#summary=null;
7437
+ this.#filtered=null;
7261
7438
  }
7262
7439
  retain(keys){
7263
7440
  const living=keys instanceof Set?keys:new Set(keys);
@@ -7272,10 +7449,10 @@ this.#history.delete(key);
7272
7449
  this.#streaks.delete(key);
7273
7450
  dropped++;
7274
7451
  }
7275
- if(dropped)this.#summary=null;
7452
+ if(dropped){this.#summary=null;this.#filtered=null;}
7276
7453
  return dropped;
7277
7454
  }
7278
- read(kind,key){
7455
+ read(kind,key,only){
7279
7456
  switch(kind){
7280
7457
  case'updates':
7281
7458
  return this.#counts.has(key)?this.#counts.get(key):0;
@@ -7312,12 +7489,27 @@ return this.#history.has(key)?[...this.#history.get(key)]:null;
7312
7489
  case'streak':
7313
7490
  return this.#streaks.has(key)?this.#streaks.get(key):0;
7314
7491
  default:
7315
- return POSITIONAL_KINDS.includes(kind)?this.#position(kind,key):null;
7492
+ return POSITIONAL_KINDS.includes(kind)?this.#position(kind,key,only):null;
7493
+ }
7316
7494
  }
7495
+ #view(only){
7496
+ if(only){
7497
+ if(this.#filtered&&this.#filtered.only===only)return this.#filtered.view;
7498
+ const view=this.#build(only);
7499
+ this.#filtered={only,view};
7500
+ return view;
7317
7501
  }
7318
- #view(){
7319
7502
  if(this.#summary)return this.#summary;
7320
- const sorted=[...this.#latest.values()].sort((a,b)=>a-b);
7503
+ this.#summary=this.#build(null);
7504
+ return this.#summary;
7505
+ }
7506
+ #build(only){
7507
+ const values=[];
7508
+ for(const[key,value]of this.#latest){
7509
+ if(only&&!only.has(key))continue;
7510
+ values.push(value);
7511
+ }
7512
+ const sorted=values.sort((a,b)=>a-b);
7321
7513
  let n=0;
7322
7514
  let mean=0;
7323
7515
  let m2=0;
@@ -7329,19 +7521,24 @@ const delta=x-mean;
7329
7521
  mean+=delta/n;
7330
7522
  m2+=delta*(x-mean);
7331
7523
  }
7332
- this.#summary={
7524
+ const baseline=[];
7525
+ for(const[key,value]of this.#baseline){
7526
+ if(only&&!only.has(key))continue;
7527
+ baseline.push(value);
7528
+ }
7529
+ return{
7333
7530
  sorted,
7334
- baseline:[...this.#baseline.values()].sort((a,b)=>a-b),
7531
+ baseline:baseline.sort((a,b)=>a-b),
7335
7532
  sum,
7336
7533
  mean:n?mean:0,
7337
7534
  sd:n>1?Math.sqrt(m2/(n-1)):0,
7338
7535
  };
7339
- return this.#summary;
7340
7536
  }
7341
- #position(kind,key){
7537
+ #position(kind,key,only){
7342
7538
  if(!this.#latest.has(key))return null;
7539
+ if(only&&!only.has(key))return null;
7343
7540
  const value=this.#latest.get(key);
7344
- const view=this.#view();
7541
+ const view=this.#view(only);
7345
7542
  const n=view.sorted.length;
7346
7543
  if(!n)return null;
7347
7544
  switch(kind){
@@ -7601,8 +7798,15 @@ return v===null||v===undefined||(typeof v==='number'&&Number.isNaN(v));
7601
7798
  });
7602
7799
  __def("packages/core/src/compute/statistics.js",function(__exports,__req){
7603
7800
  'use strict';
7801
+ Object.defineProperty(__exports,"KENDALL_LIMIT",{enumerable:true,get:function(){return KENDALL_LIMIT;}});
7604
7802
  Object.defineProperty(__exports,"MAINTENANCE",{enumerable:true,get:function(){return MAINTENANCE;}});
7605
7803
  Object.defineProperty(__exports,"numbers",{enumerable:true,get:function(){return numbers;}});
7804
+ Object.defineProperty(__exports,"frequencies",{enumerable:true,get:function(){return frequencies;}});
7805
+ Object.defineProperty(__exports,"herfindahl",{enumerable:true,get:function(){return herfindahl;}});
7806
+ Object.defineProperty(__exports,"entropy",{enumerable:true,get:function(){return entropy;}});
7807
+ Object.defineProperty(__exports,"evenness",{enumerable:true,get:function(){return evenness;}});
7808
+ Object.defineProperty(__exports,"topShare",{enumerable:true,get:function(){return topShare;}});
7809
+ Object.defineProperty(__exports,"gini",{enumerable:true,get:function(){return gini;}});
7606
7810
  Object.defineProperty(__exports,"moments",{enumerable:true,get:function(){return moments;}});
7607
7811
  Object.defineProperty(__exports,"quantileSorted",{enumerable:true,get:function(){return quantileSorted;}});
7608
7812
  Object.defineProperty(__exports,"quantile",{enumerable:true,get:function(){return quantile;}});
@@ -7611,11 +7815,28 @@ Object.defineProperty(__exports,"STAT_LABELS",{enumerable:true,get:function(){re
7611
7815
  Object.defineProperty(__exports,"weightedAverage",{enumerable:true,get:function(){return weightedAverage;}});
7612
7816
  Object.defineProperty(__exports,"extremeRow",{enumerable:true,get:function(){return extremeRow;}});
7613
7817
  Object.defineProperty(__exports,"correlation",{enumerable:true,get:function(){return correlation;}});
7818
+ Object.defineProperty(__exports,"trimmedMean",{enumerable:true,get:function(){return trimmedMean;}});
7819
+ Object.defineProperty(__exports,"winsorizedMean",{enumerable:true,get:function(){return winsorizedMean;}});
7820
+ Object.defineProperty(__exports,"modifiedZOutliers",{enumerable:true,get:function(){return modifiedZOutliers;}});
7821
+ Object.defineProperty(__exports,"jarqueBera",{enumerable:true,get:function(){return jarqueBera;}});
7822
+ Object.defineProperty(__exports,"weightedQuantile",{enumerable:true,get:function(){return weightedQuantile;}});
7823
+ Object.defineProperty(__exports,"pairs",{enumerable:true,get:function(){return pairs;}});
7824
+ Object.defineProperty(__exports,"covariance",{enumerable:true,get:function(){return covariance;}});
7825
+ Object.defineProperty(__exports,"regression",{enumerable:true,get:function(){return regression;}});
7826
+ Object.defineProperty(__exports,"spearman",{enumerable:true,get:function(){return spearman;}});
7827
+ Object.defineProperty(__exports,"kendall",{enumerable:true,get:function(){return kendall;}});
7828
+ Object.defineProperty(__exports,"seriesStats",{enumerable:true,get:function(){return seriesStats;}});
7829
+ Object.defineProperty(__exports,"D2_N2",{enumerable:true,get:function(){return D2_N2;}});
7830
+ Object.defineProperty(__exports,"withinSigma",{enumerable:true,get:function(){return withinSigma;}});
7831
+ Object.defineProperty(__exports,"capability",{enumerable:true,get:function(){return capability;}});
7832
+ Object.defineProperty(__exports,"controlLimits",{enumerable:true,get:function(){return controlLimits;}});
7833
+ Object.defineProperty(__exports,"controlViolations",{enumerable:true,get:function(){return controlViolations;}});
7614
7834
  Object.defineProperty(__exports,"countOutside",{enumerable:true,get:function(){return countOutside;}});
7615
7835
  Object.defineProperty(__exports,"histogram",{enumerable:true,get:function(){return histogram;}});
7616
7836
  const __m0=__req("packages/core/src/compute/handle.js");
7617
7837
  const presenceReader=__m0["presenceReader"];
7618
7838
  const valueReader=__m0["valueReader"];
7839
+ const KENDALL_LIMIT=5000;
7619
7840
  const MAINTENANCE=Object.freeze({
7620
7841
  variance:'maintained',
7621
7842
  varianceP:'maintained',
@@ -7640,6 +7861,16 @@ harmean:'rescan',
7640
7861
  mad:'rescan',
7641
7862
  argmin:'rescan',
7642
7863
  argmax:'rescan',
7864
+ hhi:'rescan',
7865
+ entropy:'rescan',
7866
+ evenness:'rescan',
7867
+ top3Share:'rescan',
7868
+ top10Share:'rescan',
7869
+ gini:'rescan',
7870
+ trimmedMean:'rescan',
7871
+ winsorizedMean:'rescan',
7872
+ robustOutliers:'rescan',
7873
+ jarqueBera:'rescan',
7643
7874
  });
7644
7875
  function numbers(handle,indices){
7645
7876
  const n=indices.length;
@@ -7668,6 +7899,68 @@ out[count++]=v;
7668
7899
  }
7669
7900
  return out.subarray(0,count);
7670
7901
  }
7902
+ function frequencies(handle,indices){
7903
+ const seen=new Map();
7904
+ const read=valueReader(handle);
7905
+ let total=0;
7906
+ for(let i=0;i<indices.length;i++){
7907
+ const raw=read(indices[i]);
7908
+ if(raw===null||raw===undefined||raw==='')continue;
7909
+ if(typeof raw==='number'&&Number.isNaN(raw))continue;
7910
+ const key=typeof raw==='object'?String(raw):raw;
7911
+ seen.set(key,(seen.get(key)||0)+1);
7912
+ total++;
7913
+ }
7914
+ const counts=[...seen.values()].sort((a,b)=>b-a);
7915
+ return{counts,total,distinct:counts.length};
7916
+ }
7917
+ function sharesOf(freq){
7918
+ return freq.total>0?freq.counts.map((c)=>c/freq.total):[];
7919
+ }
7920
+ function herfindahl(handle,indices){
7921
+ const freq=frequencies(handle,indices);
7922
+ if(!freq.total)return null;
7923
+ let sum=0;
7924
+ for(const share of sharesOf(freq))sum+=share*share;
7925
+ return sum;
7926
+ }
7927
+ function entropy(handle,indices){
7928
+ const freq=frequencies(handle,indices);
7929
+ if(!freq.total)return null;
7930
+ let sum=0;
7931
+ for(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);
7932
+ return sum;
7933
+ }
7934
+ function evenness(handle,indices){
7935
+ const freq=frequencies(handle,indices);
7936
+ if(!freq.total||freq.distinct<2)return freq.total?1:null;
7937
+ let sum=0;
7938
+ for(const share of sharesOf(freq))if(share>0)sum-=share*Math.log2(share);
7939
+ return sum/Math.log2(freq.distinct);
7940
+ }
7941
+ function topShare(handle,indices,n=3){
7942
+ const freq=frequencies(handle,indices);
7943
+ if(!freq.total)return null;
7944
+ const take=Math.max(1,Math.floor(n));
7945
+ let held=0;
7946
+ for(let i=0;i<Math.min(take,freq.counts.length);i++)held+=freq.counts[i];
7947
+ return held/freq.total;
7948
+ }
7949
+ function gini(handle,indices){
7950
+ const values=numbers(handle,indices);
7951
+ const n=values.length;
7952
+ if(!n)return null;
7953
+ const sorted=values.slice().sort();
7954
+ if(sorted[0]<0)return null;
7955
+ let total=0;
7956
+ let weighted=0;
7957
+ for(let i=0;i<n;i++){
7958
+ total+=sorted[i];
7959
+ weighted+=(i+1)*sorted[i];
7960
+ }
7961
+ if(total===0)return 0;
7962
+ return(2*weighted)/(n*total)-(n+1)/n;
7963
+ }
7671
7964
  function moments(values){
7672
7965
  let n=0;
7673
7966
  let mean=0;
@@ -7697,6 +7990,16 @@ const sorted=values.slice().sort();
7697
7990
  return quantileSorted(sorted,p);
7698
7991
  }
7699
7992
  const STAT_FNS=Object.freeze({
7993
+ hhi:(h,i)=>herfindahl(h,i),
7994
+ entropy:(h,i)=>entropy(h,i),
7995
+ evenness:(h,i)=>evenness(h,i),
7996
+ top3Share:(h,i)=>topShare(h,i,3),
7997
+ top10Share:(h,i)=>topShare(h,i,10),
7998
+ gini:(h,i)=>gini(h,i),
7999
+ trimmedMean:(h,i)=>trimmedMean(numbers(h,i),0.1),
8000
+ winsorizedMean:(h,i)=>winsorizedMean(numbers(h,i),0.1),
8001
+ robustOutliers:(h,i)=>modifiedZOutliers(numbers(h,i),3.5),
8002
+ jarqueBera:(h,i)=>jarqueBera(numbers(h,i)),
7700
8003
  variance:(h,i)=>{
7701
8004
  const{n,m2}=moments(numbers(h,i));
7702
8005
  return n>1?m2/(n-1):null;
@@ -7839,6 +8142,16 @@ return sum;
7839
8142
  },
7840
8143
  });
7841
8144
  const STAT_LABELS=Object.freeze({
8145
+ hhi:'Concentration (HHI)',
8146
+ entropy:'Entropy',
8147
+ evenness:'Evenness',
8148
+ top3Share:'Top 3 share',
8149
+ top10Share:'Top 10 share',
8150
+ gini:'Gini coefficient',
8151
+ trimmedMean:'Trimmed mean',
8152
+ winsorizedMean:'Winsorized mean',
8153
+ robustOutliers:'Outliers (robust)',
8154
+ jarqueBera:'Jarque–Bera',
7842
8155
  median:'Median',
7843
8156
  p25:'25th percentile',
7844
8157
  p75:'75th percentile',
@@ -7921,6 +8234,393 @@ if(bottom===0)return null;
7921
8234
  const r=top/bottom;
7922
8235
  return Math.max(-1,Math.min(1,r));
7923
8236
  }
8237
+ function trimmedMean(values,share=0.1){
8238
+ const n=values.length;
8239
+ if(!n)return null;
8240
+ const sorted=Array.from(values).sort((a,b)=>a-b);
8241
+ const cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));
8242
+ const kept=sorted.slice(cut,n-cut);
8243
+ if(!kept.length)return quantileSorted(sorted,0.5);
8244
+ let sum=0;
8245
+ for(const v of kept)sum+=v;
8246
+ return sum/kept.length;
8247
+ }
8248
+ function winsorizedMean(values,share=0.1){
8249
+ const n=values.length;
8250
+ if(!n)return null;
8251
+ const sorted=Array.from(values).sort((a,b)=>a-b);
8252
+ const cut=Math.floor(n*Math.min(0.49,Math.max(0,share)));
8253
+ const low=sorted[cut];
8254
+ const high=sorted[n-1-cut];
8255
+ let sum=0;
8256
+ for(const v of sorted)sum+=Math.min(high,Math.max(low,v));
8257
+ return sum/n;
8258
+ }
8259
+ function modifiedZOutliers(values,threshold=3.5){
8260
+ const n=values.length;
8261
+ if(!n)return null;
8262
+ const sorted=Array.from(values).sort((a,b)=>a-b);
8263
+ const middle=quantileSorted(sorted,0.5);
8264
+ const deviations=sorted.map((v)=>Math.abs(v-middle)).sort((a,b)=>a-b);
8265
+ const mad=quantileSorted(deviations,0.5);
8266
+ if(mad===0)return null;
8267
+ let count=0;
8268
+ for(const v of sorted)if(Math.abs((0.6745*(v-middle))/mad)>threshold)count++;
8269
+ return count;
8270
+ }
8271
+ function jarqueBera(values){
8272
+ const n=values.length;
8273
+ if(n<8)return null;
8274
+ let mean=0;
8275
+ for(const v of values)mean+=v;
8276
+ mean/=n;
8277
+ let m2=0;
8278
+ let m3=0;
8279
+ let m4=0;
8280
+ for(const v of values){
8281
+ const d=v-mean;
8282
+ m2+=d*d;
8283
+ m3+=d*d*d;
8284
+ m4+=d*d*d*d;
8285
+ }
8286
+ m2/=n;
8287
+ m3/=n;
8288
+ m4/=n;
8289
+ if(m2===0)return null;
8290
+ const skew=m3/m2**1.5;
8291
+ const excess=m4/(m2*m2)-3;
8292
+ return(n/6)*(skew*skew+(excess*excess)/4);
8293
+ }
8294
+ function weightedQuantile(values,weights,p){
8295
+ const paired=[];
8296
+ let total=0;
8297
+ for(let i=0;i<values.length;i++){
8298
+ const v=Number(values[i]);
8299
+ const w=Number(weights[i]);
8300
+ if(!Number.isFinite(v)||!Number.isFinite(w)||w<=0)continue;
8301
+ paired.push([v,w]);
8302
+ total+=w;
8303
+ }
8304
+ if(!paired.length||total<=0)return null;
8305
+ paired.sort((a,b)=>a[0]-b[0]);
8306
+ if(paired.length===1)return paired[0][0];
8307
+ const at=[];
8308
+ let seen=0;
8309
+ for(const[,w]of paired){
8310
+ at.push((seen+w/2)/total);
8311
+ seen+=w;
8312
+ }
8313
+ const target=Math.max(0,Math.min(1,p));
8314
+ if(target<=at[0])return paired[0][0];
8315
+ if(target>=at[at.length-1])return paired[paired.length-1][0];
8316
+ for(let i=1;i<at.length;i++){
8317
+ if(target>at[i])continue;
8318
+ const span=at[i]-at[i-1];
8319
+ const within=span>0?(target-at[i-1])/span:0;
8320
+ return paired[i-1][0]+(paired[i][0]-paired[i-1][0])*within;
8321
+ }
8322
+ return paired[paired.length-1][0];
8323
+ }
8324
+ function pairs(a,b,indices){
8325
+ const readA=valueReader(a);
8326
+ const readB=valueReader(b);
8327
+ const xs=new Float64Array(indices.length);
8328
+ const ys=new Float64Array(indices.length);
8329
+ let n=0;
8330
+ for(let i=0;i<indices.length;i++){
8331
+ const row=indices[i];
8332
+ const x=Number(readA(row));
8333
+ const y=Number(readB(row));
8334
+ if(!Number.isFinite(x)||!Number.isFinite(y))continue;
8335
+ xs[n]=x;
8336
+ ys[n]=y;
8337
+ n++;
8338
+ }
8339
+ return{xs:xs.subarray(0,n),ys:ys.subarray(0,n),n};
8340
+ }
8341
+ function covariance(a,b,indices,population=false){
8342
+ const{xs,ys,n}=pairs(a,b,indices);
8343
+ if(n<2)return null;
8344
+ let mx=0;
8345
+ let my=0;
8346
+ for(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}
8347
+ mx/=n;
8348
+ my/=n;
8349
+ let sum=0;
8350
+ for(let i=0;i<n;i++)sum+=(xs[i]-mx)*(ys[i]-my);
8351
+ return sum/(population?n:n-1);
8352
+ }
8353
+ function regression(a,b,indices){
8354
+ const{xs,ys,n}=pairs(a,b,indices);
8355
+ if(n<2)return null;
8356
+ let mx=0;
8357
+ let my=0;
8358
+ for(let i=0;i<n;i++){mx+=xs[i];my+=ys[i];}
8359
+ mx/=n;
8360
+ my/=n;
8361
+ let sxx=0;
8362
+ let sxy=0;
8363
+ let syy=0;
8364
+ for(let i=0;i<n;i++){
8365
+ const dx=xs[i]-mx;
8366
+ const dy=ys[i]-my;
8367
+ sxx+=dx*dx;
8368
+ sxy+=dx*dy;
8369
+ syy+=dy*dy;
8370
+ }
8371
+ if(sxx===0)return null;
8372
+ const slope=sxy/sxx;
8373
+ const intercept=my-slope*mx;
8374
+ const r2=syy===0?1:Math.max(0,Math.min(1,(sxy*sxy)/(sxx*syy)));
8375
+ const residual=Math.max(0,syy-slope*sxy);
8376
+ const stdError=n>2?Math.sqrt(residual/(n-2)/sxx):0;
8377
+ return{slope,intercept,r2,stdError,n};
8378
+ }
8379
+ function ranksOf(values){
8380
+ const n=values.length;
8381
+ const order=Array.from({length:n},(unused,i)=>i)
8382
+ .sort((i,j)=>values[i]-values[j]);
8383
+ const ranks=new Float64Array(n);
8384
+ let i=0;
8385
+ while(i<n){
8386
+ let j=i;
8387
+ while(j+1<n&&values[order[j+1]]===values[order[i]])j++;
8388
+ const shared=(i+j)/2+1;
8389
+ for(let k=i;k<=j;k++)ranks[order[k]]=shared;
8390
+ i=j+1;
8391
+ }
8392
+ return ranks;
8393
+ }
8394
+ function spearman(a,b,indices){
8395
+ const{xs,ys,n}=pairs(a,b,indices);
8396
+ if(n<2)return null;
8397
+ const rx=ranksOf(xs);
8398
+ const ry=ranksOf(ys);
8399
+ let mx=0;
8400
+ let my=0;
8401
+ for(let i=0;i<n;i++){mx+=rx[i];my+=ry[i];}
8402
+ mx/=n;
8403
+ my/=n;
8404
+ let sxy=0;
8405
+ let sxx=0;
8406
+ let syy=0;
8407
+ for(let i=0;i<n;i++){
8408
+ const dx=rx[i]-mx;
8409
+ const dy=ry[i]-my;
8410
+ sxy+=dx*dy;
8411
+ sxx+=dx*dx;
8412
+ syy+=dy*dy;
8413
+ }
8414
+ if(sxx===0||syy===0)return null;
8415
+ return Math.max(-1,Math.min(1,sxy/Math.sqrt(sxx*syy)));
8416
+ }
8417
+ function kendall(a,b,indices){
8418
+ const{xs,ys,n}=pairs(a,b,indices);
8419
+ if(n<2||n>KENDALL_LIMIT)return null;
8420
+ let concordant=0;
8421
+ let discordant=0;
8422
+ let tiedXOnly=0;
8423
+ let tiedYOnly=0;
8424
+ for(let i=0;i<n;i++){
8425
+ for(let j=i+1;j<n;j++){
8426
+ const dx=Math.sign(xs[i]-xs[j]);
8427
+ const dy=Math.sign(ys[i]-ys[j]);
8428
+ const product=dx*dy;
8429
+ if(product>0)concordant++;
8430
+ else if(product<0)discordant++;
8431
+ else if(dx===0&&dy===0){}
8432
+ else if(dx===0)tiedXOnly++;
8433
+ else tiedYOnly++;
8434
+ }
8435
+ }
8436
+ const orderedByX=concordant+discordant+tiedYOnly;
8437
+ const orderedByY=concordant+discordant+tiedXOnly;
8438
+ if(orderedByX===0||orderedByY===0)return null;
8439
+ return(concordant-discordant)/Math.sqrt(orderedByX*orderedByY);
8440
+ }
8441
+ function seriesStats(ordered,opts={}){
8442
+ const n=ordered.length;
8443
+ if(n<2)return null;
8444
+ const first=ordered[0];
8445
+ const last=ordered[n-1];
8446
+ const returns=[];
8447
+ for(let i=1;i<n;i++){
8448
+ const previous=ordered[i-1];
8449
+ if(previous===0)continue;
8450
+ returns.push((ordered[i]-previous)/Math.abs(previous));
8451
+ }
8452
+ let volatility=null;
8453
+ if(returns.length>1){
8454
+ let mean=0;
8455
+ for(const r of returns)mean+=r;
8456
+ mean/=returns.length;
8457
+ let m2=0;
8458
+ for(const r of returns)m2+=(r-mean)**2;
8459
+ volatility=Math.sqrt(m2/(returns.length-1));
8460
+ }
8461
+ const periods=Number(opts.periodsPerYear)>0?Number(opts.periodsPerYear):null;
8462
+ let peak=ordered[0];
8463
+ let peakAt=0;
8464
+ let worst=0;
8465
+ let worstFrom=0;
8466
+ let worstTo=0;
8467
+ for(let i=1;i<n;i++){
8468
+ if(ordered[i]>peak){peak=ordered[i];peakAt=i;continue;}
8469
+ if(peak<=0)continue;
8470
+ const fall=(peak-ordered[i])/peak;
8471
+ if(fall>worst){worst=fall;worstFrom=peakAt;worstTo=i;}
8472
+ }
8473
+ let autocorrelation=null;
8474
+ if(n>2){
8475
+ let mean=0;
8476
+ for(let i=0;i<n;i++)mean+=ordered[i];
8477
+ mean/=n;
8478
+ let top=0;
8479
+ let bottom=0;
8480
+ for(let i=0;i<n;i++){
8481
+ const d=ordered[i]-mean;
8482
+ bottom+=d*d;
8483
+ if(i>0)top+=d*(ordered[i-1]-mean);
8484
+ }
8485
+ autocorrelation=bottom>0?top/bottom:null;
8486
+ }
8487
+ let up=0;
8488
+ let down=0;
8489
+ for(const r of returns){if(r>0)up++;else if(r<0)down++;}
8490
+ let growth=null;
8491
+ if(first>0&&last>0){
8492
+ const perPeriod=(last/first)**(1/(n-1))-1;
8493
+ growth=periods?(1+perPeriod)**periods-1:perPeriod;
8494
+ }
8495
+ return{
8496
+ n,
8497
+ first,
8498
+ last,
8499
+ change:last-first,
8500
+ changePercent:first===0?null:((last-first)/Math.abs(first))*100,
8501
+ volatility,
8502
+ annualisedVolatility:volatility!==null&&periods?volatility*Math.sqrt(periods):null,
8503
+ growth,
8504
+ maxDrawdown:worst,
8505
+ maxDrawdownFrom:worstFrom,
8506
+ maxDrawdownTo:worstTo,
8507
+ autocorrelation,
8508
+ upDays:up,
8509
+ downDays:down,
8510
+ };
8511
+ }
8512
+ const D2_N2=1.128;
8513
+ function withinSigma(ordered){
8514
+ const n=ordered.length;
8515
+ if(n<2)return null;
8516
+ let total=0;
8517
+ for(let i=1;i<n;i++)total+=Math.abs(ordered[i]-ordered[i-1]);
8518
+ const meanRange=total/(n-1);
8519
+ return{sigma:meanRange/D2_N2,meanRange};
8520
+ }
8521
+ function capability(ordered,spec){
8522
+ const n=ordered.length;
8523
+ if(n<2||!spec)return null;
8524
+ const lower=Number.isFinite(Number(spec.lower))?Number(spec.lower):null;
8525
+ const upper=Number.isFinite(Number(spec.upper))?Number(spec.upper):null;
8526
+ if(lower===null&&upper===null)return null;
8527
+ let mean=0;
8528
+ for(let i=0;i<n;i++)mean+=ordered[i];
8529
+ mean/=n;
8530
+ let m2=0;
8531
+ for(let i=0;i<n;i++)m2+=(ordered[i]-mean)**2;
8532
+ const overall=Math.sqrt(m2/(n-1));
8533
+ const within=withinSigma(ordered);
8534
+ const sigmaWithin=within?within.sigma:null;
8535
+ const indices=(sigma)=>{
8536
+ if(!sigma||sigma<=0)return{index:null,k:null};
8537
+ const both=lower!==null&&upper!==null;
8538
+ const index=both?(upper-lower)/(6*sigma):null;
8539
+ const upperSide=upper!==null?(upper-mean)/(3*sigma):Infinity;
8540
+ const lowerSide=lower!==null?(mean-lower)/(3*sigma):Infinity;
8541
+ return{index,k:Math.min(upperSide,lowerSide)};
8542
+ };
8543
+ const short=indices(sigmaWithin);
8544
+ const long=indices(overall);
8545
+ let outOfSpec=0;
8546
+ for(let i=0;i<n;i++){
8547
+ if(lower!==null&&ordered[i]<lower){outOfSpec++;continue;}
8548
+ if(upper!==null&&ordered[i]>upper)outOfSpec++;
8549
+ }
8550
+ return{
8551
+ n,
8552
+ mean,
8553
+ lower,
8554
+ upper,
8555
+ target:Number.isFinite(Number(spec.target))?Number(spec.target):null,
8556
+ sigmaWithin,
8557
+ sigmaOverall:overall,
8558
+ cp:short.index,
8559
+ cpk:short.k,
8560
+ pp:long.index,
8561
+ ppk:long.k,
8562
+ outOfSpec,
8563
+ defectRate:n?outOfSpec/n:null,
8564
+ };
8565
+ }
8566
+ function controlLimits(ordered){
8567
+ const n=ordered.length;
8568
+ if(n<2)return null;
8569
+ const within=withinSigma(ordered);
8570
+ if(!within||!(within.sigma>0))return null;
8571
+ let centre=0;
8572
+ for(let i=0;i<n;i++)centre+=ordered[i];
8573
+ centre/=n;
8574
+ return{
8575
+ centre,
8576
+ sigma:within.sigma,
8577
+ upper:centre+3*within.sigma,
8578
+ lower:centre-3*within.sigma,
8579
+ };
8580
+ }
8581
+ function controlViolations(ordered,limits){
8582
+ if(!limits||!(limits.sigma>0))return[];
8583
+ const n=ordered.length;
8584
+ const{centre,sigma}=limits;
8585
+ const z=(i)=>(ordered[i]-centre)/sigma;
8586
+ const out=[];
8587
+ for(let i=0;i<n;i++){
8588
+ if(Math.abs(z(i))>3){
8589
+ out.push({index:i,rule:1,description:'beyond three sigma'});
8590
+ }
8591
+ if(i>=2){
8592
+ for(const side of[1,-1]){
8593
+ let hits=0;
8594
+ for(let k=i-2;k<=i;k++)if(z(k)*side>2)hits++;
8595
+ if(hits>=2){
8596
+ out.push({index:i,rule:2,description:'two of three past two sigma'});
8597
+ break;
8598
+ }
8599
+ }
8600
+ }
8601
+ if(i>=4){
8602
+ for(const side of[1,-1]){
8603
+ let hits=0;
8604
+ for(let k=i-4;k<=i;k++)if(z(k)*side>1)hits++;
8605
+ if(hits>=4){
8606
+ out.push({index:i,rule:3,description:'four of five past one sigma'});
8607
+ break;
8608
+ }
8609
+ }
8610
+ }
8611
+ if(i>=7){
8612
+ for(const side of[1,-1]){
8613
+ let all=true;
8614
+ for(let k=i-7;k<=i;k++)if(z(k)*side<=0){all=false;break;}
8615
+ if(all){
8616
+ out.push({index:i,rule:4,description:'eight in a row on one side'});
8617
+ break;
8618
+ }
8619
+ }
8620
+ }
8621
+ }
8622
+ return out;
8623
+ }
7924
8624
  function countOutside(values,low,high){
7925
8625
  let count=0;
7926
8626
  for(let i=0;i<values.length;i++){
@@ -24449,132 +25149,143 @@ const ShadowTracker=__m8["ShadowTracker"];
24449
25149
  const shadowsIn=__m8["shadowsIn"];
24450
25150
  const __m9=__req("packages/core/src/compute/total.js");
24451
25151
  const total=__m9["total"];
24452
- const __m10=__req("packages/core/src/compute/statistics.js");
24453
- const MAINTENANCE=__m10["MAINTENANCE"];
24454
- const statCorrelation=__m10["correlation"];
24455
- const statMoments=__m10["moments"];
24456
- const countOutside=__m10["countOutside"];
24457
- const statHistogram=__m10["histogram"];
24458
- const statNumbers=__m10["numbers"];
24459
- const statQuantileSorted=__m10["quantileSorted"];
24460
- const statWeightedAverage=__m10["weightedAverage"];
24461
- const __m11=__req("packages/core/src/columns/detailcolumn.js");
24462
- const createDetailColumn=__m11["createDetailColumn"];
24463
- const DETAIL_COLUMN_ID=__m11["DETAIL_COLUMN_ID"];
24464
- const __m12=__req("packages/core/src/columns/treecolumn.js");
24465
- const createTreeColumn=__m12["createTreeColumn"];
24466
- const TREE_COLUMN_ID=__m12["TREE_COLUMN_ID"];
24467
- const __m13=__req("packages/core/src/columns/pivotcolumns.js");
24468
- const createPivotColumns=__m13["createPivotColumns"];
24469
- const __m14=__req("packages/core/src/compute/pivot.js");
24470
- const pivotKey=__m14["pivotKey"];
24471
- const DEFAULT_PATH_SEPARATOR=__m14["DEFAULT_PATH_SEPARATOR"];
24472
- const __m15=__req("packages/core/src/columns/value.js");
24473
- const ValuePipeline=__m15["ValuePipeline"];
24474
- const __m16=__req("packages/core/src/store/columnstore.js");
24475
- const ColumnStore=__m16["ColumnStore"];
24476
- const __m17=__req("packages/core/src/store/pool.js");
24477
- const MaskPool=__m17["MaskPool"];
24478
- const __m18=__req("packages/core/src/compute/index.js");
24479
- const compute=__m18;
24480
- const __m19=__req("packages/core/src/source/index.js");
24481
- const createSource=__m19["createSource"];
24482
- const __m20=__req("packages/core/src/source/rows.js");
24483
- const pinnedRow=__m20["pinnedRow"];
24484
- const DEFAULT_ROW_HEIGHT=__m20["DEFAULT_ROW_HEIGHT"];
24485
- const __m21=__req("packages/core/src/model/rowkey.js");
24486
- const createRowKey=__m21["createRowKey"];
24487
- const __m22=__req("packages/core/src/model/rowmodel.js");
24488
- const RowModel=__m22["RowModel"];
24489
- const createRow=__m22["createRow"];
24490
- const __m23=__req("packages/core/src/model/selection.js");
24491
- const SelectionModel=__m23["SelectionModel"];
24492
- const RangeModel=__m23["RangeModel"];
24493
- const summarise=__m23["summarise"];
24494
- const __m24=__req("packages/core/src/model/history.js");
24495
- const HistoryModel=__m24["HistoryModel"];
24496
- const __m25=__req("packages/core/src/model/diff.js");
24497
- const DiffModel=__m25["DiffModel"];
24498
- const readValue=__m25["readValue"];
24499
- const __m26=__req("packages/core/src/model/views.js");
24500
- const ViewStore=__m26["ViewStore"];
24501
- const __m27=__req("packages/core/src/model/highlight.js");
24502
- const HighlightModel=__m27["HighlightModel"];
24503
- const __m28=__req("packages/core/src/model/redaction.js");
24504
- const RedactionModel=__m28["RedactionModel"];
24505
- const __m29=__req("packages/core/src/model/presentation.js");
24506
- const PresentationModel=__m29["PresentationModel"];
24507
- const __m30=__req("packages/core/src/model/timeline.js");
24508
- const Timeline=__m30["Timeline"];
24509
- const __m31=__req("packages/core/src/model/facets.js");
24510
- const FacetModel=__m31["FacetModel"];
24511
- const DEFAULT_DEBOUNCE=__m31["DEFAULT_DEBOUNCE"];
24512
- const DEFAULT_ROW_CEILING=__m31["DEFAULT_ROW_CEILING"];
24513
- const DEFAULT_FACET_HEIGHT=__m31["DEFAULT_FACET_HEIGHT"];
24514
- const __m32=__req("packages/core/src/model/comments.js");
24515
- const CommentModel=__m32["CommentModel"];
24516
- const parseCommentKey=__m32["parseCellKey"];
24517
- const DEFAULT_INDEX_DEBOUNCE=__m32["DEFAULT_INDEX_DEBOUNCE"];
24518
- const DEFAULT_INDEX_LIMIT=__m32["DEFAULT_INDEX_LIMIT"];
24519
- const __m33=__req("packages/core/src/model/diagnostics.js");
24520
- const Diagnostics=__m33["Diagnostics"];
24521
- const WARNING_IDS=__m33["WARNING_IDS"];
24522
- const instrument=__m33["instrument"];
24523
- const instrumentProvider=__m33["instrumentProvider"];
24524
- const __m34=__req("packages/core/src/model/presence.js");
24525
- const PresenceModel=__m34["PresenceModel"];
24526
- const DEFAULT_THROTTLE_MS=__m34["DEFAULT_THROTTLE_MS"];
24527
- const DEFAULT_IDLE_MS=__m34["DEFAULT_IDLE_MS"];
24528
- const DEFAULT_REMOVE_MS=__m34["DEFAULT_REMOVE_MS"];
24529
- const DEFAULT_LOCK_MS=__m34["DEFAULT_LOCK_MS"];
24530
- const __m35=__req("packages/core/src/compute/facet.js");
24531
- const facetKind=__m35["facetKind"];
24532
- const DEFAULT_BUCKETS=__m35["DEFAULT_BUCKETS"];
24533
- const DEFAULT_CARDINALITY_LIMIT=__m35["DEFAULT_CARDINALITY_LIMIT"];
24534
- const __m36=__req("packages/worker/src/host.js");
24535
- const createWorkerHost=__m36["createWorkerHost"];
24536
- const __m37=__req("packages/core/src/i18n/index.js");
24537
- const Messages=__m37["Messages"];
24538
- const MESSAGE_KEYS=__m37["MESSAGE_KEYS"];
24539
- const __m38=__req("packages/core/src/model/pending.js");
24540
- const PendingWrites=__m38["PendingWrites"];
24541
- const __m39=__req("packages/core/src/registry/licence.js");
24542
- const setSharedLicence=__m39["setLicence"];
24543
- const licenceInfo=__m39["licenceInfo"];
24544
- const licenceWatermark=__m39["watermark"];
24545
- const licenceState=__m39["licenceState"];
24546
- const sharedLicence=__m39["sharedLicence"];
24547
- const __m40=__req("packages/core/src/columns/permissions.js");
24548
- const PermissionModel=__m40["PermissionModel"];
24549
- const __m41=__req("packages/core/src/ai/schema.js");
24550
- const describeGrid=__m41["describeGrid"];
24551
- const promptText=__m41["promptText"];
24552
- const toolDefinition=__m41["toolDefinition"];
24553
- const __m42=__req("packages/core/src/ai/intent.js");
24554
- const planIntent=__m42["planIntent"];
24555
- const applyPlan=__m42["applyPlan"];
24556
- const buildPrompt=__m42["buildPrompt"];
24557
- const __m43=__req("packages/core/src/model/edit.js");
24558
- const EditModel=__m43["EditModel"];
24559
- const __m44=__req("packages/core/src/model/changes.js");
24560
- const ChangeModel=__m44["ChangeModel"];
24561
- const __m45=__req("packages/core/src/model/state.js");
24562
- const StateModel=__m45["StateModel"];
24563
- const __m46=__req("packages/core/src/formatting/model.js");
24564
- const FormattingModel=__m46["FormattingModel"];
24565
- const GRID_SCOPE=__m46["GRID_SCOPE"];
24566
- const __m47=__req("packages/core/src/formatting/rules.js");
24567
- const summariseColumn=__m47["summariseColumn"];
24568
- const __m48=__req("packages/core/src/export/index.js");
24569
- const exportCsv=__m48["exportCsv"];
24570
- const exportExcel=__m48["exportExcel"];
24571
- const copyToClipboard=__m48["copyToClipboard"];
24572
- const writeClipboardText=__m48["writeClipboardText"];
24573
- const printGrid=__m48["printGrid"];
24574
- const buildClipboardText=__m48["buildClipboardText"];
24575
- const pasteIntoRange=__m48["pasteIntoRange"];
24576
- const writeHookFor=__m48["writeHookFor"];
24577
- const parseClipboardText=__m48["parseClipboardText"];
25152
+ const __m10=__req("packages/core/src/compute/handle.js");
25153
+ const statValueReader=__m10["valueReader"];
25154
+ const __m11=__req("packages/core/src/compute/statistics.js");
25155
+ const MAINTENANCE=__m11["MAINTENANCE"];
25156
+ const statCorrelation=__m11["correlation"];
25157
+ const statMoments=__m11["moments"];
25158
+ const countOutside=__m11["countOutside"];
25159
+ const statCapability=__m11["capability"];
25160
+ const statControlLimits=__m11["controlLimits"];
25161
+ const statControlViolations=__m11["controlViolations"];
25162
+ const statCovariance=__m11["covariance"];
25163
+ const statHistogram=__m11["histogram"];
25164
+ const statKendall=__m11["kendall"];
25165
+ const statRegression=__m11["regression"];
25166
+ const statSeries=__m11["seriesStats"];
25167
+ const statSpearman=__m11["spearman"];
25168
+ const statWeightedQuantile=__m11["weightedQuantile"];
25169
+ const statNumbers=__m11["numbers"];
25170
+ const statQuantileSorted=__m11["quantileSorted"];
25171
+ const statWeightedAverage=__m11["weightedAverage"];
25172
+ const __m12=__req("packages/core/src/columns/detailcolumn.js");
25173
+ const createDetailColumn=__m12["createDetailColumn"];
25174
+ const DETAIL_COLUMN_ID=__m12["DETAIL_COLUMN_ID"];
25175
+ const __m13=__req("packages/core/src/columns/treecolumn.js");
25176
+ const createTreeColumn=__m13["createTreeColumn"];
25177
+ const TREE_COLUMN_ID=__m13["TREE_COLUMN_ID"];
25178
+ const __m14=__req("packages/core/src/columns/pivotcolumns.js");
25179
+ const createPivotColumns=__m14["createPivotColumns"];
25180
+ const __m15=__req("packages/core/src/compute/pivot.js");
25181
+ const pivotKey=__m15["pivotKey"];
25182
+ const DEFAULT_PATH_SEPARATOR=__m15["DEFAULT_PATH_SEPARATOR"];
25183
+ const __m16=__req("packages/core/src/columns/value.js");
25184
+ const ValuePipeline=__m16["ValuePipeline"];
25185
+ const __m17=__req("packages/core/src/store/columnstore.js");
25186
+ const ColumnStore=__m17["ColumnStore"];
25187
+ const __m18=__req("packages/core/src/store/pool.js");
25188
+ const MaskPool=__m18["MaskPool"];
25189
+ const __m19=__req("packages/core/src/compute/index.js");
25190
+ const compute=__m19;
25191
+ const __m20=__req("packages/core/src/source/index.js");
25192
+ const createSource=__m20["createSource"];
25193
+ const __m21=__req("packages/core/src/source/rows.js");
25194
+ const pinnedRow=__m21["pinnedRow"];
25195
+ const DEFAULT_ROW_HEIGHT=__m21["DEFAULT_ROW_HEIGHT"];
25196
+ const __m22=__req("packages/core/src/model/rowkey.js");
25197
+ const createRowKey=__m22["createRowKey"];
25198
+ const __m23=__req("packages/core/src/model/rowmodel.js");
25199
+ const RowModel=__m23["RowModel"];
25200
+ const createRow=__m23["createRow"];
25201
+ const __m24=__req("packages/core/src/model/selection.js");
25202
+ const SelectionModel=__m24["SelectionModel"];
25203
+ const RangeModel=__m24["RangeModel"];
25204
+ const summarise=__m24["summarise"];
25205
+ const __m25=__req("packages/core/src/model/history.js");
25206
+ const HistoryModel=__m25["HistoryModel"];
25207
+ const __m26=__req("packages/core/src/model/diff.js");
25208
+ const DiffModel=__m26["DiffModel"];
25209
+ const readValue=__m26["readValue"];
25210
+ const __m27=__req("packages/core/src/model/views.js");
25211
+ const ViewStore=__m27["ViewStore"];
25212
+ const __m28=__req("packages/core/src/model/highlight.js");
25213
+ const HighlightModel=__m28["HighlightModel"];
25214
+ const __m29=__req("packages/core/src/model/redaction.js");
25215
+ const RedactionModel=__m29["RedactionModel"];
25216
+ const __m30=__req("packages/core/src/model/presentation.js");
25217
+ const PresentationModel=__m30["PresentationModel"];
25218
+ const __m31=__req("packages/core/src/model/timeline.js");
25219
+ const Timeline=__m31["Timeline"];
25220
+ const __m32=__req("packages/core/src/model/facets.js");
25221
+ const FacetModel=__m32["FacetModel"];
25222
+ const DEFAULT_DEBOUNCE=__m32["DEFAULT_DEBOUNCE"];
25223
+ const DEFAULT_ROW_CEILING=__m32["DEFAULT_ROW_CEILING"];
25224
+ const DEFAULT_FACET_HEIGHT=__m32["DEFAULT_FACET_HEIGHT"];
25225
+ const __m33=__req("packages/core/src/model/comments.js");
25226
+ const CommentModel=__m33["CommentModel"];
25227
+ const parseCommentKey=__m33["parseCellKey"];
25228
+ const DEFAULT_INDEX_DEBOUNCE=__m33["DEFAULT_INDEX_DEBOUNCE"];
25229
+ const DEFAULT_INDEX_LIMIT=__m33["DEFAULT_INDEX_LIMIT"];
25230
+ const __m34=__req("packages/core/src/model/diagnostics.js");
25231
+ const Diagnostics=__m34["Diagnostics"];
25232
+ const WARNING_IDS=__m34["WARNING_IDS"];
25233
+ const instrument=__m34["instrument"];
25234
+ const instrumentProvider=__m34["instrumentProvider"];
25235
+ const __m35=__req("packages/core/src/model/presence.js");
25236
+ const PresenceModel=__m35["PresenceModel"];
25237
+ const DEFAULT_THROTTLE_MS=__m35["DEFAULT_THROTTLE_MS"];
25238
+ const DEFAULT_IDLE_MS=__m35["DEFAULT_IDLE_MS"];
25239
+ const DEFAULT_REMOVE_MS=__m35["DEFAULT_REMOVE_MS"];
25240
+ const DEFAULT_LOCK_MS=__m35["DEFAULT_LOCK_MS"];
25241
+ const __m36=__req("packages/core/src/compute/facet.js");
25242
+ const facetKind=__m36["facetKind"];
25243
+ const DEFAULT_BUCKETS=__m36["DEFAULT_BUCKETS"];
25244
+ const DEFAULT_CARDINALITY_LIMIT=__m36["DEFAULT_CARDINALITY_LIMIT"];
25245
+ const __m37=__req("packages/worker/src/host.js");
25246
+ const createWorkerHost=__m37["createWorkerHost"];
25247
+ const __m38=__req("packages/core/src/i18n/index.js");
25248
+ const Messages=__m38["Messages"];
25249
+ const MESSAGE_KEYS=__m38["MESSAGE_KEYS"];
25250
+ const __m39=__req("packages/core/src/model/pending.js");
25251
+ const PendingWrites=__m39["PendingWrites"];
25252
+ const __m40=__req("packages/core/src/registry/licence.js");
25253
+ const setSharedLicence=__m40["setLicence"];
25254
+ const licenceInfo=__m40["licenceInfo"];
25255
+ const licenceWatermark=__m40["watermark"];
25256
+ const licenceState=__m40["licenceState"];
25257
+ const sharedLicence=__m40["sharedLicence"];
25258
+ const __m41=__req("packages/core/src/columns/permissions.js");
25259
+ const PermissionModel=__m41["PermissionModel"];
25260
+ const __m42=__req("packages/core/src/ai/schema.js");
25261
+ const describeGrid=__m42["describeGrid"];
25262
+ const promptText=__m42["promptText"];
25263
+ const toolDefinition=__m42["toolDefinition"];
25264
+ const __m43=__req("packages/core/src/ai/intent.js");
25265
+ const planIntent=__m43["planIntent"];
25266
+ const applyPlan=__m43["applyPlan"];
25267
+ const buildPrompt=__m43["buildPrompt"];
25268
+ const __m44=__req("packages/core/src/model/edit.js");
25269
+ const EditModel=__m44["EditModel"];
25270
+ const __m45=__req("packages/core/src/model/changes.js");
25271
+ const ChangeModel=__m45["ChangeModel"];
25272
+ const __m46=__req("packages/core/src/model/state.js");
25273
+ const StateModel=__m46["StateModel"];
25274
+ const __m47=__req("packages/core/src/formatting/model.js");
25275
+ const FormattingModel=__m47["FormattingModel"];
25276
+ const GRID_SCOPE=__m47["GRID_SCOPE"];
25277
+ const __m48=__req("packages/core/src/formatting/rules.js");
25278
+ const summariseColumn=__m48["summariseColumn"];
25279
+ const __m49=__req("packages/core/src/export/index.js");
25280
+ const exportCsv=__m49["exportCsv"];
25281
+ const exportExcel=__m49["exportExcel"];
25282
+ const copyToClipboard=__m49["copyToClipboard"];
25283
+ const writeClipboardText=__m49["writeClipboardText"];
25284
+ const printGrid=__m49["printGrid"];
25285
+ const buildClipboardText=__m49["buildClipboardText"];
25286
+ const pasteIntoRange=__m49["pasteIntoRange"];
25287
+ const writeHookFor=__m49["writeHookFor"];
25288
+ const parseClipboardText=__m49["parseClipboardText"];
24578
25289
  const QUICK_MODES=['contains','words','fuzzy','regex'];
24579
25290
  function canonicalise(column,value){
24580
25291
  const lookup=column&&column.lookup;
@@ -24718,6 +25429,8 @@ pageSize:0,
24718
25429
  #renderer=null;
24719
25430
  #destroyed=false;
24720
25431
  #shadows=new Map();
25432
+ #running=new Map();
25433
+ #filteredKeyCache=null;
24721
25434
  #ready=false;
24722
25435
  #teardown=new Set();
24723
25436
  constructor(config={}){
@@ -25526,6 +26239,75 @@ return this.#store?this.#store.column(colId):undefined;
25526
26239
  const handle=this.#handleFor(colId);
25527
26240
  return handle?statNumbers(handle,this.#statIndices()):new Float64Array(0);
25528
26241
  }
26242
+ #filteredKeys(){
26243
+ const indices=this.#statIndices();
26244
+ if(this.#filteredKeyCache&&this.#filteredKeyCache.indices===indices){
26245
+ return this.#filteredKeyCache.keys;
26246
+ }
26247
+ const keys=new Set();
26248
+ const all=isFunction(this.#source.rows)?this.#source.rows():null;
26249
+ for(let i=0;i<indices.length;i++){
26250
+ const data=all?all[indices[i]]:null;
26251
+ const key=data==null?null:this.#rowKey(data);
26252
+ if(key!==null&&key!==undefined)keys.add(String(key));
26253
+ }
26254
+ this.#filteredKeyCache={indices,keys};
26255
+ return keys;
26256
+ }
26257
+ #runningValues(colId,kind){
26258
+ const rows=this.#displayRows();
26259
+ const cached=this.#running.get(colId);
26260
+ if(cached&&cached.rows===rows&&cached.kind===kind)return cached.values;
26261
+ const values=new Map();
26262
+ let total=0;
26263
+ let grand=0;
26264
+ if(kind==='percent'){
26265
+ for(const row of rows){
26266
+ if(!row||row.kind)continue;
26267
+ const v=Number(this.#values.value(this.#columns.get(colId),row.data,row));
26268
+ if(Number.isFinite(v))grand+=v;
26269
+ }
26270
+ }
26271
+ for(const row of rows){
26272
+ if(!row||row.kind)continue;
26273
+ const v=Number(this.#values.value(this.#columns.get(colId),row.data,row));
26274
+ if(Number.isFinite(v))total+=v;
26275
+ const key=row.key===undefined||row.key===null?null:String(row.key);
26276
+ if(!key)continue;
26277
+ values.set(key,kind==='percent'?(grand?(total/grand)*100:null):total);
26278
+ }
26279
+ this.#running.set(colId,{rows,kind,values});
26280
+ return values;
26281
+ }
26282
+ #orderedValues(colId,by){
26283
+ const values=this.#handleFor(colId);
26284
+ if(!values)return null;
26285
+ const indices=this.#statIndices();
26286
+ const readValue=statValueReader(values);
26287
+ if(!by){
26288
+ const out=[];
26289
+ for(let i=0;i<indices.length;i++){
26290
+ const v=Number(readValue(indices[i]));
26291
+ if(Number.isFinite(v))out.push(v);
26292
+ }
26293
+ return out;
26294
+ }
26295
+ const order=this.#handleFor(by);
26296
+ if(!order)return null;
26297
+ const readOrder=statValueReader(order);
26298
+ const rows=[];
26299
+ for(let i=0;i<indices.length;i++){
26300
+ const row=indices[i];
26301
+ const v=Number(readValue(row));
26302
+ const raw=readOrder(row);
26303
+ const at=raw instanceof Date?raw.getTime()
26304
+ :(typeof raw==='number'?raw:Date.parse(String(raw)));
26305
+ if(!Number.isFinite(v)||!Number.isFinite(at))continue;
26306
+ rows.push([at,v]);
26307
+ }
26308
+ rows.sort((x,y)=>x[0]-y[0]);
26309
+ return rows.map((r)=>r[1]);
26310
+ }
25529
26311
  #statIndices(){
25530
26312
  const source=this.#source;
25531
26313
  if(isFunction(source.filteredIndices))return source.filteredIndices();
@@ -26527,6 +27309,36 @@ return summarise(grid.#ranges.cells((i)=>grid.rows.get(i)).map(
26527
27309
  ({key,colId})=>grid.rows.value(key,colId),
26528
27310
  ));
26529
27311
  },
27312
+ statistics(){
27313
+ const cells=grid.#ranges.cells((i)=>grid.rows.get(i));
27314
+ if(!cells.length)return null;
27315
+ const raw=cells.map(({key,colId})=>grid.rows.value(key,colId));
27316
+ const base=summarise(raw);
27317
+ const numbers=[];
27318
+ const seen=new Set();
27319
+ for(const v of raw){
27320
+ if(v===null||v===undefined||v==='')continue;
27321
+ seen.add(typeof v==='object'?String(v):v);
27322
+ const n=typeof v==='number'?v:Number(v);
27323
+ if(Number.isFinite(n))numbers.push(n);
27324
+ }
27325
+ if(!numbers.length)return{...base,cells:cells.length,distinct:seen.size};
27326
+ const sorted=numbers.slice().sort((a,b)=>a-b);
27327
+ const{n,mean,m2}=statMoments(Float64Array.from(sorted));
27328
+ const q1=statQuantileSorted(sorted,0.25);
27329
+ const q3=statQuantileSorted(sorted,0.75);
27330
+ return{
27331
+ ...base,
27332
+ cells:cells.length,
27333
+ distinct:seen.size,
27334
+ median:statQuantileSorted(sorted,0.5),
27335
+ q1,
27336
+ q3,
27337
+ iqr:q3-q1,
27338
+ stddev:n>1?Math.sqrt(m2/(n-1)):null,
27339
+ outliers:countOutside(Float64Array.from(sorted),q1-1.5*(q3-q1),q3+1.5*(q3-q1)),
27340
+ };
27341
+ },
26530
27342
  };
26531
27343
  }
26532
27344
  get filters(){
@@ -27352,9 +28164,9 @@ get active(){return grid.#redaction.active;},
27352
28164
  get statistics(){
27353
28165
  const grid=this;
27354
28166
  return{
27355
- shadow(colId,kind,rowKey){
28167
+ shadow(colId,kind,rowKey,scope){
27356
28168
  const tracker=grid.#shadows.get(colId);
27357
- return tracker?tracker.read(kind,rowKey):null;
28169
+ return tracker?tracker.read(kind,rowKey,scope==='filtered'?grid.#filteredKeys():undefined):null;
27358
28170
  },
27359
28171
  rebase(colId){
27360
28172
  if(colId){
@@ -27412,6 +28224,79 @@ const second=grid.#handleFor(b);
27412
28224
  if(!first||!second)return null;
27413
28225
  return statCorrelation(first,second,grid.#statIndices());
27414
28226
  },
28227
+ covariance(a,b,opts={}){
28228
+ const first=grid.#handleFor(a);
28229
+ const second=grid.#handleFor(b);
28230
+ if(!first||!second)return null;
28231
+ return statCovariance(first,second,grid.#statIndices(),opts.population===true);
28232
+ },
28233
+ regression(a,b){
28234
+ const first=grid.#handleFor(a);
28235
+ const second=grid.#handleFor(b);
28236
+ if(!first||!second)return null;
28237
+ return statRegression(first,second,grid.#statIndices());
28238
+ },
28239
+ spearman(a,b){
28240
+ const first=grid.#handleFor(a);
28241
+ const second=grid.#handleFor(b);
28242
+ if(!first||!second)return null;
28243
+ return statSpearman(first,second,grid.#statIndices());
28244
+ },
28245
+ kendall(a,b){
28246
+ const first=grid.#handleFor(a);
28247
+ const second=grid.#handleFor(b);
28248
+ if(!first||!second)return null;
28249
+ return statKendall(first,second,grid.#statIndices());
28250
+ },
28251
+ weightedQuantile(colId,weightId,p=0.5){
28252
+ const values=grid.#handleFor(colId);
28253
+ const weights=grid.#handleFor(weightId);
28254
+ if(!values||!weights)return null;
28255
+ const indices=grid.#statIndices();
28256
+ const readV=statValueReader(values);
28257
+ const readW=statValueReader(weights);
28258
+ const vs=[];
28259
+ const ws=[];
28260
+ for(let i=0;i<indices.length;i++){
28261
+ vs.push(Number(readV(indices[i])));
28262
+ ws.push(Number(readW(indices[i])));
28263
+ }
28264
+ return statWeightedQuantile(vs,ws,p);
28265
+ },
28266
+ running(colId,kind,rowKey){
28267
+ const values=grid.#runningValues(colId,kind);
28268
+ return values&&values.has(rowKey)?values.get(rowKey):null;
28269
+ },
28270
+ capability(colId,opts={}){
28271
+ const handle=grid.#handleFor(colId);
28272
+ if(!handle)return null;
28273
+ const column=grid.#columns.get(colId);
28274
+ const declared=(column&&column.spec)||{};
28275
+ const spec={
28276
+ lower:opts.lower===undefined?declared.lower:opts.lower,
28277
+ upper:opts.upper===undefined?declared.upper:opts.upper,
28278
+ target:opts.target===undefined?declared.target:opts.target,
28279
+ };
28280
+ const ordered=grid.#orderedValues(colId,opts.by);
28281
+ if(!ordered)return null;
28282
+ const result=statCapability(ordered,spec);
28283
+ if(!result)return null;
28284
+ const from=Number(opts.baseline)>1
28285
+ ?ordered.slice(0,Math.min(ordered.length,Math.floor(Number(opts.baseline))))
28286
+ :ordered;
28287
+ const limits=statControlLimits(from);
28288
+ return{
28289
+ ...result,
28290
+ limits,
28291
+ baseline:from.length,
28292
+ violations:limits?statControlViolations(ordered,limits):[],
28293
+ };
28294
+ },
28295
+ series(colId,opts){
28296
+ if(!opts||!opts.by)return null;
28297
+ const ordered=grid.#orderedValues(colId,opts.by);
28298
+ return ordered?statSeries(ordered,opts):null;
28299
+ },
27415
28300
  weightedAverage(colId,weightId){
27416
28301
  const values=grid.#handleFor(colId);
27417
28302
  const weights=grid.#handleFor(weightId);
@@ -27899,6 +28784,62 @@ other:'{count} cellules mises à jour',
27899
28784
  'panel.quickFilter':'Filtre rapide',
27900
28785
  'panel.formatting':'Mise en forme',
27901
28786
  'panel.statistics':'Statistiques',
28787
+ 'panel.compare':'Comparer',
28788
+ 'compare.first':'Première colonne',
28789
+ 'compare.second':'Deuxième colonne',
28790
+ 'compare.needTwo':'Deux colonnes numériques sont nécessaires',
28791
+ 'compare.noPairs':'Aucune ligne n’a de valeur dans les deux',
28792
+ 'compare.pairs':'{count} paires',
28793
+ 'compare.pearson':'Corrélation (Pearson)',
28794
+ 'compare.spearman':'Corrélation des rangs (Spearman)',
28795
+ 'compare.kendall':'Tau de Kendall',
28796
+ 'compare.covariance':'Covariance',
28797
+ 'compare.slope':'Pente',
28798
+ 'compare.intercept':'Ordonnée à l’origine',
28799
+ 'compare.r2':'R²',
28800
+ 'compare.stdError':'Erreur type',
28801
+ 'compare.weighted':'Moyenne pondérée',
28802
+ 'total.sum':'Somme',
28803
+ 'total.avg':'Moyenne',
28804
+ 'total.min':'Min',
28805
+ 'total.max':'Max',
28806
+ 'total.count':'Nombre',
28807
+ 'total.countValues':'Nombre de valeurs',
28808
+ 'total.first':'Premier',
28809
+ 'total.last':'Dernier',
28810
+ 'total.median':'Médiane',
28811
+ 'total.p25':'25e centile',
28812
+ 'total.p75':'75e centile',
28813
+ 'total.p90':'90e centile',
28814
+ 'total.p95':'95e centile',
28815
+ 'total.p99':'99e centile',
28816
+ 'total.iqr':'Écart interquartile',
28817
+ 'total.mad':'Écart absolu médian',
28818
+ 'total.variance':'Variance',
28819
+ 'total.varianceP':'Variance (population)',
28820
+ 'total.stddev':'Écart type',
28821
+ 'total.stddevP':'Écart type (population)',
28822
+ 'total.range':'Étendue',
28823
+ 'total.distinct':'Valeurs distinctes',
28824
+ 'total.mode':'Mode',
28825
+ 'total.skewness':'Asymétrie',
28826
+ 'total.kurtosis':'Aplatissement',
28827
+ 'total.geomean':'Moyenne géométrique',
28828
+ 'total.harmean':'Moyenne harmonique',
28829
+ 'total.sumSquares':'Somme des carrés',
28830
+ 'total.weightedAvg':'Moyenne pondérée',
28831
+ 'total.argmin':'Plus bas selon',
28832
+ 'total.argmax':'Plus haut selon',
28833
+ 'total.hhi':'Concentration (IHH)',
28834
+ 'total.entropy':'Entropie',
28835
+ 'total.evenness':'Régularité',
28836
+ 'total.top3Share':'Part des 3 premiers',
28837
+ 'total.top10Share':'Part des 10 premiers',
28838
+ 'total.gini':'Coefficient de Gini',
28839
+ 'total.trimmedMean':'Moyenne tronquée',
28840
+ 'total.winsorizedMean':'Moyenne winsorisée',
28841
+ 'total.robustOutliers':'Valeurs aberrantes (robuste)',
28842
+ 'total.jarqueBera':'Jarque–Bera',
27902
28843
  'stats.column':'Colonne',
27903
28844
  'stats.choose':'Choisissez une colonne à analyser',
27904
28845
  'stats.noColumns':'Aucune colonne numérique à analyser',
@@ -27918,6 +28859,15 @@ other:'{count} cellules mises à jour',
27918
28859
  'stats.outliers':'Valeurs aberrantes',
27919
28860
  'stats.distribution':'Distribution',
27920
28861
  'stats.bin':'{count} entre {from} et {to}',
28862
+ 'stats.section.shape':'Forme',
28863
+ 'stats.section.robust':'Robuste',
28864
+ 'stats.section.concentration':'Concentration',
28865
+ 'stats.section.capability':'Capabilité',
28866
+ 'stats.cp':'Cp',
28867
+ 'stats.cpk':'Cpk',
28868
+ 'stats.pp':'Pp',
28869
+ 'stats.ppk':'Ppk',
28870
+ 'stats.outOfSpec':'Hors spécification',
27921
28871
  'stats.filtered':'Sur {count} lignes filtrées',
27922
28872
  'panel.zone.group':'les regroupements de lignes',
27923
28873
  'panel.zone.values':'les valeurs',
@@ -28310,6 +29260,62 @@ other:'{count} celle aggiornate',
28310
29260
  'panel.quickFilter':'Filtro rapido',
28311
29261
  'panel.formatting':'Formattazione',
28312
29262
  'panel.statistics':'Statistiche',
29263
+ 'panel.compare':'Confronta',
29264
+ 'compare.first':'Prima colonna',
29265
+ 'compare.second':'Seconda colonna',
29266
+ 'compare.needTwo':'Servono due colonne numeriche',
29267
+ 'compare.noPairs':'Nessuna riga ha un valore in entrambe',
29268
+ 'compare.pairs':'{count} coppie',
29269
+ 'compare.pearson':'Correlazione (Pearson)',
29270
+ 'compare.spearman':'Correlazione per ranghi (Spearman)',
29271
+ 'compare.kendall':'Tau di Kendall',
29272
+ 'compare.covariance':'Covarianza',
29273
+ 'compare.slope':'Pendenza',
29274
+ 'compare.intercept':'Intercetta',
29275
+ 'compare.r2':'R²',
29276
+ 'compare.stdError':'Errore standard',
29277
+ 'compare.weighted':'Media ponderata',
29278
+ 'total.sum':'Somma',
29279
+ 'total.avg':'Media',
29280
+ 'total.min':'Min',
29281
+ 'total.max':'Max',
29282
+ 'total.count':'Conteggio',
29283
+ 'total.countValues':'Conteggio valori',
29284
+ 'total.first':'Primo',
29285
+ 'total.last':'Ultimo',
29286
+ 'total.median':'Mediana',
29287
+ 'total.p25':'25° percentile',
29288
+ 'total.p75':'75° percentile',
29289
+ 'total.p90':'90° percentile',
29290
+ 'total.p95':'95° percentile',
29291
+ 'total.p99':'99° percentile',
29292
+ 'total.iqr':'Scarto interquartile',
29293
+ 'total.mad':'Deviazione assoluta mediana',
29294
+ 'total.variance':'Varianza',
29295
+ 'total.varianceP':'Varianza (popolazione)',
29296
+ 'total.stddev':'Deviazione standard',
29297
+ 'total.stddevP':'Deviazione standard (popolazione)',
29298
+ 'total.range':'Intervallo',
29299
+ 'total.distinct':'Distinti',
29300
+ 'total.mode':'Moda',
29301
+ 'total.skewness':'Asimmetria',
29302
+ 'total.kurtosis':'Curtosi',
29303
+ 'total.geomean':'Media geometrica',
29304
+ 'total.harmean':'Media armonica',
29305
+ 'total.sumSquares':'Somma dei quadrati',
29306
+ 'total.weightedAvg':'Media ponderata',
29307
+ 'total.argmin':'Più basso per',
29308
+ 'total.argmax':'Più alto per',
29309
+ 'total.hhi':'Concentrazione (HHI)',
29310
+ 'total.entropy':'Entropia',
29311
+ 'total.evenness':'Uniformità',
29312
+ 'total.top3Share':'Quota primi 3',
29313
+ 'total.top10Share':'Quota primi 10',
29314
+ 'total.gini':'Coefficiente di Gini',
29315
+ 'total.trimmedMean':'Media troncata',
29316
+ 'total.winsorizedMean':'Media winsorizzata',
29317
+ 'total.robustOutliers':'Valori anomali (robusto)',
29318
+ 'total.jarqueBera':'Jarque–Bera',
28313
29319
  'stats.column':'Colonna',
28314
29320
  'stats.choose':'Scegli una colonna da analizzare',
28315
29321
  'stats.noColumns':'Nessuna colonna numerica da analizzare',
@@ -28329,6 +29335,15 @@ other:'{count} celle aggiornate',
28329
29335
  'stats.outliers':'Valori anomali',
28330
29336
  'stats.distribution':'Distribuzione',
28331
29337
  'stats.bin':'{count} tra {from} e {to}',
29338
+ 'stats.section.shape':'Forma',
29339
+ 'stats.section.robust':'Robusto',
29340
+ 'stats.section.concentration':'Concentrazione',
29341
+ 'stats.section.capability':'Capacità',
29342
+ 'stats.cp':'Cp',
29343
+ 'stats.cpk':'Cpk',
29344
+ 'stats.pp':'Pp',
29345
+ 'stats.ppk':'Ppk',
29346
+ 'stats.outOfSpec':'Fuori specifica',
28332
29347
  'stats.filtered':'Su {count} righe filtrate',
28333
29348
  'panel.zone.group':'i raggruppamenti di righe',
28334
29349
  'panel.zone.values':'i valori',
@@ -28706,6 +29721,62 @@ other:'{count} celdas actualizadas',
28706
29721
  'panel.quickFilter':'Filtro rápido',
28707
29722
  'panel.formatting':'Formato',
28708
29723
  'panel.statistics':'Estadísticas',
29724
+ 'panel.compare':'Comparar',
29725
+ 'compare.first':'Primera columna',
29726
+ 'compare.second':'Segunda columna',
29727
+ 'compare.needTwo':'Se necesitan dos columnas numéricas',
29728
+ 'compare.noPairs':'Ninguna fila tiene valor en ambas',
29729
+ 'compare.pairs':'{count} pares',
29730
+ 'compare.pearson':'Correlación (Pearson)',
29731
+ 'compare.spearman':'Correlación de rangos (Spearman)',
29732
+ 'compare.kendall':'Tau de Kendall',
29733
+ 'compare.covariance':'Covarianza',
29734
+ 'compare.slope':'Pendiente',
29735
+ 'compare.intercept':'Intersección',
29736
+ 'compare.r2':'R²',
29737
+ 'compare.stdError':'Error típico',
29738
+ 'compare.weighted':'Media ponderada',
29739
+ 'total.sum':'Suma',
29740
+ 'total.avg':'Promedio',
29741
+ 'total.min':'Mín',
29742
+ 'total.max':'Máx',
29743
+ 'total.count':'Recuento',
29744
+ 'total.countValues':'Recuento de valores',
29745
+ 'total.first':'Primero',
29746
+ 'total.last':'Último',
29747
+ 'total.median':'Mediana',
29748
+ 'total.p25':'Percentil 25',
29749
+ 'total.p75':'Percentil 75',
29750
+ 'total.p90':'Percentil 90',
29751
+ 'total.p95':'Percentil 95',
29752
+ 'total.p99':'Percentil 99',
29753
+ 'total.iqr':'Rango intercuartílico',
29754
+ 'total.mad':'Desviación absoluta mediana',
29755
+ 'total.variance':'Varianza',
29756
+ 'total.varianceP':'Varianza (población)',
29757
+ 'total.stddev':'Desviación típica',
29758
+ 'total.stddevP':'Desviación típica (población)',
29759
+ 'total.range':'Rango',
29760
+ 'total.distinct':'Distintos',
29761
+ 'total.mode':'Moda',
29762
+ 'total.skewness':'Asimetría',
29763
+ 'total.kurtosis':'Curtosis',
29764
+ 'total.geomean':'Media geométrica',
29765
+ 'total.harmean':'Media armónica',
29766
+ 'total.sumSquares':'Suma de cuadrados',
29767
+ 'total.weightedAvg':'Media ponderada',
29768
+ 'total.argmin':'Menor por',
29769
+ 'total.argmax':'Mayor por',
29770
+ 'total.hhi':'Concentración (HHI)',
29771
+ 'total.entropy':'Entropía',
29772
+ 'total.evenness':'Uniformidad',
29773
+ 'total.top3Share':'Cuota de los 3 mayores',
29774
+ 'total.top10Share':'Cuota de los 10 mayores',
29775
+ 'total.gini':'Coeficiente de Gini',
29776
+ 'total.trimmedMean':'Media recortada',
29777
+ 'total.winsorizedMean':'Media winsorizada',
29778
+ 'total.robustOutliers':'Valores atípicos (robusto)',
29779
+ 'total.jarqueBera':'Jarque–Bera',
28709
29780
  'stats.column':'Columna',
28710
29781
  'stats.choose':'Elija una columna para analizar',
28711
29782
  'stats.noColumns':'No hay columnas numéricas que analizar',
@@ -28725,6 +29796,15 @@ other:'{count} celdas actualizadas',
28725
29796
  'stats.outliers':'Valores atípicos',
28726
29797
  'stats.distribution':'Distribución',
28727
29798
  'stats.bin':'{count} entre {from} y {to}',
29799
+ 'stats.section.shape':'Forma',
29800
+ 'stats.section.robust':'Robusto',
29801
+ 'stats.section.concentration':'Concentración',
29802
+ 'stats.section.capability':'Capacidad',
29803
+ 'stats.cp':'Cp',
29804
+ 'stats.cpk':'Cpk',
29805
+ 'stats.pp':'Pp',
29806
+ 'stats.ppk':'Ppk',
29807
+ 'stats.outOfSpec':'Fuera de especificación',
28728
29808
  'stats.filtered':'De las {count} filas filtradas',
28729
29809
  'panel.zone.group':'las agrupaciones de filas',
28730
29810
  'panel.zone.values':'los valores',
@@ -29129,6 +30209,62 @@ other:'{count} células atualizadas',
29129
30209
  'panel.quickFilter':'Filtro rápido',
29130
30210
  'panel.formatting':'Formatação',
29131
30211
  'panel.statistics':'Estatísticas',
30212
+ 'panel.compare':'Comparar',
30213
+ 'compare.first':'Primeira coluna',
30214
+ 'compare.second':'Segunda coluna',
30215
+ 'compare.needTwo':'São necessárias duas colunas numéricas',
30216
+ 'compare.noPairs':'Nenhuma linha tem valor em ambas',
30217
+ 'compare.pairs':'{count} pares',
30218
+ 'compare.pearson':'Correlação (Pearson)',
30219
+ 'compare.spearman':'Correlação de postos (Spearman)',
30220
+ 'compare.kendall':'Tau de Kendall',
30221
+ 'compare.covariance':'Covariância',
30222
+ 'compare.slope':'Inclinação',
30223
+ 'compare.intercept':'Intercepto',
30224
+ 'compare.r2':'R²',
30225
+ 'compare.stdError':'Erro padrão',
30226
+ 'compare.weighted':'Média ponderada',
30227
+ 'total.sum':'Soma',
30228
+ 'total.avg':'Média',
30229
+ 'total.min':'Mín',
30230
+ 'total.max':'Máx',
30231
+ 'total.count':'Contagem',
30232
+ 'total.countValues':'Contagem de valores',
30233
+ 'total.first':'Primeiro',
30234
+ 'total.last':'Último',
30235
+ 'total.median':'Mediana',
30236
+ 'total.p25':'Percentil 25',
30237
+ 'total.p75':'Percentil 75',
30238
+ 'total.p90':'Percentil 90',
30239
+ 'total.p95':'Percentil 95',
30240
+ 'total.p99':'Percentil 99',
30241
+ 'total.iqr':'Intervalo interquartil',
30242
+ 'total.mad':'Desvio absoluto mediano',
30243
+ 'total.variance':'Variância',
30244
+ 'total.varianceP':'Variância (população)',
30245
+ 'total.stddev':'Desvio padrão',
30246
+ 'total.stddevP':'Desvio padrão (população)',
30247
+ 'total.range':'Amplitude',
30248
+ 'total.distinct':'Distintos',
30249
+ 'total.mode':'Moda',
30250
+ 'total.skewness':'Assimetria',
30251
+ 'total.kurtosis':'Curtose',
30252
+ 'total.geomean':'Média geométrica',
30253
+ 'total.harmean':'Média harmônica',
30254
+ 'total.sumSquares':'Soma dos quadrados',
30255
+ 'total.weightedAvg':'Média ponderada',
30256
+ 'total.argmin':'Menor por',
30257
+ 'total.argmax':'Maior por',
30258
+ 'total.hhi':'Concentração (HHI)',
30259
+ 'total.entropy':'Entropia',
30260
+ 'total.evenness':'Uniformidade',
30261
+ 'total.top3Share':'Participação dos 3 maiores',
30262
+ 'total.top10Share':'Participação dos 10 maiores',
30263
+ 'total.gini':'Coeficiente de Gini',
30264
+ 'total.trimmedMean':'Média aparada',
30265
+ 'total.winsorizedMean':'Média winsorizada',
30266
+ 'total.robustOutliers':'Valores atípicos (robusto)',
30267
+ 'total.jarqueBera':'Jarque–Bera',
29132
30268
  'stats.column':'Coluna',
29133
30269
  'stats.choose':'Escolha uma coluna para analisar',
29134
30270
  'stats.noColumns':'Nenhuma coluna numérica para analisar',
@@ -29148,6 +30284,15 @@ other:'{count} células atualizadas',
29148
30284
  'stats.outliers':'Valores atípicos',
29149
30285
  'stats.distribution':'Distribuição',
29150
30286
  'stats.bin':'{count} entre {from} e {to}',
30287
+ 'stats.section.shape':'Forma',
30288
+ 'stats.section.robust':'Robusto',
30289
+ 'stats.section.concentration':'Concentração',
30290
+ 'stats.section.capability':'Capacidade',
30291
+ 'stats.cp':'Cp',
30292
+ 'stats.cpk':'Cpk',
30293
+ 'stats.pp':'Pp',
30294
+ 'stats.ppk':'Ppk',
30295
+ 'stats.outOfSpec':'Fora da especificação',
29151
30296
  'stats.filtered':'De {count} linhas filtradas',
29152
30297
  'panel.zone.group':'os agrupamentos de linhas',
29153
30298
  'panel.zone.values':'os valores',
@@ -29552,6 +30697,62 @@ other:'{count} Zellen aktualisiert',
29552
30697
  'panel.quickFilter':'Schnellfilter',
29553
30698
  'panel.formatting':'Formatierung',
29554
30699
  'panel.statistics':'Statistik',
30700
+ 'panel.compare':'Vergleichen',
30701
+ 'compare.first':'Erste Spalte',
30702
+ 'compare.second':'Zweite Spalte',
30703
+ 'compare.needTwo':'Zum Vergleich sind zwei numerische Spalten nötig',
30704
+ 'compare.noPairs':'Keine Zeile hat in beiden einen Wert',
30705
+ 'compare.pairs':'{count} Paare',
30706
+ 'compare.pearson':'Korrelation (Pearson)',
30707
+ 'compare.spearman':'Rangkorrelation (Spearman)',
30708
+ 'compare.kendall':'Kendalls Tau',
30709
+ 'compare.covariance':'Kovarianz',
30710
+ 'compare.slope':'Steigung',
30711
+ 'compare.intercept':'Achsenabschnitt',
30712
+ 'compare.r2':'R²',
30713
+ 'compare.stdError':'Standardfehler',
30714
+ 'compare.weighted':'Gewichteter Mittelwert',
30715
+ 'total.sum':'Summe',
30716
+ 'total.avg':'Durchschnitt',
30717
+ 'total.min':'Min',
30718
+ 'total.max':'Max',
30719
+ 'total.count':'Anzahl',
30720
+ 'total.countValues':'Anzahl Werte',
30721
+ 'total.first':'Erster',
30722
+ 'total.last':'Letzter',
30723
+ 'total.median':'Median',
30724
+ 'total.p25':'25. Perzentil',
30725
+ 'total.p75':'75. Perzentil',
30726
+ 'total.p90':'90. Perzentil',
30727
+ 'total.p95':'95. Perzentil',
30728
+ 'total.p99':'99. Perzentil',
30729
+ 'total.iqr':'Interquartilsabstand',
30730
+ 'total.mad':'Mittlere absolute Abweichung',
30731
+ 'total.variance':'Varianz',
30732
+ 'total.varianceP':'Varianz (Grundgesamtheit)',
30733
+ 'total.stddev':'Standardabweichung',
30734
+ 'total.stddevP':'Standardabweichung (Grundgesamtheit)',
30735
+ 'total.range':'Spannweite',
30736
+ 'total.distinct':'Eindeutige',
30737
+ 'total.mode':'Modus',
30738
+ 'total.skewness':'Schiefe',
30739
+ 'total.kurtosis':'Wölbung',
30740
+ 'total.geomean':'Geometrisches Mittel',
30741
+ 'total.harmean':'Harmonisches Mittel',
30742
+ 'total.sumSquares':'Quadratsumme',
30743
+ 'total.weightedAvg':'Gewichteter Mittelwert',
30744
+ 'total.argmin':'Niedrigster nach',
30745
+ 'total.argmax':'Höchster nach',
30746
+ 'total.hhi':'Konzentration (HHI)',
30747
+ 'total.entropy':'Entropie',
30748
+ 'total.evenness':'Gleichmäßigkeit',
30749
+ 'total.top3Share':'Anteil Top 3',
30750
+ 'total.top10Share':'Anteil Top 10',
30751
+ 'total.gini':'Gini-Koeffizient',
30752
+ 'total.trimmedMean':'Getrimmtes Mittel',
30753
+ 'total.winsorizedMean':'Winsorisiertes Mittel',
30754
+ 'total.robustOutliers':'Ausreißer (robust)',
30755
+ 'total.jarqueBera':'Jarque–Bera',
29555
30756
  'stats.column':'Spalte',
29556
30757
  'stats.choose':'Spalte zum Analysieren wählen',
29557
30758
  'stats.noColumns':'Keine numerischen Spalten zum Analysieren',
@@ -29571,6 +30772,15 @@ other:'{count} Zellen aktualisiert',
29571
30772
  'stats.outliers':'Ausreißer',
29572
30773
  'stats.distribution':'Verteilung',
29573
30774
  'stats.bin':'{count} zwischen {from} und {to}',
30775
+ 'stats.section.shape':'Form',
30776
+ 'stats.section.robust':'Robust',
30777
+ 'stats.section.concentration':'Konzentration',
30778
+ 'stats.section.capability':'Fähigkeit',
30779
+ 'stats.cp':'Cp',
30780
+ 'stats.cpk':'Cpk',
30781
+ 'stats.pp':'Pp',
30782
+ 'stats.ppk':'Ppk',
30783
+ 'stats.outOfSpec':'Außerhalb der Spezifikation',
29574
30784
  'stats.filtered':'Von {count} gefilterten Zeilen',
29575
30785
  'panel.zone.group':'Zeilengruppen',
29576
30786
  'panel.zone.values':'Werte',
@@ -29975,6 +31185,62 @@ other:'{count} cellen bijgewerkt',
29975
31185
  'panel.quickFilter':'Snelfilter',
29976
31186
  'panel.formatting':'Opmaak',
29977
31187
  'panel.statistics':'Statistiek',
31188
+ 'panel.compare':'Vergelijken',
31189
+ 'compare.first':'Eerste kolom',
31190
+ 'compare.second':'Tweede kolom',
31191
+ 'compare.needTwo':'Er zijn twee numerieke kolommen nodig',
31192
+ 'compare.noPairs':'Geen rij heeft een waarde in beide',
31193
+ 'compare.pairs':'{count} paren',
31194
+ 'compare.pearson':'Correlatie (Pearson)',
31195
+ 'compare.spearman':'Rangcorrelatie (Spearman)',
31196
+ 'compare.kendall':'Kendalls tau',
31197
+ 'compare.covariance':'Covariantie',
31198
+ 'compare.slope':'Helling',
31199
+ 'compare.intercept':'Snijpunt',
31200
+ 'compare.r2':'R²',
31201
+ 'compare.stdError':'Standaardfout',
31202
+ 'compare.weighted':'Gewogen gemiddelde',
31203
+ 'total.sum':'Som',
31204
+ 'total.avg':'Gemiddelde',
31205
+ 'total.min':'Min',
31206
+ 'total.max':'Max',
31207
+ 'total.count':'Aantal',
31208
+ 'total.countValues':'Aantal waarden',
31209
+ 'total.first':'Eerste',
31210
+ 'total.last':'Laatste',
31211
+ 'total.median':'Mediaan',
31212
+ 'total.p25':'25e percentiel',
31213
+ 'total.p75':'75e percentiel',
31214
+ 'total.p90':'90e percentiel',
31215
+ 'total.p95':'95e percentiel',
31216
+ 'total.p99':'99e percentiel',
31217
+ 'total.iqr':'Interkwartielafstand',
31218
+ 'total.mad':'Mediane absolute afwijking',
31219
+ 'total.variance':'Variantie',
31220
+ 'total.varianceP':'Variantie (populatie)',
31221
+ 'total.stddev':'Standaardafwijking',
31222
+ 'total.stddevP':'Standaardafwijking (populatie)',
31223
+ 'total.range':'Bereik',
31224
+ 'total.distinct':'Unieke waarden',
31225
+ 'total.mode':'Modus',
31226
+ 'total.skewness':'Scheefheid',
31227
+ 'total.kurtosis':'Kurtosis',
31228
+ 'total.geomean':'Meetkundig gemiddelde',
31229
+ 'total.harmean':'Harmonisch gemiddelde',
31230
+ 'total.sumSquares':'Kwadratensom',
31231
+ 'total.weightedAvg':'Gewogen gemiddelde',
31232
+ 'total.argmin':'Laagste op',
31233
+ 'total.argmax':'Hoogste op',
31234
+ 'total.hhi':'Concentratie (HHI)',
31235
+ 'total.entropy':'Entropie',
31236
+ 'total.evenness':'Gelijkmatigheid',
31237
+ 'total.top3Share':'Aandeel top 3',
31238
+ 'total.top10Share':'Aandeel top 10',
31239
+ 'total.gini':'Gini-coëfficiënt',
31240
+ 'total.trimmedMean':'Getrimd gemiddelde',
31241
+ 'total.winsorizedMean':'Gewinsoriseerd gemiddelde',
31242
+ 'total.robustOutliers':'Uitschieters (robuust)',
31243
+ 'total.jarqueBera':'Jarque–Bera',
29978
31244
  'stats.column':'Kolom',
29979
31245
  'stats.choose':'Kies een kolom om te analyseren',
29980
31246
  'stats.noColumns':'Geen numerieke kolommen om te analyseren',
@@ -29994,6 +31260,15 @@ other:'{count} cellen bijgewerkt',
29994
31260
  'stats.outliers':'Uitschieters',
29995
31261
  'stats.distribution':'Verdeling',
29996
31262
  'stats.bin':'{count} tussen {from} en {to}',
31263
+ 'stats.section.shape':'Vorm',
31264
+ 'stats.section.robust':'Robuust',
31265
+ 'stats.section.concentration':'Concentratie',
31266
+ 'stats.section.capability':'Capabiliteit',
31267
+ 'stats.cp':'Cp',
31268
+ 'stats.cpk':'Cpk',
31269
+ 'stats.pp':'Pp',
31270
+ 'stats.ppk':'Ppk',
31271
+ 'stats.outOfSpec':'Buiten specificatie',
29997
31272
  'stats.filtered':'Van {count} gefilterde rijen',
29998
31273
  'panel.zone.group':'de rijgroepen',
29999
31274
  'panel.zone.values':'de waarden',
@@ -30398,6 +31673,62 @@ other:'{count} celler uppdaterade',
30398
31673
  'panel.quickFilter':'Snabbfilter',
30399
31674
  'panel.formatting':'Formatering',
30400
31675
  'panel.statistics':'Statistik',
31676
+ 'panel.compare':'Jämför',
31677
+ 'compare.first':'Första kolumnen',
31678
+ 'compare.second':'Andra kolumnen',
31679
+ 'compare.needTwo':'Två numeriska kolumner krävs',
31680
+ 'compare.noPairs':'Ingen rad har värde i båda',
31681
+ 'compare.pairs':'{count} par',
31682
+ 'compare.pearson':'Korrelation (Pearson)',
31683
+ 'compare.spearman':'Rangkorrelation (Spearman)',
31684
+ 'compare.kendall':'Kendalls tau',
31685
+ 'compare.covariance':'Kovarians',
31686
+ 'compare.slope':'Lutning',
31687
+ 'compare.intercept':'Intercept',
31688
+ 'compare.r2':'R²',
31689
+ 'compare.stdError':'Standardfel',
31690
+ 'compare.weighted':'Viktat medelvärde',
31691
+ 'total.sum':'Summa',
31692
+ 'total.avg':'Medelvärde',
31693
+ 'total.min':'Min',
31694
+ 'total.max':'Max',
31695
+ 'total.count':'Antal',
31696
+ 'total.countValues':'Antal värden',
31697
+ 'total.first':'Första',
31698
+ 'total.last':'Sista',
31699
+ 'total.median':'Median',
31700
+ 'total.p25':'25:e percentilen',
31701
+ 'total.p75':'75:e percentilen',
31702
+ 'total.p90':'90:e percentilen',
31703
+ 'total.p95':'95:e percentilen',
31704
+ 'total.p99':'99:e percentilen',
31705
+ 'total.iqr':'Kvartilavstånd',
31706
+ 'total.mad':'Median absolutavvikelse',
31707
+ 'total.variance':'Varians',
31708
+ 'total.varianceP':'Varians (population)',
31709
+ 'total.stddev':'Standardavvikelse',
31710
+ 'total.stddevP':'Standardavvikelse (population)',
31711
+ 'total.range':'Variationsbredd',
31712
+ 'total.distinct':'Unika',
31713
+ 'total.mode':'Typvärde',
31714
+ 'total.skewness':'Skevhet',
31715
+ 'total.kurtosis':'Toppighet',
31716
+ 'total.geomean':'Geometriskt medelvärde',
31717
+ 'total.harmean':'Harmoniskt medelvärde',
31718
+ 'total.sumSquares':'Kvadratsumma',
31719
+ 'total.weightedAvg':'Viktat medelvärde',
31720
+ 'total.argmin':'Lägst efter',
31721
+ 'total.argmax':'Högst efter',
31722
+ 'total.hhi':'Koncentration (HHI)',
31723
+ 'total.entropy':'Entropi',
31724
+ 'total.evenness':'Jämnhet',
31725
+ 'total.top3Share':'Andel topp 3',
31726
+ 'total.top10Share':'Andel topp 10',
31727
+ 'total.gini':'Ginikoefficient',
31728
+ 'total.trimmedMean':'Trimmat medelvärde',
31729
+ 'total.winsorizedMean':'Winsoriserat medelvärde',
31730
+ 'total.robustOutliers':'Avvikande värden (robust)',
31731
+ 'total.jarqueBera':'Jarque–Bera',
30401
31732
  'stats.column':'Kolumn',
30402
31733
  'stats.choose':'Välj en kolumn att analysera',
30403
31734
  'stats.noColumns':'Inga numeriska kolumner att analysera',
@@ -30417,6 +31748,15 @@ other:'{count} celler uppdaterade',
30417
31748
  'stats.outliers':'Avvikande värden',
30418
31749
  'stats.distribution':'Fördelning',
30419
31750
  'stats.bin':'{count} mellan {from} och {to}',
31751
+ 'stats.section.shape':'Form',
31752
+ 'stats.section.robust':'Robust',
31753
+ 'stats.section.concentration':'Koncentration',
31754
+ 'stats.section.capability':'Duglighet',
31755
+ 'stats.cp':'Cp',
31756
+ 'stats.cpk':'Cpk',
31757
+ 'stats.pp':'Pp',
31758
+ 'stats.ppk':'Ppk',
31759
+ 'stats.outOfSpec':'Utanför specifikation',
30420
31760
  'stats.filtered':'Av {count} filtrerade rader',
30421
31761
  'panel.zone.group':'radgrupperna',
30422
31762
  'panel.zone.values':'värdena',
@@ -30821,6 +32161,62 @@ other:'{count} celler opdateret',
30821
32161
  'panel.quickFilter':'Hurtigfilter',
30822
32162
  'panel.formatting':'Formatering',
30823
32163
  'panel.statistics':'Statistik',
32164
+ 'panel.compare':'Sammenlign',
32165
+ 'compare.first':'Første kolonne',
32166
+ 'compare.second':'Anden kolonne',
32167
+ 'compare.needTwo':'Der kræves to numeriske kolonner',
32168
+ 'compare.noPairs':'Ingen rækker har værdi i begge',
32169
+ 'compare.pairs':'{count} par',
32170
+ 'compare.pearson':'Korrelation (Pearson)',
32171
+ 'compare.spearman':'Rangkorrelation (Spearman)',
32172
+ 'compare.kendall':'Kendalls tau',
32173
+ 'compare.covariance':'Kovarians',
32174
+ 'compare.slope':'Hældning',
32175
+ 'compare.intercept':'Skæring',
32176
+ 'compare.r2':'R²',
32177
+ 'compare.stdError':'Standardfejl',
32178
+ 'compare.weighted':'Vægtet gennemsnit',
32179
+ 'total.sum':'Sum',
32180
+ 'total.avg':'Gennemsnit',
32181
+ 'total.min':'Min',
32182
+ 'total.max':'Maks',
32183
+ 'total.count':'Antal',
32184
+ 'total.countValues':'Antal værdier',
32185
+ 'total.first':'Første',
32186
+ 'total.last':'Sidste',
32187
+ 'total.median':'Median',
32188
+ 'total.p25':'25. percentil',
32189
+ 'total.p75':'75. percentil',
32190
+ 'total.p90':'90. percentil',
32191
+ 'total.p95':'95. percentil',
32192
+ 'total.p99':'99. percentil',
32193
+ 'total.iqr':'Interkvartilbredde',
32194
+ 'total.mad':'Median absolut afvigelse',
32195
+ 'total.variance':'Varians',
32196
+ 'total.varianceP':'Varians (population)',
32197
+ 'total.stddev':'Standardafvigelse',
32198
+ 'total.stddevP':'Standardafvigelse (population)',
32199
+ 'total.range':'Spændvidde',
32200
+ 'total.distinct':'Unikke',
32201
+ 'total.mode':'Typetal',
32202
+ 'total.skewness':'Skævhed',
32203
+ 'total.kurtosis':'Kurtosis',
32204
+ 'total.geomean':'Geometrisk gennemsnit',
32205
+ 'total.harmean':'Harmonisk gennemsnit',
32206
+ 'total.sumSquares':'Kvadratsum',
32207
+ 'total.weightedAvg':'Vægtet gennemsnit',
32208
+ 'total.argmin':'Laveste efter',
32209
+ 'total.argmax':'Højeste efter',
32210
+ 'total.hhi':'Koncentration (HHI)',
32211
+ 'total.entropy':'Entropi',
32212
+ 'total.evenness':'Jævnhed',
32213
+ 'total.top3Share':'Top 3-andel',
32214
+ 'total.top10Share':'Top 10-andel',
32215
+ 'total.gini':'Gini-koefficient',
32216
+ 'total.trimmedMean':'Trimmet gennemsnit',
32217
+ 'total.winsorizedMean':'Winsoriseret gennemsnit',
32218
+ 'total.robustOutliers':'Outliere (robust)',
32219
+ 'total.jarqueBera':'Jarque–Bera',
30824
32220
  'stats.column':'Kolonne',
30825
32221
  'stats.choose':'Vælg en kolonne at analysere',
30826
32222
  'stats.noColumns':'Ingen numeriske kolonner at analysere',
@@ -30840,6 +32236,15 @@ other:'{count} celler opdateret',
30840
32236
  'stats.outliers':'Outliere',
30841
32237
  'stats.distribution':'Fordeling',
30842
32238
  'stats.bin':'{count} mellem {from} og {to}',
32239
+ 'stats.section.shape':'Form',
32240
+ 'stats.section.robust':'Robust',
32241
+ 'stats.section.concentration':'Koncentration',
32242
+ 'stats.section.capability':'Kapabilitet',
32243
+ 'stats.cp':'Cp',
32244
+ 'stats.cpk':'Cpk',
32245
+ 'stats.pp':'Pp',
32246
+ 'stats.ppk':'Ppk',
32247
+ 'stats.outOfSpec':'Uden for specifikation',
30843
32248
  'stats.filtered':'Ud af {count} filtrerede rækker',
30844
32249
  'panel.zone.group':'rækkegrupperne',
30845
32250
  'panel.zone.values':'værdierne',
@@ -31244,6 +32649,62 @@ other:'{count} celler oppdatert',
31244
32649
  'panel.quickFilter':'Hurtigfilter',
31245
32650
  'panel.formatting':'Formatering',
31246
32651
  'panel.statistics':'Statistikk',
32652
+ 'panel.compare':'Sammenlign',
32653
+ 'compare.first':'Første kolonne',
32654
+ 'compare.second':'Andre kolonne',
32655
+ 'compare.needTwo':'Det trengs to numeriske kolonner',
32656
+ 'compare.noPairs':'Ingen rader har verdi i begge',
32657
+ 'compare.pairs':'{count} par',
32658
+ 'compare.pearson':'Korrelasjon (Pearson)',
32659
+ 'compare.spearman':'Rangkorrelasjon (Spearman)',
32660
+ 'compare.kendall':'Kendalls tau',
32661
+ 'compare.covariance':'Kovarians',
32662
+ 'compare.slope':'Stigningstall',
32663
+ 'compare.intercept':'Skjæringspunkt',
32664
+ 'compare.r2':'R²',
32665
+ 'compare.stdError':'Standardfeil',
32666
+ 'compare.weighted':'Vektet gjennomsnitt',
32667
+ 'total.sum':'Sum',
32668
+ 'total.avg':'Gjennomsnitt',
32669
+ 'total.min':'Min',
32670
+ 'total.max':'Maks',
32671
+ 'total.count':'Antall',
32672
+ 'total.countValues':'Antall verdier',
32673
+ 'total.first':'Første',
32674
+ 'total.last':'Siste',
32675
+ 'total.median':'Median',
32676
+ 'total.p25':'25. persentil',
32677
+ 'total.p75':'75. persentil',
32678
+ 'total.p90':'90. persentil',
32679
+ 'total.p95':'95. persentil',
32680
+ 'total.p99':'99. persentil',
32681
+ 'total.iqr':'Kvartilbredde',
32682
+ 'total.mad':'Median absolutt avvik',
32683
+ 'total.variance':'Varians',
32684
+ 'total.varianceP':'Varians (populasjon)',
32685
+ 'total.stddev':'Standardavvik',
32686
+ 'total.stddevP':'Standardavvik (populasjon)',
32687
+ 'total.range':'Variasjonsbredde',
32688
+ 'total.distinct':'Unike',
32689
+ 'total.mode':'Typetall',
32690
+ 'total.skewness':'Skjevhet',
32691
+ 'total.kurtosis':'Kurtose',
32692
+ 'total.geomean':'Geometrisk gjennomsnitt',
32693
+ 'total.harmean':'Harmonisk gjennomsnitt',
32694
+ 'total.sumSquares':'Kvadratsum',
32695
+ 'total.weightedAvg':'Vektet gjennomsnitt',
32696
+ 'total.argmin':'Laveste etter',
32697
+ 'total.argmax':'Høyeste etter',
32698
+ 'total.hhi':'Konsentrasjon (HHI)',
32699
+ 'total.entropy':'Entropi',
32700
+ 'total.evenness':'Jevnhet',
32701
+ 'total.top3Share':'Topp 3-andel',
32702
+ 'total.top10Share':'Topp 10-andel',
32703
+ 'total.gini':'Gini-koeffisient',
32704
+ 'total.trimmedMean':'Trimmet gjennomsnitt',
32705
+ 'total.winsorizedMean':'Winsorisert gjennomsnitt',
32706
+ 'total.robustOutliers':'Uteliggere (robust)',
32707
+ 'total.jarqueBera':'Jarque–Bera',
31247
32708
  'stats.column':'Kolonne',
31248
32709
  'stats.choose':'Velg en kolonne å analysere',
31249
32710
  'stats.noColumns':'Ingen numeriske kolonner å analysere',
@@ -31263,6 +32724,15 @@ other:'{count} celler oppdatert',
31263
32724
  'stats.outliers':'Uteliggere',
31264
32725
  'stats.distribution':'Fordeling',
31265
32726
  'stats.bin':'{count} mellom {from} og {to}',
32727
+ 'stats.section.shape':'Form',
32728
+ 'stats.section.robust':'Robust',
32729
+ 'stats.section.concentration':'Konsentrasjon',
32730
+ 'stats.section.capability':'Kapabilitet',
32731
+ 'stats.cp':'Cp',
32732
+ 'stats.cpk':'Cpk',
32733
+ 'stats.pp':'Pp',
32734
+ 'stats.ppk':'Ppk',
32735
+ 'stats.outOfSpec':'Utenfor spesifikasjon',
31266
32736
  'stats.filtered':'Av {count} filtrerte rader',
31267
32737
  'panel.zone.group':'radgruppene',
31268
32738
  'panel.zone.values':'verdiene',
@@ -31667,6 +33137,62 @@ other:'{count} solua päivitetty',
31667
33137
  'panel.quickFilter':'Pikasuodatin',
31668
33138
  'panel.formatting':'Muotoilu',
31669
33139
  'panel.statistics':'Tilastot',
33140
+ 'panel.compare':'Vertaa',
33141
+ 'compare.first':'Ensimmäinen sarake',
33142
+ 'compare.second':'Toinen sarake',
33143
+ 'compare.needTwo':'Vertailuun tarvitaan kaksi numeerista saraketta',
33144
+ 'compare.noPairs':'Yhdelläkään rivillä ei ole arvoa molemmissa',
33145
+ 'compare.pairs':'{count} paria',
33146
+ 'compare.pearson':'Korrelaatio (Pearson)',
33147
+ 'compare.spearman':'Järjestyskorrelaatio (Spearman)',
33148
+ 'compare.kendall':'Kendallin tau',
33149
+ 'compare.covariance':'Kovarianssi',
33150
+ 'compare.slope':'Kulmakerroin',
33151
+ 'compare.intercept':'Vakiotermi',
33152
+ 'compare.r2':'R²',
33153
+ 'compare.stdError':'Keskivirhe',
33154
+ 'compare.weighted':'Painotettu keskiarvo',
33155
+ 'total.sum':'Summa',
33156
+ 'total.avg':'Keskiarvo',
33157
+ 'total.min':'Pienin',
33158
+ 'total.max':'Suurin',
33159
+ 'total.count':'Lukumäärä',
33160
+ 'total.countValues':'Arvojen määrä',
33161
+ 'total.first':'Ensimmäinen',
33162
+ 'total.last':'Viimeinen',
33163
+ 'total.median':'Mediaani',
33164
+ 'total.p25':'25. persentiili',
33165
+ 'total.p75':'75. persentiili',
33166
+ 'total.p90':'90. persentiili',
33167
+ 'total.p95':'95. persentiili',
33168
+ 'total.p99':'99. persentiili',
33169
+ 'total.iqr':'Kvartiiliväli',
33170
+ 'total.mad':'Mediaanin absoluuttinen poikkeama',
33171
+ 'total.variance':'Varianssi',
33172
+ 'total.varianceP':'Varianssi (populaatio)',
33173
+ 'total.stddev':'Keskihajonta',
33174
+ 'total.stddevP':'Keskihajonta (populaatio)',
33175
+ 'total.range':'Vaihteluväli',
33176
+ 'total.distinct':'Eri arvoja',
33177
+ 'total.mode':'Moodi',
33178
+ 'total.skewness':'Vinous',
33179
+ 'total.kurtosis':'Huipukkuus',
33180
+ 'total.geomean':'Geometrinen keskiarvo',
33181
+ 'total.harmean':'Harmoninen keskiarvo',
33182
+ 'total.sumSquares':'Neliösumma',
33183
+ 'total.weightedAvg':'Painotettu keskiarvo',
33184
+ 'total.argmin':'Pienin sarakkeen mukaan',
33185
+ 'total.argmax':'Suurin sarakkeen mukaan',
33186
+ 'total.hhi':'Keskittyminen (HHI)',
33187
+ 'total.entropy':'Entropia',
33188
+ 'total.evenness':'Tasaisuus',
33189
+ 'total.top3Share':'Kolmen suurimman osuus',
33190
+ 'total.top10Share':'Kymmenen suurimman osuus',
33191
+ 'total.gini':'Gini-kerroin',
33192
+ 'total.trimmedMean':'Typistetty keskiarvo',
33193
+ 'total.winsorizedMean':'Winsoroitu keskiarvo',
33194
+ 'total.robustOutliers':'Poikkeavat arvot (robusti)',
33195
+ 'total.jarqueBera':'Jarque–Bera',
31670
33196
  'stats.column':'Sarake',
31671
33197
  'stats.choose':'Valitse analysoitava sarake',
31672
33198
  'stats.noColumns':'Ei numeerisia sarakkeita analysoitavaksi',
@@ -31686,6 +33212,15 @@ other:'{count} solua päivitetty',
31686
33212
  'stats.outliers':'Poikkeavat arvot',
31687
33213
  'stats.distribution':'Jakauma',
31688
33214
  'stats.bin':'{count} välillä {from}–{to}',
33215
+ 'stats.section.shape':'Muoto',
33216
+ 'stats.section.robust':'Robusti',
33217
+ 'stats.section.concentration':'Keskittyminen',
33218
+ 'stats.section.capability':'Suorituskyky',
33219
+ 'stats.cp':'Cp',
33220
+ 'stats.cpk':'Cpk',
33221
+ 'stats.pp':'Pp',
33222
+ 'stats.ppk':'Ppk',
33223
+ 'stats.outOfSpec':'Spesifikaation ulkopuolella',
31689
33224
  'stats.filtered':'{count} suodatetusta rivistä',
31690
33225
  'panel.zone.group':'riviryhmiin',
31691
33226
  'panel.zone.values':'arvoihin',
@@ -32114,6 +33649,62 @@ other:'zaktualizowano {count} komórek',
32114
33649
  'panel.quickFilter':'Szybki filtr',
32115
33650
  'panel.formatting':'Formatowanie',
32116
33651
  'panel.statistics':'Statystyki',
33652
+ 'panel.compare':'Porównaj',
33653
+ 'compare.first':'Pierwsza kolumna',
33654
+ 'compare.second':'Druga kolumna',
33655
+ 'compare.needTwo':'Do porównania potrzebne są dwie kolumny liczbowe',
33656
+ 'compare.noPairs':'Żaden wiersz nie ma wartości w obu',
33657
+ 'compare.pairs':'Liczba par: {count}',
33658
+ 'compare.pearson':'Korelacja (Pearson)',
33659
+ 'compare.spearman':'Korelacja rang (Spearman)',
33660
+ 'compare.kendall':'Tau Kendalla',
33661
+ 'compare.covariance':'Kowariancja',
33662
+ 'compare.slope':'Nachylenie',
33663
+ 'compare.intercept':'Wyraz wolny',
33664
+ 'compare.r2':'R²',
33665
+ 'compare.stdError':'Błąd standardowy',
33666
+ 'compare.weighted':'Średnia ważona',
33667
+ 'total.sum':'Suma',
33668
+ 'total.avg':'Średnia',
33669
+ 'total.min':'Min',
33670
+ 'total.max':'Maks',
33671
+ 'total.count':'Liczba',
33672
+ 'total.countValues':'Liczba wartości',
33673
+ 'total.first':'Pierwszy',
33674
+ 'total.last':'Ostatni',
33675
+ 'total.median':'Mediana',
33676
+ 'total.p25':'25. percentyl',
33677
+ 'total.p75':'75. percentyl',
33678
+ 'total.p90':'90. percentyl',
33679
+ 'total.p95':'95. percentyl',
33680
+ 'total.p99':'99. percentyl',
33681
+ 'total.iqr':'Rozstęp ćwiartkowy',
33682
+ 'total.mad':'Mediana odchyleń bezwzględnych',
33683
+ 'total.variance':'Wariancja',
33684
+ 'total.varianceP':'Wariancja (populacja)',
33685
+ 'total.stddev':'Odchylenie standardowe',
33686
+ 'total.stddevP':'Odchylenie standardowe (populacja)',
33687
+ 'total.range':'Rozstęp',
33688
+ 'total.distinct':'Unikatowe',
33689
+ 'total.mode':'Dominanta',
33690
+ 'total.skewness':'Skośność',
33691
+ 'total.kurtosis':'Kurtoza',
33692
+ 'total.geomean':'Średnia geometryczna',
33693
+ 'total.harmean':'Średnia harmoniczna',
33694
+ 'total.sumSquares':'Suma kwadratów',
33695
+ 'total.weightedAvg':'Średnia ważona',
33696
+ 'total.argmin':'Najniższy wg',
33697
+ 'total.argmax':'Najwyższy wg',
33698
+ 'total.hhi':'Koncentracja (HHI)',
33699
+ 'total.entropy':'Entropia',
33700
+ 'total.evenness':'Równomierność',
33701
+ 'total.top3Share':'Udział 3 największych',
33702
+ 'total.top10Share':'Udział 10 największych',
33703
+ 'total.gini':'Współczynnik Giniego',
33704
+ 'total.trimmedMean':'Średnia ucinana',
33705
+ 'total.winsorizedMean':'Średnia winsorowska',
33706
+ 'total.robustOutliers':'Wartości odstające (odporne)',
33707
+ 'total.jarqueBera':'Jarque–Bera',
32117
33708
  'stats.column':'Kolumna',
32118
33709
  'stats.choose':'Wybierz kolumnę do analizy',
32119
33710
  'stats.noColumns':'Brak kolumn liczbowych do analizy',
@@ -32133,6 +33724,15 @@ other:'zaktualizowano {count} komórek',
32133
33724
  'stats.outliers':'Wartości odstające',
32134
33725
  'stats.distribution':'Rozkład',
32135
33726
  'stats.bin':'{count} między {from} a {to}',
33727
+ 'stats.section.shape':'Kształt',
33728
+ 'stats.section.robust':'Odporne',
33729
+ 'stats.section.concentration':'Koncentracja',
33730
+ 'stats.section.capability':'Zdolność',
33731
+ 'stats.cp':'Cp',
33732
+ 'stats.cpk':'Cpk',
33733
+ 'stats.pp':'Pp',
33734
+ 'stats.ppk':'Ppk',
33735
+ 'stats.outOfSpec':'Poza specyfikacją',
32136
33736
  'stats.filtered':'Z {count} przefiltrowanych wierszy',
32137
33737
  'panel.zone.group':'grupowania wierszy',
32138
33738
  'panel.zone.values':'wartości',
@@ -32565,6 +34165,62 @@ other:'aktualizováno {count} buněk',
32565
34165
  'panel.quickFilter':'Rychlý filtr',
32566
34166
  'panel.formatting':'Formátování',
32567
34167
  'panel.statistics':'Statistika',
34168
+ 'panel.compare':'Porovnat',
34169
+ 'compare.first':'První sloupec',
34170
+ 'compare.second':'Druhý sloupec',
34171
+ 'compare.needTwo':'K porovnání jsou potřeba dva číselné sloupce',
34172
+ 'compare.noPairs':'Žádné řádky nemají hodnotu v obou',
34173
+ 'compare.pairs':'Počet dvojic: {count}',
34174
+ 'compare.pearson':'Korelace (Pearson)',
34175
+ 'compare.spearman':'Pořadová korelace (Spearman)',
34176
+ 'compare.kendall':'Kendallovo tau',
34177
+ 'compare.covariance':'Kovariance',
34178
+ 'compare.slope':'Sklon',
34179
+ 'compare.intercept':'Průsečík',
34180
+ 'compare.r2':'R²',
34181
+ 'compare.stdError':'Standardní chyba',
34182
+ 'compare.weighted':'Vážený průměr',
34183
+ 'total.sum':'Součet',
34184
+ 'total.avg':'Průměr',
34185
+ 'total.min':'Minimum',
34186
+ 'total.max':'Maximum',
34187
+ 'total.count':'Počet',
34188
+ 'total.countValues':'Počet hodnot',
34189
+ 'total.first':'První',
34190
+ 'total.last':'Poslední',
34191
+ 'total.median':'Medián',
34192
+ 'total.p25':'25. percentil',
34193
+ 'total.p75':'75. percentil',
34194
+ 'total.p90':'90. percentil',
34195
+ 'total.p95':'95. percentil',
34196
+ 'total.p99':'99. percentil',
34197
+ 'total.iqr':'Mezikvartilové rozpětí',
34198
+ 'total.mad':'Mediánová absolutní odchylka',
34199
+ 'total.variance':'Rozptyl',
34200
+ 'total.varianceP':'Rozptyl (populace)',
34201
+ 'total.stddev':'Směrodatná odchylka',
34202
+ 'total.stddevP':'Směrodatná odchylka (populace)',
34203
+ 'total.range':'Rozpětí',
34204
+ 'total.distinct':'Jedinečných',
34205
+ 'total.mode':'Modus',
34206
+ 'total.skewness':'Šikmost',
34207
+ 'total.kurtosis':'Špičatost',
34208
+ 'total.geomean':'Geometrický průměr',
34209
+ 'total.harmean':'Harmonický průměr',
34210
+ 'total.sumSquares':'Součet čtverců',
34211
+ 'total.weightedAvg':'Vážený průměr',
34212
+ 'total.argmin':'Nejnižší podle',
34213
+ 'total.argmax':'Nejvyšší podle',
34214
+ 'total.hhi':'Koncentrace (HHI)',
34215
+ 'total.entropy':'Entropie',
34216
+ 'total.evenness':'Vyrovnanost',
34217
+ 'total.top3Share':'Podíl top 3',
34218
+ 'total.top10Share':'Podíl top 10',
34219
+ 'total.gini':'Giniho koeficient',
34220
+ 'total.trimmedMean':'Useknutý průměr',
34221
+ 'total.winsorizedMean':'Winsorizovaný průměr',
34222
+ 'total.robustOutliers':'Odlehlé hodnoty (robustní)',
34223
+ 'total.jarqueBera':'Jarque–Bera',
32568
34224
  'stats.column':'Sloupec',
32569
34225
  'stats.choose':'Vyberte sloupec k analýze',
32570
34226
  'stats.noColumns':'Žádné číselné sloupce k analýze',
@@ -32584,6 +34240,15 @@ other:'aktualizováno {count} buněk',
32584
34240
  'stats.outliers':'Odlehlé hodnoty',
32585
34241
  'stats.distribution':'Rozdělení',
32586
34242
  'stats.bin':'{count} mezi {from} a {to}',
34243
+ 'stats.section.shape':'Tvar',
34244
+ 'stats.section.robust':'Robustní',
34245
+ 'stats.section.concentration':'Koncentrace',
34246
+ 'stats.section.capability':'Způsobilost',
34247
+ 'stats.cp':'Cp',
34248
+ 'stats.cpk':'Cpk',
34249
+ 'stats.pp':'Pp',
34250
+ 'stats.ppk':'Ppk',
34251
+ 'stats.outOfSpec':'Mimo specifikaci',
32587
34252
  'stats.filtered':'Z {count} filtrovaných řádků',
32588
34253
  'panel.zone.group':'seskupení řádků',
32589
34254
  'panel.zone.values':'hodnot',
@@ -32992,6 +34657,62 @@ other:'{count} cella frissítve',
32992
34657
  'panel.quickFilter':'Gyorsszűrő',
32993
34658
  'panel.formatting':'Formázás',
32994
34659
  'panel.statistics':'Statisztika',
34660
+ 'panel.compare':'Összehasonlítás',
34661
+ 'compare.first':'Első oszlop',
34662
+ 'compare.second':'Második oszlop',
34663
+ 'compare.needTwo':'Két numerikus oszlop szükséges',
34664
+ 'compare.noPairs':'Egyetlen sorban sincs érték mindkettőben',
34665
+ 'compare.pairs':'{count} pár',
34666
+ 'compare.pearson':'Korreláció (Pearson)',
34667
+ 'compare.spearman':'Rangkorreláció (Spearman)',
34668
+ 'compare.kendall':'Kendall-féle tau',
34669
+ 'compare.covariance':'Kovariancia',
34670
+ 'compare.slope':'Meredekség',
34671
+ 'compare.intercept':'Tengelymetszet',
34672
+ 'compare.r2':'R²',
34673
+ 'compare.stdError':'Standard hiba',
34674
+ 'compare.weighted':'Súlyozott átlag',
34675
+ 'total.sum':'Összeg',
34676
+ 'total.avg':'Átlag',
34677
+ 'total.min':'Minimum',
34678
+ 'total.max':'Maximum',
34679
+ 'total.count':'Darabszám',
34680
+ 'total.countValues':'Értékek száma',
34681
+ 'total.first':'Első',
34682
+ 'total.last':'Utolsó',
34683
+ 'total.median':'Medián',
34684
+ 'total.p25':'25. percentilis',
34685
+ 'total.p75':'75. percentilis',
34686
+ 'total.p90':'90. percentilis',
34687
+ 'total.p95':'95. percentilis',
34688
+ 'total.p99':'99. percentilis',
34689
+ 'total.iqr':'Interkvartilis terjedelem',
34690
+ 'total.mad':'Medián abszolút eltérés',
34691
+ 'total.variance':'Variancia',
34692
+ 'total.varianceP':'Variancia (sokaság)',
34693
+ 'total.stddev':'Szórás',
34694
+ 'total.stddevP':'Szórás (sokaság)',
34695
+ 'total.range':'Terjedelem',
34696
+ 'total.distinct':'Egyedi',
34697
+ 'total.mode':'Módusz',
34698
+ 'total.skewness':'Ferdeség',
34699
+ 'total.kurtosis':'Csúcsosság',
34700
+ 'total.geomean':'Mértani átlag',
34701
+ 'total.harmean':'Harmonikus átlag',
34702
+ 'total.sumSquares':'Négyzetösszeg',
34703
+ 'total.weightedAvg':'Súlyozott átlag',
34704
+ 'total.argmin':'Legalacsonyabb eszerint',
34705
+ 'total.argmax':'Legmagasabb eszerint',
34706
+ 'total.hhi':'Koncentráció (HHI)',
34707
+ 'total.entropy':'Entrópia',
34708
+ 'total.evenness':'Egyenletesség',
34709
+ 'total.top3Share':'Top 3 részesedés',
34710
+ 'total.top10Share':'Top 10 részesedés',
34711
+ 'total.gini':'Gini-együttható',
34712
+ 'total.trimmedMean':'Nyesett átlag',
34713
+ 'total.winsorizedMean':'Winsorizált átlag',
34714
+ 'total.robustOutliers':'Kiugró értékek (robusztus)',
34715
+ 'total.jarqueBera':'Jarque–Bera',
32995
34716
  'stats.column':'Oszlop',
32996
34717
  'stats.choose':'Válasszon oszlopot az elemzéshez',
32997
34718
  'stats.noColumns':'Nincs elemezhető numerikus oszlop',
@@ -33011,6 +34732,15 @@ other:'{count} cella frissítve',
33011
34732
  'stats.outliers':'Kiugró értékek',
33012
34733
  'stats.distribution':'Eloszlás',
33013
34734
  'stats.bin':'{count} a(z) {from} és {to} között',
34735
+ 'stats.section.shape':'Alak',
34736
+ 'stats.section.robust':'Robusztus',
34737
+ 'stats.section.concentration':'Koncentráció',
34738
+ 'stats.section.capability':'Képesség',
34739
+ 'stats.cp':'Cp',
34740
+ 'stats.cpk':'Cpk',
34741
+ 'stats.pp':'Pp',
34742
+ 'stats.ppk':'Ppk',
34743
+ 'stats.outOfSpec':'Specifikáción kívül',
33014
34744
  'stats.filtered':'A {count} szűrt sorból',
33015
34745
  'panel.zone.group':'a sorcsoportokból',
33016
34746
  'panel.zone.values':'az értékekből',
@@ -33427,6 +35157,62 @@ other:'{count} de celule actualizate',
33427
35157
  'panel.quickFilter':'Filtru rapid',
33428
35158
  'panel.formatting':'Formatare',
33429
35159
  'panel.statistics':'Statistici',
35160
+ 'panel.compare':'Compară',
35161
+ 'compare.first':'Prima coloană',
35162
+ 'compare.second':'A doua coloană',
35163
+ 'compare.needTwo':'Sunt necesare două coloane numerice',
35164
+ 'compare.noPairs':'Niciun rând nu are valoare în ambele',
35165
+ 'compare.pairs':'{count} perechi',
35166
+ 'compare.pearson':'Corelație (Pearson)',
35167
+ 'compare.spearman':'Corelație de rang (Spearman)',
35168
+ 'compare.kendall':'Tau Kendall',
35169
+ 'compare.covariance':'Covarianță',
35170
+ 'compare.slope':'Panta',
35171
+ 'compare.intercept':'Interceptul',
35172
+ 'compare.r2':'R²',
35173
+ 'compare.stdError':'Eroare standard',
35174
+ 'compare.weighted':'Medie ponderată',
35175
+ 'total.sum':'Sumă',
35176
+ 'total.avg':'Medie',
35177
+ 'total.min':'Min',
35178
+ 'total.max':'Max',
35179
+ 'total.count':'Număr',
35180
+ 'total.countValues':'Număr de valori',
35181
+ 'total.first':'Primul',
35182
+ 'total.last':'Ultimul',
35183
+ 'total.median':'Mediană',
35184
+ 'total.p25':'Percentila 25',
35185
+ 'total.p75':'Percentila 75',
35186
+ 'total.p90':'Percentila 90',
35187
+ 'total.p95':'Percentila 95',
35188
+ 'total.p99':'Percentila 99',
35189
+ 'total.iqr':'Interval intercuartilic',
35190
+ 'total.mad':'Abatere absolută mediană',
35191
+ 'total.variance':'Varianță',
35192
+ 'total.varianceP':'Varianță (populație)',
35193
+ 'total.stddev':'Abatere standard',
35194
+ 'total.stddevP':'Abatere standard (populație)',
35195
+ 'total.range':'Amplitudine',
35196
+ 'total.distinct':'Distincte',
35197
+ 'total.mode':'Mod',
35198
+ 'total.skewness':'Asimetrie',
35199
+ 'total.kurtosis':'Boltire',
35200
+ 'total.geomean':'Medie geometrică',
35201
+ 'total.harmean':'Medie armonică',
35202
+ 'total.sumSquares':'Suma pătratelor',
35203
+ 'total.weightedAvg':'Medie ponderată',
35204
+ 'total.argmin':'Cel mai mic după',
35205
+ 'total.argmax':'Cel mai mare după',
35206
+ 'total.hhi':'Concentrare (HHI)',
35207
+ 'total.entropy':'Entropie',
35208
+ 'total.evenness':'Uniformitate',
35209
+ 'total.top3Share':'Cota primelor 3',
35210
+ 'total.top10Share':'Cota primelor 10',
35211
+ 'total.gini':'Coeficient Gini',
35212
+ 'total.trimmedMean':'Medie trunchiată',
35213
+ 'total.winsorizedMean':'Medie winsorizată',
35214
+ 'total.robustOutliers':'Valori aberante (robust)',
35215
+ 'total.jarqueBera':'Jarque–Bera',
33430
35216
  'stats.column':'Coloană',
33431
35217
  'stats.choose':'Alegeți o coloană de analizat',
33432
35218
  'stats.noColumns':'Nicio coloană numerică de analizat',
@@ -33446,6 +35232,15 @@ other:'{count} de celule actualizate',
33446
35232
  'stats.outliers':'Valori aberante',
33447
35233
  'stats.distribution':'Distribuție',
33448
35234
  'stats.bin':'{count} între {from} și {to}',
35235
+ 'stats.section.shape':'Formă',
35236
+ 'stats.section.robust':'Robust',
35237
+ 'stats.section.concentration':'Concentrare',
35238
+ 'stats.section.capability':'Capabilitate',
35239
+ 'stats.cp':'Cp',
35240
+ 'stats.cpk':'Cpk',
35241
+ 'stats.pp':'Pp',
35242
+ 'stats.ppk':'Ppk',
35243
+ 'stats.outOfSpec':'În afara specificației',
33449
35244
  'stats.filtered':'Din {count} rânduri filtrate',
33450
35245
  'panel.zone.group':'grupările de rânduri',
33451
35246
  'panel.zone.values':'valorile',
@@ -33876,6 +35671,62 @@ other:'оновлено {count} комірок',
33876
35671
  'panel.quickFilter':'Швидкий фільтр',
33877
35672
  'panel.formatting':'Форматування',
33878
35673
  'panel.statistics':'Статистика',
35674
+ 'panel.compare':'Порівняти',
35675
+ 'compare.first':'Перший стовпець',
35676
+ 'compare.second':'Другий стовпець',
35677
+ 'compare.needTwo':'Потрібні два числові стовпці',
35678
+ 'compare.noPairs':'Жоден рядок не має значення в обох',
35679
+ 'compare.pairs':'{count} пар',
35680
+ 'compare.pearson':'Кореляція (Пірсон)',
35681
+ 'compare.spearman':'Рангова кореляція (Спірмен)',
35682
+ 'compare.kendall':'Тау Кендала',
35683
+ 'compare.covariance':'Коваріація',
35684
+ 'compare.slope':'Нахил',
35685
+ 'compare.intercept':'Перетин',
35686
+ 'compare.r2':'R²',
35687
+ 'compare.stdError':'Стандартна похибка',
35688
+ 'compare.weighted':'Зважене середнє',
35689
+ 'total.sum':'Сума',
35690
+ 'total.avg':'Середнє',
35691
+ 'total.min':'Мінімум',
35692
+ 'total.max':'Максимум',
35693
+ 'total.count':'Кількість',
35694
+ 'total.countValues':'Кількість значень',
35695
+ 'total.first':'Перше',
35696
+ 'total.last':'Останнє',
35697
+ 'total.median':'Медіана',
35698
+ 'total.p25':'25-й процентиль',
35699
+ 'total.p75':'75-й процентиль',
35700
+ 'total.p90':'90-й процентиль',
35701
+ 'total.p95':'95-й процентиль',
35702
+ 'total.p99':'99-й процентиль',
35703
+ 'total.iqr':'Міжквартильний розмах',
35704
+ 'total.mad':'Медіанне абсолютне відхилення',
35705
+ 'total.variance':'Дисперсія',
35706
+ 'total.varianceP':'Дисперсія (генеральна)',
35707
+ 'total.stddev':'Стандартне відхилення',
35708
+ 'total.stddevP':'Стандартне відхилення (генеральна)',
35709
+ 'total.range':'Розмах',
35710
+ 'total.distinct':'Унікальних',
35711
+ 'total.mode':'Мода',
35712
+ 'total.skewness':'Асиметрія',
35713
+ 'total.kurtosis':'Ексцес',
35714
+ 'total.geomean':'Середнє геометричне',
35715
+ 'total.harmean':'Середнє гармонійне',
35716
+ 'total.sumSquares':'Сума квадратів',
35717
+ 'total.weightedAvg':'Зважене середнє',
35718
+ 'total.argmin':'Найменше за',
35719
+ 'total.argmax':'Найбільше за',
35720
+ 'total.hhi':'Концентрація (HHI)',
35721
+ 'total.entropy':'Ентропія',
35722
+ 'total.evenness':'Рівномірність',
35723
+ 'total.top3Share':'Частка топ-3',
35724
+ 'total.top10Share':'Частка топ-10',
35725
+ 'total.gini':'Коефіцієнт Джині',
35726
+ 'total.trimmedMean':'Зрізане середнє',
35727
+ 'total.winsorizedMean':'Вінзоризоване середнє',
35728
+ 'total.robustOutliers':'Викиди (стійкі)',
35729
+ 'total.jarqueBera':'Жарк–Бера',
33879
35730
  'stats.column':'Стовпець',
33880
35731
  'stats.choose':'Виберіть стовпець для аналізу',
33881
35732
  'stats.noColumns':'Немає числових стовпців для аналізу',
@@ -33895,6 +35746,15 @@ other:'оновлено {count} комірок',
33895
35746
  'stats.outliers':'Викиди',
33896
35747
  'stats.distribution':'Розподіл',
33897
35748
  'stats.bin':'{count} між {from} і {to}',
35749
+ 'stats.section.shape':'Форма',
35750
+ 'stats.section.robust':'Стійкі',
35751
+ 'stats.section.concentration':'Концентрація',
35752
+ 'stats.section.capability':'Придатність',
35753
+ 'stats.cp':'Cp',
35754
+ 'stats.cpk':'Cpk',
35755
+ 'stats.pp':'Pp',
35756
+ 'stats.ppk':'Ppk',
35757
+ 'stats.outOfSpec':'Поза специфікацією',
33898
35758
  'stats.filtered':'З {count} відфільтрованих рядків',
33899
35759
  'panel.zone.group':'групувань рядків',
33900
35760
  'panel.zone.values':'значень',
@@ -34303,6 +36163,62 @@ other:'ενημερώθηκαν {count} κελιά',
34303
36163
  'panel.quickFilter':'Γρήγορο φίλτρο',
34304
36164
  'panel.formatting':'Μορφοποίηση',
34305
36165
  'panel.statistics':'Στατιστικά',
36166
+ 'panel.compare':'Σύγκριση',
36167
+ 'compare.first':'Πρώτη στήλη',
36168
+ 'compare.second':'Δεύτερη στήλη',
36169
+ 'compare.needTwo':'Χρειάζονται δύο αριθμητικές στήλες',
36170
+ 'compare.noPairs':'Καμία γραμμή δεν έχει τιμή και στις δύο',
36171
+ 'compare.pairs':'{count} ζεύγη',
36172
+ 'compare.pearson':'Συσχέτιση (Pearson)',
36173
+ 'compare.spearman':'Συσχέτιση τάξης (Spearman)',
36174
+ 'compare.kendall':'Tau του Kendall',
36175
+ 'compare.covariance':'Συνδιακύμανση',
36176
+ 'compare.slope':'Κλίση',
36177
+ 'compare.intercept':'Τεταγμένη',
36178
+ 'compare.r2':'R²',
36179
+ 'compare.stdError':'Τυπικό σφάλμα',
36180
+ 'compare.weighted':'Σταθμισμένος μέσος',
36181
+ 'total.sum':'Άθροισμα',
36182
+ 'total.avg':'Μέσος όρος',
36183
+ 'total.min':'Ελάχιστο',
36184
+ 'total.max':'Μέγιστο',
36185
+ 'total.count':'Πλήθος',
36186
+ 'total.countValues':'Πλήθος τιμών',
36187
+ 'total.first':'Πρώτο',
36188
+ 'total.last':'Τελευταίο',
36189
+ 'total.median':'Διάμεσος',
36190
+ 'total.p25':'25ο εκατοστημόριο',
36191
+ 'total.p75':'75ο εκατοστημόριο',
36192
+ 'total.p90':'90ό εκατοστημόριο',
36193
+ 'total.p95':'95ο εκατοστημόριο',
36194
+ 'total.p99':'99ο εκατοστημόριο',
36195
+ 'total.iqr':'Ενδοτεταρτημοριακό εύρος',
36196
+ 'total.mad':'Διάμεση απόλυτη απόκλιση',
36197
+ 'total.variance':'Διακύμανση',
36198
+ 'total.varianceP':'Διακύμανση (πληθυσμού)',
36199
+ 'total.stddev':'Τυπική απόκλιση',
36200
+ 'total.stddevP':'Τυπική απόκλιση (πληθυσμού)',
36201
+ 'total.range':'Εύρος',
36202
+ 'total.distinct':'Διακριτές',
36203
+ 'total.mode':'Επικρατούσα τιμή',
36204
+ 'total.skewness':'Ασυμμετρία',
36205
+ 'total.kurtosis':'Κύρτωση',
36206
+ 'total.geomean':'Γεωμετρικός μέσος',
36207
+ 'total.harmean':'Αρμονικός μέσος',
36208
+ 'total.sumSquares':'Άθροισμα τετραγώνων',
36209
+ 'total.weightedAvg':'Σταθμισμένος μέσος',
36210
+ 'total.argmin':'Χαμηλότερο κατά',
36211
+ 'total.argmax':'Υψηλότερο κατά',
36212
+ 'total.hhi':'Συγκέντρωση (HHI)',
36213
+ 'total.entropy':'Εντροπία',
36214
+ 'total.evenness':'Ομοιομορφία',
36215
+ 'total.top3Share':'Μερίδιο top 3',
36216
+ 'total.top10Share':'Μερίδιο top 10',
36217
+ 'total.gini':'Συντελεστής Gini',
36218
+ 'total.trimmedMean':'Περικομμένος μέσος',
36219
+ 'total.winsorizedMean':'Winsorized μέσος',
36220
+ 'total.robustOutliers':'Ακραίες τιμές (ανθεκτικό)',
36221
+ 'total.jarqueBera':'Jarque–Bera',
34306
36222
  'stats.column':'Στήλη',
34307
36223
  'stats.choose':'Επιλέξτε στήλη για ανάλυση',
34308
36224
  'stats.noColumns':'Δεν υπάρχουν αριθμητικές στήλες για ανάλυση',
@@ -34322,6 +36238,15 @@ other:'ενημερώθηκαν {count} κελιά',
34322
36238
  'stats.outliers':'Ακραίες τιμές',
34323
36239
  'stats.distribution':'Κατανομή',
34324
36240
  'stats.bin':'{count} μεταξύ {from} και {to}',
36241
+ 'stats.section.shape':'Σχήμα',
36242
+ 'stats.section.robust':'Ανθεκτικά',
36243
+ 'stats.section.concentration':'Συγκέντρωση',
36244
+ 'stats.section.capability':'Ικανότητα',
36245
+ 'stats.cp':'Cp',
36246
+ 'stats.cpk':'Cpk',
36247
+ 'stats.pp':'Pp',
36248
+ 'stats.ppk':'Ppk',
36249
+ 'stats.outOfSpec':'Εκτός προδιαγραφής',
34325
36250
  'stats.filtered':'Από {count} φιλτραρισμένες γραμμές',
34326
36251
  'panel.zone.group':'τις ομαδοποιήσεις γραμμών',
34327
36252
  'panel.zone.values':'τις τιμές',
@@ -34714,6 +36639,62 @@ other:'{count} セルを更新しました',
34714
36639
  'panel.quickFilter':'クイックフィルター',
34715
36640
  'panel.formatting':'書式',
34716
36641
  'panel.statistics':'統計',
36642
+ 'panel.compare':'比較',
36643
+ 'compare.first':'1つ目の列',
36644
+ 'compare.second':'2つ目の列',
36645
+ 'compare.needTwo':'比較には数値列が2つ必要です',
36646
+ 'compare.noPairs':'両方に値のある行がありません',
36647
+ 'compare.pairs':'{count} 組',
36648
+ 'compare.pearson':'相関(ピアソン)',
36649
+ 'compare.spearman':'順位相関(スピアマン)',
36650
+ 'compare.kendall':'ケンドールのタウ',
36651
+ 'compare.covariance':'共分散',
36652
+ 'compare.slope':'傾き',
36653
+ 'compare.intercept':'切片',
36654
+ 'compare.r2':'R²',
36655
+ 'compare.stdError':'標準誤差',
36656
+ 'compare.weighted':'加重平均',
36657
+ 'total.sum':'合計',
36658
+ 'total.avg':'平均',
36659
+ 'total.min':'最小',
36660
+ 'total.max':'最大',
36661
+ 'total.count':'件数',
36662
+ 'total.countValues':'値の件数',
36663
+ 'total.first':'最初',
36664
+ 'total.last':'最後',
36665
+ 'total.median':'中央値',
36666
+ 'total.p25':'第25パーセンタイル',
36667
+ 'total.p75':'第75パーセンタイル',
36668
+ 'total.p90':'第90パーセンタイル',
36669
+ 'total.p95':'第95パーセンタイル',
36670
+ 'total.p99':'第99パーセンタイル',
36671
+ 'total.iqr':'四分位範囲',
36672
+ 'total.mad':'中央絶対偏差',
36673
+ 'total.variance':'分散',
36674
+ 'total.varianceP':'分散(母集団)',
36675
+ 'total.stddev':'標準偏差',
36676
+ 'total.stddevP':'標準偏差(母集団)',
36677
+ 'total.range':'範囲',
36678
+ 'total.distinct':'一意の値',
36679
+ 'total.mode':'最頻値',
36680
+ 'total.skewness':'歪度',
36681
+ 'total.kurtosis':'尖度',
36682
+ 'total.geomean':'幾何平均',
36683
+ 'total.harmean':'調和平均',
36684
+ 'total.sumSquares':'平方和',
36685
+ 'total.weightedAvg':'加重平均',
36686
+ 'total.argmin':'最小(基準列)',
36687
+ 'total.argmax':'最大(基準列)',
36688
+ 'total.hhi':'集中度(HHI)',
36689
+ 'total.entropy':'エントロピー',
36690
+ 'total.evenness':'均等度',
36691
+ 'total.top3Share':'上位3件の割合',
36692
+ 'total.top10Share':'上位10件の割合',
36693
+ 'total.gini':'ジニ係数',
36694
+ 'total.trimmedMean':'トリム平均',
36695
+ 'total.winsorizedMean':'ウィンザー化平均',
36696
+ 'total.robustOutliers':'外れ値(頑健)',
36697
+ 'total.jarqueBera':'ジャック–ベラ',
34717
36698
  'stats.column':'列',
34718
36699
  'stats.choose':'分析する列を選択',
34719
36700
  'stats.noColumns':'分析できる数値列がありません',
@@ -34733,6 +36714,15 @@ other:'{count} セルを更新しました',
34733
36714
  'stats.outliers':'外れ値',
34734
36715
  'stats.distribution':'分布',
34735
36716
  'stats.bin':'{from}~{to} に {count} 件',
36717
+ 'stats.section.shape':'形状',
36718
+ 'stats.section.robust':'頑健',
36719
+ 'stats.section.concentration':'集中度',
36720
+ 'stats.section.capability':'工程能力',
36721
+ 'stats.cp':'Cp',
36722
+ 'stats.cpk':'Cpk',
36723
+ 'stats.pp':'Pp',
36724
+ 'stats.ppk':'Ppk',
36725
+ 'stats.outOfSpec':'規格外',
34736
36726
  'stats.filtered':'フィルター後の {count} 行が対象',
34737
36727
  'panel.zone.group':'行グループ',
34738
36728
  'panel.zone.values':'値',
@@ -35166,6 +37156,62 @@ other:'تم تحديث {count} خلية',
35166
37156
  'panel.quickFilter':'تصفية سريعة',
35167
37157
  'panel.formatting':'التنسيق',
35168
37158
  'panel.statistics':'الإحصاءات',
37159
+ 'panel.compare':'قارن',
37160
+ 'compare.first':'العمود الأول',
37161
+ 'compare.second':'العمود الثاني',
37162
+ 'compare.needTwo':'يلزم عمودان رقميان للمقارنة',
37163
+ 'compare.noPairs':'لا توجد صفوف بقيمة في كليهما',
37164
+ 'compare.pairs':'{count} زوجًا',
37165
+ 'compare.pearson':'الارتباط (بيرسون)',
37166
+ 'compare.spearman':'ارتباط الرتب (سبيرمان)',
37167
+ 'compare.kendall':'تاو كندال',
37168
+ 'compare.covariance':'التغاير',
37169
+ 'compare.slope':'الميل',
37170
+ 'compare.intercept':'التقاطع',
37171
+ 'compare.r2':'R²',
37172
+ 'compare.stdError':'الخطأ المعياري',
37173
+ 'compare.weighted':'المتوسط المرجح',
37174
+ 'total.sum':'المجموع',
37175
+ 'total.avg':'المتوسط',
37176
+ 'total.min':'الأدنى',
37177
+ 'total.max':'الأعلى',
37178
+ 'total.count':'العدد',
37179
+ 'total.countValues':'عدد القيم',
37180
+ 'total.first':'الأول',
37181
+ 'total.last':'الأخير',
37182
+ 'total.median':'الوسيط',
37183
+ 'total.p25':'المئين 25',
37184
+ 'total.p75':'المئين 75',
37185
+ 'total.p90':'المئين 90',
37186
+ 'total.p95':'المئين 95',
37187
+ 'total.p99':'المئين 99',
37188
+ 'total.iqr':'المدى الربيعي',
37189
+ 'total.mad':'الانحراف المطلق الوسيط',
37190
+ 'total.variance':'التباين',
37191
+ 'total.varianceP':'التباين (المجتمع)',
37192
+ 'total.stddev':'الانحراف المعياري',
37193
+ 'total.stddevP':'الانحراف المعياري (المجتمع)',
37194
+ 'total.range':'المدى',
37195
+ 'total.distinct':'القيم المميزة',
37196
+ 'total.mode':'المنوال',
37197
+ 'total.skewness':'الالتواء',
37198
+ 'total.kurtosis':'التفلطح',
37199
+ 'total.geomean':'المتوسط الهندسي',
37200
+ 'total.harmean':'المتوسط التوافقي',
37201
+ 'total.sumSquares':'مجموع المربعات',
37202
+ 'total.weightedAvg':'المتوسط المرجح',
37203
+ 'total.argmin':'الأدنى حسب',
37204
+ 'total.argmax':'الأعلى حسب',
37205
+ 'total.hhi':'التركز (HHI)',
37206
+ 'total.entropy':'الإنتروبيا',
37207
+ 'total.evenness':'التجانس',
37208
+ 'total.top3Share':'حصة أعلى 3',
37209
+ 'total.top10Share':'حصة أعلى 10',
37210
+ 'total.gini':'معامل جيني',
37211
+ 'total.trimmedMean':'المتوسط المشذب',
37212
+ 'total.winsorizedMean':'المتوسط الوينزوري',
37213
+ 'total.robustOutliers':'القيم الشاذة (حصينة)',
37214
+ 'total.jarqueBera':'جارك–بيرا',
35169
37215
  'stats.column':'العمود',
35170
37216
  'stats.choose':'اختر عمودًا لتحليله',
35171
37217
  'stats.noColumns':'لا توجد أعمدة رقمية للتحليل',
@@ -35185,6 +37231,15 @@ other:'تم تحديث {count} خلية',
35185
37231
  'stats.outliers':'القيم الشاذة',
35186
37232
  'stats.distribution':'التوزيع',
35187
37233
  'stats.bin':'{count} بين {from} و {to}',
37234
+ 'stats.section.shape':'الشكل',
37235
+ 'stats.section.robust':'حصين',
37236
+ 'stats.section.concentration':'التركز',
37237
+ 'stats.section.capability':'القدرة',
37238
+ 'stats.cp':'Cp',
37239
+ 'stats.cpk':'Cpk',
37240
+ 'stats.pp':'Pp',
37241
+ 'stats.ppk':'Ppk',
37242
+ 'stats.outOfSpec':'خارج المواصفة',
35188
37243
  'stats.filtered':'من بين {count} صفًا بعد التصفية',
35189
37244
  'panel.zone.group':'تجميعات الصفوف',
35190
37245
  'panel.zone.values':'القيم',
@@ -53607,6 +55662,20 @@ const FIGURES=Object.freeze([
53607
55662
  {key:'stddev',label:'stats.stddev',kind:'value'},
53608
55663
  {key:'outliers',label:'stats.outliers',kind:'count'},
53609
55664
  ]);
55665
+ const SECTIONS=Object.freeze([
55666
+ {
55667
+ label:'stats.section.shape',
55668
+ kernels:['skewness','kurtosis','jarqueBera'],
55669
+ },
55670
+ {
55671
+ label:'stats.section.robust',
55672
+ kernels:['trimmedMean','winsorizedMean','mad','robustOutliers'],
55673
+ },
55674
+ {
55675
+ label:'stats.section.concentration',
55676
+ kernels:['gini','hhi','entropy','evenness','top3Share'],
55677
+ },
55678
+ ]);
53610
55679
  function readable(value){
53611
55680
  if(value===null||value===undefined||!Number.isFinite(value))return'—';
53612
55681
  if(Number.isInteger(value))return String(value);
@@ -53648,6 +55717,12 @@ class:`${CLS.panel}__count`,
53648
55717
  text:this.t('stats.filtered',{count:profile.rows}),
53649
55718
  }));
53650
55719
  root.appendChild(this.#figures(profile));
55720
+ for(const section of SECTIONS){
55721
+ const rendered=this.#section(section);
55722
+ if(rendered)root.appendChild(rendered);
55723
+ }
55724
+ const capability=this.#capability();
55725
+ if(capability)root.appendChild(capability);
53651
55726
  if(profile.histogram&&profile.histogram.length>1){
53652
55727
  root.appendChild(this.#histogram(profile.histogram));
53653
55728
  }
@@ -53677,6 +55752,60 @@ select,
53677
55752
  ],
53678
55753
  });
53679
55754
  }
55755
+ #section(section){
55756
+ const reduce=this.host.reduceColumn;
55757
+ if(!isFunction(reduce)||!this.column)return null;
55758
+ const rows=[];
55759
+ for(const kernel of section.kernels){
55760
+ const value=reduce(this.column,kernel);
55761
+ if(value===null||value===undefined||Number.isNaN(value))continue;
55762
+ rows.push([kernel,value]);
55763
+ }
55764
+ if(!rows.length)return null;
55765
+ const wrapper=this.doc.createElement('div');
55766
+ wrapper.appendChild(el(this.doc,'h4',{
55767
+ class:`${CLS.panel}__subtitle`,text:this.t(section.label),
55768
+ }));
55769
+ const list=el(this.doc,'dl',{class:`${CLS.panel}__stats`});
55770
+ for(const[kernel,value]of rows){
55771
+ list.appendChild(el(this.doc,'dt',{
55772
+ class:`${CLS.panel}__stat-name`,
55773
+ text:this.t(`total.${kernel}`),
55774
+ }));
55775
+ list.appendChild(el(this.doc,'dd',{
55776
+ class:`${CLS.panel}__stat-value`,
55777
+ text:typeof value==='number'?readable(value):String(value),
55778
+ }));
55779
+ }
55780
+ wrapper.appendChild(list);
55781
+ return wrapper;
55782
+ }
55783
+ #capability(){
55784
+ const read=this.host.columnCapability;
55785
+ if(!isFunction(read)||!this.column)return null;
55786
+ const c=read(this.column);
55787
+ if(!c)return null;
55788
+ const wrapper=this.doc.createElement('div');
55789
+ wrapper.appendChild(el(this.doc,'h4',{
55790
+ class:`${CLS.panel}__subtitle`,text:this.t('stats.section.capability'),
55791
+ }));
55792
+ const list=el(this.doc,'dl',{class:`${CLS.panel}__stats`});
55793
+ const pairs=[
55794
+ ['stats.cp',c.cp],['stats.cpk',c.cpk],['stats.pp',c.pp],['stats.ppk',c.ppk],
55795
+ ['stats.outOfSpec',c.outOfSpec],
55796
+ ];
55797
+ for(const[key,value]of pairs){
55798
+ if(value===null||value===undefined)continue;
55799
+ list.appendChild(el(this.doc,'dt',{
55800
+ class:`${CLS.panel}__stat-name`,text:this.t(key),
55801
+ }));
55802
+ list.appendChild(el(this.doc,'dd',{
55803
+ class:`${CLS.panel}__stat-value`,text:readable(value),
55804
+ }));
55805
+ }
55806
+ wrapper.appendChild(list);
55807
+ return wrapper;
55808
+ }
53680
55809
  #figures(profile){
53681
55810
  const list=el(this.doc,'dl',{class:`${CLS.panel}__stats`});
53682
55811
  for(const figure of FIGURES){
@@ -53716,6 +55845,122 @@ return chart;
53716
55845
  }
53717
55846
  }
53718
55847
  });
55848
+ __def("packages/dom/src/comparepanel.js",function(__exports,__req){
55849
+ 'use strict';
55850
+ Object.defineProperty(__exports,"ComparePanel",{enumerable:true,get:function(){return ComparePanel;}});
55851
+ const __m0=__req("packages/dom/src/editors/common.js");
55852
+ const CLS=__m0["CLS"];
55853
+ const el=__m0["el"];
55854
+ const on=__m0["on"];
55855
+ const clear=__m0["clear"];
55856
+ const __m1=__req("packages/core/src/internal/util.js");
55857
+ const isFunction=__m1["isFunction"];
55858
+ const __m2=__req("packages/dom/src/ui/panelbase.js");
55859
+ const ToolPanelBase=__m2["ToolPanelBase"];
55860
+ const FIGURES=Object.freeze([
55861
+ {key:'pearson',label:'compare.pearson'},
55862
+ {key:'spearman',label:'compare.spearman'},
55863
+ {key:'kendall',label:'compare.kendall'},
55864
+ {key:'slope',label:'compare.slope'},
55865
+ {key:'intercept',label:'compare.intercept'},
55866
+ {key:'r2',label:'compare.r2'},
55867
+ {key:'stdError',label:'compare.stdError'},
55868
+ {key:'covariance',label:'compare.covariance'},
55869
+ {key:'weighted',label:'compare.weighted'},
55870
+ ]);
55871
+ function readable(value){
55872
+ if(value===null||value===undefined||!Number.isFinite(value))return'—';
55873
+ if(Number.isInteger(value))return String(value);
55874
+ const magnitude=Math.abs(value);
55875
+ if(magnitude!==0&&(magnitude<0.001||magnitude>=1e7))return value.toExponential(2);
55876
+ return String(Number(value.toPrecision(4)));
55877
+ }
55878
+ class ComparePanel extends ToolPanelBase{
55879
+ first=null;
55880
+ second=null;
55881
+ #columns(){
55882
+ return isFunction(this.host.profilableColumns)?this.host.profilableColumns():[];
55883
+ }
55884
+ refresh(){
55885
+ const root=this.root;
55886
+ if(!root)return;
55887
+ for(const off of this.off)off();
55888
+ this.off.length=0;
55889
+ clear(root);
55890
+ const columns=this.#columns();
55891
+ if(columns.length<2){
55892
+ root.appendChild(el(this.doc,'p',{
55893
+ class:`${CLS.panel}__empty`,text:this.t('compare.needTwo'),
55894
+ }));
55895
+ return;
55896
+ }
55897
+ if(!columns.some((c)=>c.id===this.first))this.first=columns[0].id;
55898
+ if(!columns.some((c)=>c.id===this.second)||this.second===this.first){
55899
+ this.second=(columns.find((c)=>c.id!==this.first)||columns[0]).id;
55900
+ }
55901
+ root.appendChild(this.#picker('compare.first',columns,this.first,(id)=>{
55902
+ this.first=id;
55903
+ if(this.second===id){
55904
+ this.second=(columns.find((c)=>c.id!==id)||columns[0]).id;
55905
+ }
55906
+ this.refresh();
55907
+ }));
55908
+ root.appendChild(this.#picker('compare.second',columns,this.second,(id)=>{
55909
+ this.second=id;
55910
+ if(this.first===id){
55911
+ this.first=(columns.find((c)=>c.id!==id)||columns[0]).id;
55912
+ }
55913
+ this.refresh();
55914
+ }));
55915
+ const figures=isFunction(this.host.compareColumns)
55916
+ ?this.host.compareColumns(this.first,this.second)
55917
+ :null;
55918
+ if(!figures||!figures.n){
55919
+ root.appendChild(el(this.doc,'p',{
55920
+ class:`${CLS.panel}__empty`,text:this.t('compare.noPairs'),
55921
+ }));
55922
+ return;
55923
+ }
55924
+ root.appendChild(el(this.doc,'p',{
55925
+ class:`${CLS.panel}__count`,
55926
+ text:this.t('compare.pairs',{count:figures.n}),
55927
+ }));
55928
+ const list=el(this.doc,'dl',{class:`${CLS.panel}__stats`});
55929
+ for(const figure of FIGURES){
55930
+ const value=figures[figure.key];
55931
+ if(value===null||value===undefined)continue;
55932
+ list.appendChild(el(this.doc,'dt',{
55933
+ class:`${CLS.panel}__stat-name`,text:this.t(figure.label),
55934
+ }));
55935
+ list.appendChild(el(this.doc,'dd',{
55936
+ class:`${CLS.panel}__stat-value`,text:readable(value),
55937
+ }));
55938
+ }
55939
+ root.appendChild(list);
55940
+ }
55941
+ #picker(label,columns,current,choose){
55942
+ const select=el(this.doc,'select',{
55943
+ class:`${CLS.panel}__select`,
55944
+ attrs:{'aria-label':this.t(label)},
55945
+ });
55946
+ for(const column of columns){
55947
+ select.appendChild(el(this.doc,'option',{
55948
+ text:column.title,
55949
+ attrs:{value:column.id,selected:column.id===current?true:null},
55950
+ }));
55951
+ }
55952
+ (select).value=current;
55953
+ this.off.push(on(select,'change',()=>choose((select).value)));
55954
+ return el(this.doc,'label',{
55955
+ class:`${CLS.panel}__field`,
55956
+ children:[
55957
+ el(this.doc,'span',{class:`${CLS.panel}__label`,text:this.t(label)}),
55958
+ select,
55959
+ ],
55960
+ });
55961
+ }
55962
+ }
55963
+ });
53719
55964
  __def("packages/dom/src/ui/toolpanel.js",function(__exports,__req){
53720
55965
  'use strict';
53721
55966
  Object.defineProperty(__exports,"ColumnsPanel",{enumerable:true,get:function(){return ColumnsPanel;}});
@@ -53748,10 +55993,12 @@ const __m5=__req("packages/dom/src/formattingpanel.js");
53748
55993
  const FormattingPanel=__m5["FormattingPanel"];
53749
55994
  const __m6=__req("packages/dom/src/statisticspanel.js");
53750
55995
  const StatisticsPanel=__m6["StatisticsPanel"];
53751
- const __m7=__req("packages/dom/src/ui/panelbase.js");
53752
- const ToolPanelBase=__m7["ToolPanelBase"];
53753
- const __m8=__req("packages/core/src/compute/total.js");
53754
- const TOTAL_LABELS=__m8["TOTAL_LABELS"];
55996
+ const __m7=__req("packages/dom/src/comparepanel.js");
55997
+ const ComparePanel=__m7["ComparePanel"];
55998
+ const __m8=__req("packages/dom/src/ui/panelbase.js");
55999
+ const ToolPanelBase=__m8["ToolPanelBase"];
56000
+ const __m9=__req("packages/core/src/compute/total.js");
56001
+ const TOTAL_LABELS=__m9["TOTAL_LABELS"];
53755
56002
  class ColumnsPanel extends ToolPanelBase{
53756
56003
  dragging=null;
53757
56004
  refresh(){
@@ -53949,7 +56196,7 @@ attrs:{'aria-label':`Calculation for ${this.titleOf(id)}`},
53949
56196
  });
53950
56197
  for(const fn of ColumnsPanel.aggregations){
53951
56198
  select.appendChild(el(this.doc,'option',{
53952
- text:fn.label,
56199
+ text:this.t(`total.${fn.name}`),
53953
56200
  attrs:{value:fn.name,selected:fn.name===current?'':null},
53954
56201
  }));
53955
56202
  }
@@ -53979,7 +56226,7 @@ zone.appendChild(body);
53979
56226
  return zone;
53980
56227
  }
53981
56228
  static aggregations=Object.freeze(
53982
- Object.entries(TOTAL_LABELS).map(([name,label])=>({name,label})),
56229
+ Object.keys(TOTAL_LABELS).map((name)=>({name})),
53983
56230
  );
53984
56231
  static zoneAbout=Object.freeze({
53985
56232
  group:'Rows are grouped by these columns, in order.',
@@ -54241,6 +56488,7 @@ views:ViewPicker,
54241
56488
  quick:QuickFilterPanel,
54242
56489
  formatting:FormattingPanel,
54243
56490
  statistics:StatisticsPanel,
56491
+ compare:ComparePanel,
54244
56492
  });
54245
56493
  const toolPanelTitles=Object.freeze({
54246
56494
  columns:'panel.columns',
@@ -54249,6 +56497,7 @@ views:'panel.views',
54249
56497
  quick:'panel.quickFilter',
54250
56498
  formatting:'panel.formatting',
54251
56499
  statistics:'panel.statistics',
56500
+ compare:'panel.compare',
54252
56501
  });
54253
56502
  const toolPanelIcons=Object.freeze({
54254
56503
  columns:'columns',
@@ -54257,6 +56506,7 @@ views:'views',
54257
56506
  quick:'search',
54258
56507
  formatting:'palette',
54259
56508
  statistics:'chart',
56509
+ compare:'link',
54260
56510
  });
54261
56511
  class ToolPanel{
54262
56512
  panels=[];
@@ -56649,6 +58899,7 @@ this.#row=null;
56649
58899
  });
56650
58900
  __def("packages/dom/src/toolpanelmount.js",function(__exports,__req){
56651
58901
  'use strict';
58902
+ Object.defineProperty(__exports,"mountPanel",{enumerable:true,get:function(){return mountPanel;}});
56652
58903
  Object.defineProperty(__exports,"panelHost",{enumerable:true,get:function(){return panelHost;}});
56653
58904
  Object.defineProperty(__exports,"ToolPanelDock",{enumerable:true,get:function(){return ToolPanelDock;}});
56654
58905
  const __m0=__req("packages/core/src/internal/util.js");
@@ -56663,10 +58914,48 @@ const __m2=__req("packages/dom/src/filters/index.js");
56663
58914
  const createFilter=__m2["createFilter"];
56664
58915
  const __m3=__req("packages/dom/src/editors/common.js");
56665
58916
  const CLS=__m3["CLS"];
58917
+ const documentFor=__m3["documentFor"];
56666
58918
  const scannableRows=__m3["scannableRows"];
56667
58919
  const __m4=__req("packages/dom/src/filtermenu.js");
56668
58920
  const mergeColumnFilter=__m4["mergeColumnFilter"];
56669
58921
  const branchFor=__m4["branchFor"];
58922
+ const REPAINT_ON=Object.freeze([
58923
+ 'column:visible','column:moved','column:pinned',
58924
+ 'column:grouped','column:pivoted','filter:changed','model:changed',
58925
+ 'views:changed','sort:changed','history:changed','state:reset',
58926
+ 'cell:changed','formatting:changed',
58927
+ ]);
58928
+ function mountPanel(opts){
58929
+ const{grid,container}=opts||{};
58930
+ if(!grid)throw new Error('[lattice] mountPanel needs a grid');
58931
+ if(!container||!container.appendChild){
58932
+ throw new Error('[lattice] mountPanel needs a container element');
58933
+ }
58934
+ const Ctor=isFunction(opts.panel)?opts.panel:toolPanels[String(opts.panel)];
58935
+ if(!Ctor){
58936
+ throw new Error(`[lattice] unknown panel "${opts.panel}"; known panels are ${Object.keys(toolPanels).join(', ')}`);
58937
+ }
58938
+ const doc=container.ownerDocument||documentFor(container);
58939
+ const host=panelHost(grid,doc,opts.announce);
58940
+ const panel=new Ctor();
58941
+ panel.init({document:doc,host,grid,props:opts.props||{}});
58942
+ const element=panel.element();
58943
+ container.appendChild(element);
58944
+ const off=[];
58945
+ for(const event of REPAINT_ON){
58946
+ if(isFunction(grid.on))off.push(grid.on(event,()=>panel.refresh()));
58947
+ }
58948
+ return{
58949
+ element,
58950
+ refresh(){panel.refresh();},
58951
+ destroy(){
58952
+ for(const stop of off)stop();
58953
+ off.length=0;
58954
+ if(isFunction(panel.destroy))panel.destroy();
58955
+ if(element&&element.parentNode)element.parentNode.removeChild(element);
58956
+ },
58957
+ };
58958
+ }
56670
58959
  const PANEL_WIDTH=260;
56671
58960
  const RAIL_WIDTH=30;
56672
58961
  const DOCK_CLASS=`${CLS.panel}-dock`;
@@ -56732,6 +59021,24 @@ profilableColumns:()=>grid.columns.visible()
56732
59021
  ||c.type==='percent'||c.type==='integer'))
56733
59022
  .map((c)=>({id:c.id,title:String(c.title??c.id)})),
56734
59023
  columnProfile:(colId)=>grid.statistics.profile(colId),
59024
+ reduceColumn:(colId,kernel)=>grid.statistics.reduce(colId,kernel),
59025
+ columnCapability:(colId)=>grid.statistics.capability(colId),
59026
+ compareColumns:(a,b)=>{
59027
+ if(!a||!b||a===b)return null;
59028
+ const fit=grid.statistics.regression(a,b);
59029
+ return{
59030
+ n:fit?fit.n:0,
59031
+ pearson:grid.statistics.correlation(a,b),
59032
+ spearman:grid.statistics.spearman(a,b),
59033
+ kendall:grid.statistics.kendall(a,b),
59034
+ covariance:grid.statistics.covariance(a,b),
59035
+ slope:fit?fit.slope:null,
59036
+ intercept:fit?fit.intercept:null,
59037
+ r2:fit?fit.r2:null,
59038
+ stdError:fit?fit.stdError:null,
59039
+ weighted:grid.statistics.weightedAverage(a,b),
59040
+ };
59041
+ },
56735
59042
  addRule:(scope,rule)=>grid.formatting.add(scope,rule),
56736
59043
  removeRule:(scope,id)=>grid.formatting.remove(scope,id),
56737
59044
  updateRule:(scope,id,patch)=>grid.formatting.update(scope,id,patch),
@@ -56864,10 +59171,7 @@ const show=this.#panel.show.bind(this.#panel);
56864
59171
  const hide=this.#panel.hide.bind(this.#panel);
56865
59172
  this.#panel.show=(name)=>{const ok=show(name);this.#applyWidth();return ok;};
56866
59173
  this.#panel.hide=()=>{hide();this.#applyWidth();};
56867
- for(const event of['column:visible','column:moved','column:pinned',
56868
- 'column:grouped','column:pivoted','filter:changed','model:changed',
56869
- 'views:changed','sort:changed','history:changed','state:reset',
56870
- 'cell:changed','formatting:changed',
59174
+ for(const event of[...REPAINT_ON,
56871
59175
  'rows:paused','rows:resumed','rows:queued']){
56872
59176
  this.#off.push(this.#grid.on(event,()=>this.#panel.refresh()));
56873
59177
  }
@@ -60828,6 +63132,7 @@ Object.defineProperty(__exports,"layoutState",{enumerable:true,get:function(){re
60828
63132
  const __m9=__req("packages/dom/src/toolpanelmount.js");
60829
63133
  Object.defineProperty(__exports,"ToolPanelDock",{enumerable:true,get:function(){return __m9["ToolPanelDock"];}});
60830
63134
  Object.defineProperty(__exports,"panelHost",{enumerable:true,get:function(){return __m9["panelHost"];}});
63135
+ Object.defineProperty(__exports,"mountPanel",{enumerable:true,get:function(){return __m9["mountPanel"];}});
60831
63136
  const __m10=__req("packages/dom/src/celledit.js");
60832
63137
  Object.defineProperty(__exports,"CellEditController",{enumerable:true,get:function(){return __m10["CellEditController"];}});
60833
63138
  const __m11=__req("packages/dom/src/editbar.js");
@@ -60889,7 +63194,7 @@ createLocalViewStorage,
60889
63194
  const __default=LatticeGrid;
60890
63195
  });
60891
63196
  try{
60892
- __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 VERSION='1.8.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',\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/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 sortByComparator(handle,idx,opts){\nconst values=indexableValues(handle,idx);\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/statistics.js\",function(__exports,__req){\n'use strict';\nObject.defineProperty(__exports,\"MAINTENANCE\",{enumerable:true,get:function(){return MAINTENANCE;}});\nObject.defineProperty(__exports,\"numbers\",{enumerable:true,get:function(){return numbers;}});\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,\"countOutside\",{enumerable:true,get:function(){return countOutside;}});\nObject.defineProperty(__exports,\"histogram\",{enumerable:true,get:function(){return histogram;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst MAINTENANCE=Object.freeze({\nvariance:'maintained',\nvarianceP:'maintained',\nstddev:'maintained',\nstddevP:'maintained',\nsumSquares:'maintained',\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',\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 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({\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({\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 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}\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,\"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}\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\"];\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;\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}\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'});
63197
+ __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 VERSION='1.9.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',\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/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 sortByComparator(handle,idx,opts){\nconst values=indexableValues(handle,idx);\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/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,\"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,\"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;}});\nconst __m0=__req(\"packages/core/src/compute/handle.js\");\nconst presenceReader=__m0[\"presenceReader\"];\nconst valueReader=__m0[\"valueReader\"];\nconst KENDALL_LIMIT=5000;\nconst MAINTENANCE=Object.freeze({\nvariance:'maintained',\nvarianceP:'maintained',\nstddev:'maintained',\nstddevP:'maintained',\nsumSquares:'maintained',\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;\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 controlViolations(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 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}\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,\"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}\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\"];\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;\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}\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'});
60893
63198
  }catch(err){}
60894
63199
  const __entry=__req("packages/dom/src/index.js");
60895
63200
  export const
@@ -61014,6 +63319,7 @@ alignGrids=__entry.alignGrids,
61014
63319
  layoutState=__entry.layoutState,
61015
63320
  ToolPanelDock=__entry.ToolPanelDock,
61016
63321
  panelHost=__entry.panelHost,
63322
+ mountPanel=__entry.mountPanel,
61017
63323
  CellEditController=__entry.CellEditController,
61018
63324
  EditBar=__entry.EditBar,
61019
63325
  HistoryBar=__entry.HistoryBar,