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