@toclocoinc/lattice-grid 1.89.0 → 1.89.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +1 -1
- package/angular/package.json +1 -1
- package/docs/API.html +5 -5
- package/docs/THEMING.md +27 -0
- package/docs/api/adapters.html +1 -1
- package/docs/api/ai.html +1 -1
- package/docs/api/alarms.html +1 -1
- package/docs/api/calendar.html +1 -1
- package/docs/api/charts.html +1 -1
- package/docs/api/dashboard.html +1 -1
- package/docs/api/data-router.html +1 -1
- package/docs/api/deckgl.html +1 -1
- package/docs/api/designer.html +2 -2
- package/docs/api/gantt.html +1 -1
- package/docs/api/geometry.html +1 -1
- package/docs/api/grid.html +2 -2
- package/docs/api/index.html +1 -1
- package/docs/api/kanban.html +1 -1
- package/docs/api/kpi.html +1 -1
- package/docs/api/layout.html +1 -1
- package/docs/api/leaflet.html +1 -1
- package/docs/api/list.html +1 -1
- package/docs/api/mapview.html +1 -1
- package/docs/api/mock-socket.html +1 -1
- package/docs/api/presets.html +1 -1
- package/docs/api/tabs.html +1 -1
- package/docs/api/types.html +1 -1
- package/docs/api-detail.html +4 -4
- package/docs/warnings.json +1 -1
- package/lattice-grid.d.ts +1 -1
- package/lattice-grid.esm.min.js +3 -3
- package/lattice-grid.min.cjs +3 -3
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +3 -3
- package/modules/ai.d.ts +1 -1
- package/modules/ai.esm.min.js +2 -2
- package/modules/ai.min.cjs +2 -2
- package/modules/ai.min.js +2 -2
- package/modules/alarms.d.ts +1 -1
- package/modules/alarms.esm.min.js +2 -2
- package/modules/alarms.min.cjs +2 -2
- package/modules/alarms.min.js +2 -2
- package/modules/angular.d.ts +1 -1
- package/modules/angular.esm.min.js +2 -2
- package/modules/angular.min.cjs +2 -2
- package/modules/angular.min.js +2 -2
- package/modules/calendar.d.ts +1 -1
- package/modules/calendar.esm.min.js +2 -2
- package/modules/calendar.min.cjs +2 -2
- package/modules/calendar.min.js +2 -2
- package/modules/chart-alluvial.d.ts +1 -1
- package/modules/chart-alluvial.esm.min.js +1 -1
- package/modules/chart-alluvial.min.cjs +1 -1
- package/modules/chart-alluvial.min.js +1 -1
- package/modules/chart-arc.d.ts +1 -1
- package/modules/chart-arc.esm.min.js +1 -1
- package/modules/chart-arc.min.cjs +1 -1
- package/modules/chart-arc.min.js +1 -1
- package/modules/chart-barrace.d.ts +1 -1
- package/modules/chart-barrace.esm.min.js +1 -1
- package/modules/chart-barrace.min.cjs +1 -1
- package/modules/chart-barrace.min.js +1 -1
- package/modules/chart-bubblemap.d.ts +1 -1
- package/modules/chart-bubblemap.esm.min.js +1 -1
- package/modules/chart-bubblemap.min.cjs +1 -1
- package/modules/chart-bubblemap.min.js +1 -1
- package/modules/chart-bump.d.ts +1 -1
- package/modules/chart-bump.esm.min.js +1 -1
- package/modules/chart-bump.min.cjs +1 -1
- package/modules/chart-bump.min.js +1 -1
- package/modules/chart-calendar.d.ts +1 -1
- package/modules/chart-calendar.esm.min.js +1 -1
- package/modules/chart-calendar.min.cjs +1 -1
- package/modules/chart-calendar.min.js +1 -1
- package/modules/chart-choropleth.d.ts +1 -1
- package/modules/chart-choropleth.esm.min.js +1 -1
- package/modules/chart-choropleth.min.cjs +1 -1
- package/modules/chart-choropleth.min.js +1 -1
- package/modules/chart-decomposition.d.ts +1 -1
- package/modules/chart-decomposition.esm.min.js +1 -1
- package/modules/chart-decomposition.min.cjs +1 -1
- package/modules/chart-decomposition.min.js +1 -1
- package/modules/chart-diverging.d.ts +1 -1
- package/modules/chart-diverging.esm.min.js +1 -1
- package/modules/chart-diverging.min.cjs +1 -1
- package/modules/chart-diverging.min.js +1 -1
- package/modules/chart-dumbbell.d.ts +1 -1
- package/modules/chart-dumbbell.esm.min.js +1 -1
- package/modules/chart-dumbbell.min.cjs +1 -1
- package/modules/chart-dumbbell.min.js +1 -1
- package/modules/chart-fan.d.ts +1 -1
- package/modules/chart-fan.esm.min.js +1 -1
- package/modules/chart-fan.min.cjs +1 -1
- package/modules/chart-fan.min.js +1 -1
- package/modules/chart-forcetree.d.ts +1 -1
- package/modules/chart-forcetree.esm.min.js +1 -1
- package/modules/chart-forcetree.min.cjs +1 -1
- package/modules/chart-forcetree.min.js +1 -1
- package/modules/chart-hexbin.d.ts +1 -1
- package/modules/chart-hexbin.esm.min.js +1 -1
- package/modules/chart-hexbin.min.cjs +1 -1
- package/modules/chart-hexbin.min.js +1 -1
- package/modules/chart-hexmap.d.ts +1 -1
- package/modules/chart-hexmap.esm.min.js +1 -1
- package/modules/chart-hexmap.min.cjs +1 -1
- package/modules/chart-hexmap.min.js +1 -1
- package/modules/chart-icicle.d.ts +1 -1
- package/modules/chart-icicle.esm.min.js +1 -1
- package/modules/chart-icicle.min.cjs +1 -1
- package/modules/chart-icicle.min.js +1 -1
- package/modules/chart-markermap.d.ts +1 -1
- package/modules/chart-markermap.esm.min.js +1 -1
- package/modules/chart-markermap.min.cjs +1 -1
- package/modules/chart-markermap.min.js +1 -1
- package/modules/chart-motion.d.ts +1 -1
- package/modules/chart-motion.esm.min.js +1 -1
- package/modules/chart-motion.min.cjs +1 -1
- package/modules/chart-motion.min.js +1 -1
- package/modules/chart-pack.d.ts +1 -1
- package/modules/chart-pack.esm.min.js +1 -1
- package/modules/chart-pack.min.cjs +1 -1
- package/modules/chart-pack.min.js +1 -1
- package/modules/chart-parallel.d.ts +1 -1
- package/modules/chart-parallel.esm.min.js +1 -1
- package/modules/chart-parallel.min.cjs +1 -1
- package/modules/chart-parallel.min.js +1 -1
- package/modules/chart-pictorial.d.ts +1 -1
- package/modules/chart-pictorial.esm.min.js +1 -1
- package/modules/chart-pictorial.min.cjs +1 -1
- package/modules/chart-pictorial.min.js +1 -1
- package/modules/chart-polararea.d.ts +1 -1
- package/modules/chart-polararea.esm.min.js +1 -1
- package/modules/chart-polararea.min.cjs +1 -1
- package/modules/chart-polararea.min.js +1 -1
- package/modules/chart-polarscatter.d.ts +1 -1
- package/modules/chart-polarscatter.esm.min.js +1 -1
- package/modules/chart-polarscatter.min.cjs +1 -1
- package/modules/chart-polarscatter.min.js +1 -1
- package/modules/chart-pyramid.d.ts +1 -1
- package/modules/chart-pyramid.esm.min.js +1 -1
- package/modules/chart-pyramid.min.cjs +1 -1
- package/modules/chart-pyramid.min.js +1 -1
- package/modules/chart-radialbar.d.ts +1 -1
- package/modules/chart-radialbar.esm.min.js +1 -1
- package/modules/chart-radialbar.min.cjs +1 -1
- package/modules/chart-radialbar.min.js +1 -1
- package/modules/chart-ridgeline.d.ts +1 -1
- package/modules/chart-ridgeline.esm.min.js +1 -1
- package/modules/chart-ridgeline.min.cjs +1 -1
- package/modules/chart-ridgeline.min.js +1 -1
- package/modules/chart-roc.d.ts +1 -1
- package/modules/chart-roc.esm.min.js +1 -1
- package/modules/chart-roc.min.cjs +1 -1
- package/modules/chart-roc.min.js +1 -1
- package/modules/chart-serpentine.d.ts +1 -1
- package/modules/chart-serpentine.esm.min.js +1 -1
- package/modules/chart-serpentine.min.cjs +1 -1
- package/modules/chart-serpentine.min.js +1 -1
- package/modules/chart-slope.d.ts +1 -1
- package/modules/chart-slope.esm.min.js +1 -1
- package/modules/chart-slope.min.cjs +1 -1
- package/modules/chart-slope.min.js +1 -1
- package/modules/chart-spiral.d.ts +1 -1
- package/modules/chart-spiral.esm.min.js +1 -1
- package/modules/chart-spiral.min.cjs +1 -1
- package/modules/chart-spiral.min.js +1 -1
- package/modules/chart-splom.d.ts +1 -1
- package/modules/chart-splom.esm.min.js +1 -1
- package/modules/chart-splom.min.cjs +1 -1
- package/modules/chart-splom.min.js +1 -1
- package/modules/chart-tree.d.ts +1 -1
- package/modules/chart-tree.esm.min.js +1 -1
- package/modules/chart-tree.min.cjs +1 -1
- package/modules/chart-tree.min.js +1 -1
- package/modules/chart-venn.d.ts +1 -1
- package/modules/chart-venn.esm.min.js +1 -1
- package/modules/chart-venn.min.cjs +1 -1
- package/modules/chart-venn.min.js +1 -1
- package/modules/chart-voronoi.d.ts +1 -1
- package/modules/chart-voronoi.esm.min.js +1 -1
- package/modules/chart-voronoi.min.cjs +1 -1
- package/modules/chart-voronoi.min.js +1 -1
- package/modules/chart-waffle.d.ts +1 -1
- package/modules/chart-waffle.esm.min.js +1 -1
- package/modules/chart-waffle.min.cjs +1 -1
- package/modules/chart-waffle.min.js +1 -1
- package/modules/chart-wordcloud.d.ts +1 -1
- package/modules/chart-wordcloud.esm.min.js +1 -1
- package/modules/chart-wordcloud.min.cjs +1 -1
- package/modules/chart-wordcloud.min.js +1 -1
- package/modules/charts.d.ts +1 -1
- package/modules/charts.esm.min.js +2 -2
- package/modules/charts.min.cjs +2 -2
- package/modules/charts.min.js +2 -2
- package/modules/dashboard.d.ts +1 -1
- package/modules/dashboard.esm.min.js +2 -2
- package/modules/dashboard.min.cjs +2 -2
- package/modules/dashboard.min.js +2 -2
- package/modules/data-router.d.ts +1 -1
- package/modules/data-router.esm.min.js +2 -2
- package/modules/data-router.min.cjs +2 -2
- package/modules/data-router.min.js +2 -2
- package/modules/deckgl.d.ts +1 -1
- package/modules/deckgl.esm.min.js +2 -2
- package/modules/deckgl.min.cjs +2 -2
- package/modules/deckgl.min.js +2 -2
- package/modules/designer.d.ts +1 -1
- package/modules/designer.esm.min.js +187 -73
- package/modules/designer.esm.min.js.map +2 -2
- package/modules/designer.min.cjs +187 -73
- package/modules/designer.min.js +187 -73
- package/modules/designer.min.js.map +2 -2
- package/modules/devtools.d.ts +1 -1
- package/modules/devtools.esm.min.js +1 -1
- package/modules/devtools.min.cjs +1 -1
- package/modules/devtools.min.js +1 -1
- package/modules/dhtmlx-compat.d.ts +1 -1
- package/modules/dhtmlx-compat.esm.min.js +2 -2
- package/modules/dhtmlx-compat.min.cjs +2 -2
- package/modules/dhtmlx-compat.min.js +2 -2
- package/modules/gantt.d.ts +1 -1
- package/modules/gantt.esm.min.js +2 -2
- package/modules/gantt.min.cjs +2 -2
- package/modules/gantt.min.js +2 -2
- package/modules/geo-europe-nuts.d.ts +1 -1
- package/modules/geo-europe-nuts.esm.min.js +1 -1
- package/modules/geo-europe-nuts.min.cjs +1 -1
- package/modules/geo-europe-nuts.min.js +1 -1
- package/modules/geo-uk.d.ts +1 -1
- package/modules/geo-uk.esm.min.js +1 -1
- package/modules/geo-uk.min.cjs +1 -1
- package/modules/geo-uk.min.js +1 -1
- package/modules/geo-us-states.d.ts +1 -1
- package/modules/geo-us-states.esm.min.js +1 -1
- package/modules/geo-us-states.min.cjs +1 -1
- package/modules/geo-us-states.min.js +1 -1
- package/modules/geo-world-110m.d.ts +1 -1
- package/modules/geo-world-110m.esm.min.js +1 -1
- package/modules/geo-world-110m.min.cjs +1 -1
- package/modules/geo-world-110m.min.js +1 -1
- package/modules/geo-world-50m.d.ts +1 -1
- package/modules/geo-world-50m.esm.min.js +1 -1
- package/modules/geo-world-50m.min.cjs +1 -1
- package/modules/geo-world-50m.min.js +1 -1
- package/modules/geometry.d.ts +1 -1
- package/modules/geometry.esm.min.js +2 -2
- package/modules/geometry.min.cjs +2 -2
- package/modules/geometry.min.js +2 -2
- package/modules/htmx.d.ts +1 -1
- package/modules/htmx.esm.min.js +3 -3
- package/modules/htmx.min.cjs +3 -3
- package/modules/htmx.min.js +3 -3
- package/modules/kanban.d.ts +1 -1
- package/modules/kanban.esm.min.js +2 -2
- package/modules/kanban.min.cjs +2 -2
- package/modules/kanban.min.js +2 -2
- package/modules/kpi.d.ts +1 -1
- package/modules/kpi.esm.min.js +2 -2
- package/modules/kpi.min.cjs +2 -2
- package/modules/kpi.min.js +2 -2
- package/modules/layout.d.ts +1 -1
- package/modules/layout.esm.min.js +2 -2
- package/modules/layout.min.cjs +2 -2
- package/modules/layout.min.js +2 -2
- package/modules/leaflet.d.ts +1 -1
- package/modules/leaflet.esm.min.js +2 -2
- package/modules/leaflet.min.cjs +2 -2
- package/modules/leaflet.min.js +2 -2
- package/modules/list.d.ts +1 -1
- package/modules/list.esm.min.js +2 -2
- package/modules/list.min.cjs +2 -2
- package/modules/list.min.js +2 -2
- package/modules/mapview.d.ts +1 -1
- package/modules/mapview.esm.min.js +2 -2
- package/modules/mapview.min.cjs +2 -2
- package/modules/mapview.min.js +2 -2
- package/modules/mock-socket.d.ts +1 -1
- package/modules/mock-socket.esm.min.js +1 -1
- package/modules/mock-socket.min.cjs +1 -1
- package/modules/mock-socket.min.js +1 -1
- package/modules/presets/antd5.css +9 -0
- package/modules/presets/bootstrap5.css +9 -0
- package/modules/presets/fluent2.css +9 -0
- package/modules/presets/material3.css +9 -0
- package/modules/presets.d.ts +1 -1
- package/modules/presets.esm.min.js +2 -2
- package/modules/presets.min.cjs +2 -2
- package/modules/presets.min.js +2 -2
- package/modules/react.d.ts +1 -1
- package/modules/react.esm.min.js +2 -2
- package/modules/react.min.cjs +2 -2
- package/modules/react.min.js +2 -2
- package/modules/svelte.d.ts +1 -1
- package/modules/svelte.esm.min.js +2 -2
- package/modules/svelte.min.cjs +2 -2
- package/modules/svelte.min.js +2 -2
- package/modules/tabs.d.ts +1 -1
- package/modules/tabs.esm.min.js +2 -2
- package/modules/tabs.min.cjs +2 -2
- package/modules/tabs.min.js +2 -2
- package/modules/vue.d.ts +1 -1
- package/modules/vue.esm.min.js +2 -2
- package/modules/vue.min.cjs +2 -2
- package/modules/vue.min.js +2 -2
- package/modules/webcomponent.d.ts +1 -1
- package/modules/webcomponent.esm.min.js +3 -3
- package/modules/webcomponent.min.cjs +3 -3
- package/modules/webcomponent.min.js +3 -3
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.89.
|
|
2
|
+
* Lattice Grid 1.89.1, data-router module
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
6
|
-
(function(yr){"use strict";var Kn=Object.create(null),Hn=Object.create(null);function mt(w,Te){Kn[w]=Te}function qn(w){var Te=Hn[w];if(Te)return Te;var ye=Object.create(null);Hn[w]=ye;var F=Kn[w];if(!F)throw new Error("[lattice] missing module: "+w);return F(ye,qn),ye}mt("packages/core/src/internal/util.js",function(w,Te){"use strict";Object.defineProperty(w,"VERSION",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"reportedWarnings",{enumerable:!0,get:function(){return B}}),Object.defineProperty(w,"warnOnce",{enumerable:!0,get:function(){return te}}),Object.defineProperty(w,"infoOnce",{enumerable:!0,get:function(){return G}}),Object.defineProperty(w,"resetWarnings",{enumerable:!0,get:function(){return ne}}),Object.defineProperty(w,"fail",{enumerable:!0,get:function(){return $}}),Object.defineProperty(w,"invariant",{enumerable:!0,get:function(){return ee}}),Object.defineProperty(w,"DEV",{enumerable:!0,get:function(){return O}}),Object.defineProperty(w,"isObject",{enumerable:!0,get:function(){return R}}),Object.defineProperty(w,"isFunction",{enumerable:!0,get:function(){return j}}),Object.defineProperty(w,"isNil",{enumerable:!0,get:function(){return N}}),Object.defineProperty(w,"isBlank",{enumerable:!0,get:function(){return H}}),Object.defineProperty(w,"isCtor",{enumerable:!0,get:function(){return q}}),Object.defineProperty(w,"pathGetter",{enumerable:!0,get:function(){return de}}),Object.defineProperty(w,"pathSetter",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(w,"getPath",{enumerable:!0,get:function(){return $e}}),Object.defineProperty(w,"setPath",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(w,"humanise",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(w,"escapeHtml",{enumerable:!0,get:function(){return kt}}),Object.defineProperty(w,"titleCase",{enumerable:!0,get:function(){return He}}),Object.defineProperty(w,"expand",{enumerable:!0,get:function(){return g}}),Object.defineProperty(w,"toArray",{enumerable:!0,get:function(){return d}}),Object.defineProperty(w,"merge",{enumerable:!0,get:function(){return b}}),Object.defineProperty(w,"mergeRow",{enumerable:!0,get:function(){return E}}),Object.defineProperty(w,"Lru",{enumerable:!0,get:function(){return K}}),Object.defineProperty(w,"collator",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(w,"defaultCompare",{enumerable:!0,get:function(){return ut}}),Object.defineProperty(w,"now",{enumerable:!0,get:function(){return De}}),Object.defineProperty(w,"nextFrame",{enumerable:!0,get:function(){return a}}),Object.defineProperty(w,"cancelFrame",{enumerable:!0,get:function(){return y}}),Object.defineProperty(w,"frameBatched",{enumerable:!0,get:function(){return I}}),Object.defineProperty(w,"settleDebounce",{enumerable:!0,get:function(){return _}}),Object.defineProperty(w,"whenIdle",{enumerable:!0,get:function(){return P}}),Object.defineProperty(w,"uid",{enumerable:!0,get:function(){return Q}});const ye="1.89.0";async function F(){return ye}const le="1.89.0",be=new Set,oe=2e3;function Pe(l){if(be.add(l),be.size>oe){const u=be.values().next().value;u!==void 0&&be.delete(u)}}const D=[],Y=500;function ae(l,u,k){D.push({key:l,level:u,message:k.map(M=>typeof M=="string"?M:W(M)).join(" "),at:Date.now()}),D.length>Y&&D.shift()}function W(l){if(l instanceof Error)return l.message;try{return JSON.stringify(l)}catch{return String(l)}}function B(){return D.map(l=>({...l}))}function J(l){if(l.length===0||typeof l[0]!="string")return l;const u=l[0].replace(/^\[lattice\]\s*/,"");return u===l[0]?l:[u,...l.slice(1)]}function te(l,...u){if(be.has(l))return;Pe(l);const k=J(u);ae(l,"warn",k),console.warn("[lattice]",...k)}function G(l,...u){if(be.has(l))return;Pe(l);const k=J(u);ae(l,"info",k),console.info("[lattice]",...k)}function ne(){be.clear(),D.length=0}function $(l,u){const k=new Error(`[lattice] ${l}`);throw u!==void 0&&(k.cause=u),k}function ee(l,u){l||$(u)}const O=(()=>{try{return!(typeof process<"u"&&process.env&&process.env.NODE_ENV==="production")}catch{return!0}})();function R(l){return l!==null&&typeof l=="object"&&!Array.isArray(l)}function j(l){return typeof l=="function"}function N(l){return l==null}function H(l){return l==null||l===""}function q(l){return typeof l!="function"?!1:/^class[\s{]/.test(Function.prototype.toString.call(l))?!0:!!(l.prototype&&Object.getOwnPropertyNames(l.prototype).length>1)}const z=new Map;function de(l){let u=z.get(l);if(u)return u;if(!l.includes("."))u=k=>k?.[l];else{const k=l.split("."),M=k.length;u=Re=>{let se=Re;for(let ke=0;ke<M;ke++){if(se==null)return;se=se[k[ke]]}return se}}return z.set(l,u),u}const qe=new Map;function Ce(l){let u=qe.get(l);if(u)return u;if(!l.includes("."))u=(k,M)=>{k!=null&&(k[l]=M)};else{const k=l.split("."),M=k.length-1;u=(Re,se)=>{let ke=Re;for(let ve=0;ve<M;ve++){if(ke==null)return;const Ve=k[ve];ke[Ve]==null&&(ke[Ve]={}),ke=ke[Ve]}ke!=null&&(ke[k[M]]=se)}}return qe.set(l,u),u}function $e(l,u){return de(u)(l)}function pe(l,u,k){Ce(u)(l,k)}function ie(l){return l?(l.includes(".")?l.slice(l.lastIndexOf(".")+1):l).replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").replace(/\s+/g," ").trim().replace(/^./,k=>k.toUpperCase()):""}const Ke={"&":"&","<":"<",">":">",'"':""","'":"'"};function kt(l){const u=l==null?"":String(l);return/[&<>"']/.test(u)?u.replace(/[&<>"']/g,k=>Ke[k]):u}function He(l){return String(l).replace(/\w\S*/g,u=>u[0].toUpperCase()+u.slice(1).toLowerCase())}function g(l,u,k){if(l!==void 0)return l===!0?{enabled:!0,...k}:l===!1?{enabled:!1}:R(l)?l:{[u]:l,enabled:!0}}function d(l){return l==null?[]:Array.isArray(l)?l:[l]}const f=Object.freeze(new Set(["__proto__","constructor","prototype"]));function b(l,u){if(!R(l))return R(u)?{...u}:u;if(!R(u))return u===void 0?l:u;const k={...l};for(const M of Object.keys(u)){if(f.has(M))continue;const Re=u[M];Re!==void 0&&(k[M]=R(Re)&&R(k[M])?b(k[M],Re):Re)}return k}function E(l,u){if(!R(l)||!R(u)||l===u)return u;const k=Object.create(Object.getPrototypeOf(l));return Object.assign(k,l,u),k}class K{#e;#t=new Map;#n;constructor(u=256,k=null){this.#e=u,this.#n=k}get size(){return this.#t.size}get max(){return this.#e}set max(u){this.#e=u,this.#r()}has(u){return this.#t.has(u)}get(u){const k=this.#t;if(!k.has(u))return;const M=k.get(u);return k.delete(u),k.set(u,M),M}peek(u){return this.#t.get(u)}set(u,k){const M=this.#t;return M.has(u)&&M.delete(u),M.set(u,k),this.#r(),k}delete(u){const k=this.#t.get(u);return this.#t.delete(u)&&this.#n&&this.#n(k,u),k}clear(){if(this.#n)for(const[u,k]of this.#t)this.#n(k,u);this.#t.clear()}keys(){return this.#t.keys()}values(){return this.#t.values()}#r(){const u=this.#t;for(;u.size>this.#e;){const k=u.keys().next().value,M=u.get(k);u.delete(k),this.#n&&this.#n(M,k)}}}const V=new Map;function ze(l,u){const k=`${l||""}|${u?JSON.stringify(u):""}`;let M=V.get(k);return M||(M=new Intl.Collator(l||void 0,{numeric:!0,sensitivity:"variant",...u}),V.set(k,M)),M}function ut(l,u){if(l===u)return 0;if(l==null)return 1;if(u==null)return-1;if(typeof l=="number"&&typeof u=="number")return Number.isNaN(l)?Number.isNaN(u)?0:1:Number.isNaN(u)||l<u?-1:l>u?1:0;const k=String(l),M=String(u);return k<M?-1:k>M?1:0}function De(){return typeof performance<"u"&&performance.now?performance.now():Date.now()}const nt=typeof requestAnimationFrame=="function";function a(l){return nt?requestAnimationFrame(l):setTimeout(()=>l(De()),16)}function y(l){l!=null&&(nt?cancelAnimationFrame(l):clearTimeout(l))}function I(l){let u=null,k=null;const M=()=>{u=null;const se=k;k=null,l(...se||[])},Re=(...se)=>{k=se,u===null&&(u=a(M))};return Re.cancel=()=>{y(u),u=null,k=null},Re.flush=()=>{u!==null&&(y(u),M())},Re}function _(l,u){let k=null,M=null;const Re=()=>{if(k=null,M===null)return;const ve=M;M=null,l(...ve),se()},se=()=>{k=setTimeout(Re,u),typeof k?.unref=="function"&&k.unref()},ke=(...ve)=>{k===null?(l(...ve),se()):(M=ve,clearTimeout(k),se())};return ke.flush=()=>{if(k!==null&&clearTimeout(k),k=null,M===null)return;const ve=M;M=null,l(...ve)},ke.cancel=()=>{k!==null&&clearTimeout(k),k=null,M=null},ke.pending=()=>k!==null||M!==null,ke}function P(l,u=50){return typeof requestIdleCallback=="function"?requestIdleCallback(l,{timeout:u}):setTimeout(()=>l({timeRemaining:()=>0,didTimeout:!0}),1)}let X=0;function Q(l="l"){return`${l}${(++X).toString(36)}`}}),mt("packages/core/src/source/filterwire.js",function(w,Te){"use strict";Object.defineProperty(w,"HOST_FILTER_WARN_ID",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"WHERE_PAGE_RELATIVE_WARN_ID",{enumerable:!0,get:function(){return be}}),Object.defineProperty(w,"warnWherePageRelative",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"warnHostFilterNotApplied",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(w,"WHERE_NOT_APPLIED_WARN_ID",{enumerable:!0,get:function(){return D}}),Object.defineProperty(w,"warnWhereNotApplied",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(w,"WHERE_OVER_THRESHOLD_WARN_ID",{enumerable:!0,get:function(){return ae}}),Object.defineProperty(w,"warnWhereOverThreshold",{enumerable:!0,get:function(){return W}}),Object.defineProperty(w,"RELATIVE_TOKENS",{enumerable:!0,get:function(){return O}}),Object.defineProperty(w,"parseRelativeToken",{enumerable:!0,get:function(){return R}}),Object.defineProperty(w,"resolveRelativeRange",{enumerable:!0,get:function(){return j}}),Object.defineProperty(w,"relativeTokenOf",{enumerable:!0,get:function(){return N}}),Object.defineProperty(w,"relativeTokenHelp",{enumerable:!0,get:function(){return H}}),Object.defineProperty(w,"isResolvableRelative",{enumerable:!0,get:function(){return q}}),Object.defineProperty(w,"resolveRelativeCondition",{enumerable:!0,get:function(){return z}}),Object.defineProperty(w,"isGroup",{enumerable:!0,get:function(){return de}}),Object.defineProperty(w,"forEachCondition",{enumerable:!0,get:function(){return qe}}),Object.defineProperty(w,"mapConditions",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(w,"normaliseFilterSet",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(w,"buildFilterSet",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(w,"wireFilters",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(w,"querySignature",{enumerable:!0,get:function(){return kt}});const F=Te("packages/core/src/internal/util.js").warnOnce,le="source.remote.hostFilter",be="source.where.pageRelative";function oe(d,f){!Array.isArray(d)||!d.length||F(be,`filters.where (${d.join(", ")}) runs over the rows the ${f} source fetched,`,"not the whole dataset: match counts and totals are page-relative.","Give the predicate a { condition } twin so the engine can narrow the fetch itself.")}function Pe(d){const f=(d||{}).config;!f||!f.hostFilter||F(le,"config.hostFilter is not sent to a server-delegated source (paged/remote) and is not applied:","filtering only the fetched window would give wrong counts and totals.","Express the filter as a FilterSet condition, or send it through config.context.")}const D="source.where.notApplied";function Y(d,f){F(`${D}:${d}`,`filters.where("${d}") is registered but the ${f} source holds only its fetched window`,"and cannot run the predicate over it: the predicate is not applied there, and rows it would","exclude stay on screen.","Give it a { condition } twin so the engine can narrow the fetch itself — that is the","supported route for a paged or remote source.")}const ae="source.where.overThreshold";function W(d,f,b,E){!Array.isArray(d)||!d.length||F(`${ae}:${f}`,`filters.where (${d.join(", ")}) is not applied to the ${f} pushdown source:`,b===null?"the adapter reports no row total, so the size of the matching set is unknown.":`its matching set is ${b.toLocaleString()} rows, at or past the whereRowLimit of ${E.toLocaleString()}.`,"Running the predicate needs every matching row fetched and held here, which is the whole","download a pushdown source exists to avoid, so it is refused and the rows the predicate","would exclude stay on screen.","Give the predicate a { condition } twin so the engine narrows the fetch itself — that is the","route that works at any size — or raise `whereRowLimit` on the source config if you want the","download.")}const B=new Map;function J(d){let f=B.get(d);return f||(f=new Intl.DateTimeFormat("en-US",{timeZone:d,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}),B.set(d,f)),f}function te(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC"}catch{return"UTC"}}function G(d,f){const b=J(f).formatToParts(new Date(d)),E={y:1970,m:1,d:1,h:0,mi:0,s:0};for(const K of b)K.type==="year"?E.y=+K.value:K.type==="month"?E.m=+K.value:K.type==="day"?E.d=+K.value:K.type==="hour"?E.h=+K.value%24:K.type==="minute"?E.mi=+K.value:K.type==="second"&&(E.s=+K.value);return E}function ne(d,f){const b=G(d,f);return Date.UTC(b.y,b.m-1,b.d,b.h,b.mi,b.s)-Math.floor(d/1e3)*1e3}function $(d,f,b,E){const K=Date.UTC(d,f-1,b),V=K-ne(K,E);return K-ne(V,E)}function ee(d,f,b){const E=new Date(Date.UTC(d.y,d.m-1,d.d+f));return $(E.getUTCFullYear(),E.getUTCMonth()+1,E.getUTCDate(),b)}const O=Object.freeze(["today","yesterday","lastNDays","thisWeek","thisMonth","thisQuarter","thisYear","quarterToDate","yearToDate"]);function R(d,f){if(typeof d!="string")return null;const b=d.trim().toLowerCase().replace(/[\s_-]+/g,""),E=/^last(\d*|n)days?$/.exec(b);if(E){const K=E[1]==="n"?"":E[1],V=Number(K||f);return!Number.isFinite(V)||V<=0?null:{kind:"lastNDays",n:Math.floor(V)}}switch(b){case"today":return{kind:"today",n:0};case"yesterday":return{kind:"yesterday",n:0};case"thisweek":return{kind:"thisWeek",n:0};case"thismonth":return{kind:"thisMonth",n:0};case"thisquarter":return{kind:"thisQuarter",n:0};case"thisyear":return{kind:"thisYear",n:0};case"quartertodate":case"qtd":return{kind:"quarterToDate",n:0};case"yeartodate":case"ytd":return{kind:"yearToDate",n:0};default:return null}}function j(d,f={}){const b=R(d,f.n);if(!b)return null;const E=f.tz||te(),K=f.now instanceof Date?f.now.getTime():typeof f.now=="number"?f.now:Date.now(),V=G(K,E),ze=$(V.y,V.m,V.d,E),ut=ee(V,1,E);let De=ze,nt=ut;switch(b.kind){case"today":break;case"yesterday":De=ee(V,-1,E),nt=ze;break;case"lastNDays":nt=f.includeToday?ut:ze,De=ee(V,f.includeToday?-(b.n-1):-b.n,E);break;case"thisWeek":{const a=Number.isFinite(f.weekStartsOn)?Number(f.weekStartsOn):1,I=(new Date(Date.UTC(V.y,V.m-1,V.d)).getUTCDay()-a+7)%7;De=ee(V,-I,E),nt=ee(V,-I+7,E);break}case"thisMonth":De=$(V.y,V.m,1,E),nt=$(V.m===12?V.y+1:V.y,V.m===12?1:V.m+1,1,E);break;case"thisQuarter":case"quarterToDate":{const a=Math.floor((V.m-1)/3)*3+1;De=$(V.y,a,1,E),nt=b.kind==="quarterToDate"?ut:a===10?$(V.y+1,1,1,E):$(V.y,a+3,1,E);break}case"thisYear":case"yearToDate":De=$(V.y,1,1,E),nt=b.kind==="yearToDate"?ut:$(V.y+1,1,1,E);break;default:return null}return{from:new Date(De).toISOString(),to:new Date(nt).toISOString(),bounds:"[)",tz:E,relative:b.kind==="lastNDays"?`last${b.n}Days`:b.kind,n:b.n}}function N(d){if(!d||typeof d!="object")return null;const f=d.value;if(f&&typeof f=="object"&&!Array.isArray(f)&&"relative"in f)return{token:String(f.relative),n:typeof f.n=="number"?f.n:void 0};if(d.op==="relative"&&typeof d.value=="string")return{token:d.value,n:void 0};const b=d.meta;return b&&typeof b.relative=="string"&&d.value===void 0?{token:b.relative,n:typeof b.n=="number"?b.n:void 0}:null}function H(){return`Known tokens: ${O.filter(f=>f!=="lastNDays").join(", ")}. "lastNDays" needs a count: pass "last7Days", or the value object { relative: 'lastNDays', n: 7 }.`}function q(d){const f=N(d);return f?R(f.token,f.n)!==null:!1}function z(d,f={}){const b=N(d);if(!b)return d;const E=j(b.token,{...f,n:b.n});return E?{...d,type:d.type||"date",op:"between",value:[E.from,E.to],bounds:d.bounds||E.bounds,meta:{...d.meta||{},relative:E.relative,tz:E.tz}}:(F(`source.relative.${b.token}`,`unknown relative date token "${b.token}"; sending the condition unresolved.`,H()),d)}function de(d){return!!d&&typeof d=="object"&&Array.isArray(d.conditions)}function qe(d,f){if(d){if(de(d)){for(const b of d.conditions)qe(b,f);return}f(d)}}function Ce(d,f){if(!d)return null;if(!de(d))return f(d);const b=d;let E=!1;const K=[];for(const V of b.conditions){const ze=Ce(V,f);ze!==V&&(E=!0),ze&&K.push(ze)}return!E&&K.length===b.conditions.length?d:K.length?{...b,conditions:K}:null}function $e(d){if(!d)return null;if(!de(d))return d;const f=d,b=[];for(const E of f.conditions){const K=$e(E);K&&b.push(K)}return b.length?{op:f.op,conditions:b}:null}function pe(d){const f=$e(d);return f?de(f)&&f.op==="and"?f:{op:"and",conditions:[f]}:null}function ie(d){const f=(d||[]).filter(Boolean);return f.length?{op:"and",conditions:f}:null}function Ke(d,f={}){const b=Ce(d,E=>z(E,f));return pe(b)}function kt(d){const f=He(d.filters??null);return JSON.stringify([f,d.sort??null,d.quick??"",d.groupBy??null,d.pivotBy??null,g(d.context)])}function He(d){if(!d)return null;if(de(d)){const E=d;return{op:E.op,conditions:E.conditions.map(He)}}const f=d,b=f.meta&&typeof f.meta.relative=="string"?f.meta.relative:N(f)?.token;return{col:f.col,op:f.op,bounds:f.bounds??null,caseSensitive:f.caseSensitive??!1,value:b?`rel:${b}`:f.value??null}}function g(d){if(d==null)return null;try{return JSON.parse(JSON.stringify(d))}catch{return F("source.context.unserialisable","config.context is not JSON-serialisable; cache keys ignore it."),"[unserialisable]"}}}),mt("packages/core/src/source/aggregates.js",function(w,Te){"use strict";Object.defineProperty(w,"STAT_PUSHDOWN",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(w,"pushableAggregates",{enumerable:!0,get:function(){return F}}),Object.defineProperty(w,"fillAggregateSql",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"resolveAggregatesConfig",{enumerable:!0,get:function(){return be}}),Object.defineProperty(w,"routeAggregate",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"resolveAggregatePlan",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(w,"groupKeysPushable",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(w,"pushdownDocRows",{enumerable:!0,get:function(){return ae}});const ye=Object.freeze({sum:{pushable:!0,class:"identical",sql:"sum(%c)"},avg:{pushable:!0,class:"identical",sql:"avg(%c)"},min:{pushable:!0,class:"identical",sql:"min(%c)"},max:{pushable:!0,class:"identical",sql:"max(%c)"},count:{pushable:!0,class:"identical",sql:"count(*)"},countValues:{pushable:!0,class:"identical",sql:"count(%c)",blankAware:!0},range:{pushable:!0,class:"identical",sql:"(max(%c) - min(%c))"},variance:{pushable:!0,class:"identical",sql:"var_samp(%c)"},varianceP:{pushable:!0,class:"identical",sql:"var_pop(%c)"},stddev:{pushable:!0,class:"identical",sql:"stddev_samp(%c)"},stddevP:{pushable:!0,class:"identical",sql:"stddev_pop(%c)"},sumSquares:{pushable:!0,class:"identical",sql:"sum(%c * %c)"},median:{pushable:!0,class:"identical",sql:"median(%c)"},p25:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.25)"},p75:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.75)"},p90:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.9)"},p95:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.95)"},p99:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.99)"},iqr:{pushable:!0,class:"identical",sql:"(quantile_cont(%c, 0.75) - quantile_cont(%c, 0.25))"},mad:{pushable:!0,class:"identical",sql:"mad(%c)"},distinct:{pushable:!0,class:"identical",sql:"count(DISTINCT %c)",blankAware:!0},skewness:{pushable:!0,class:"identical",sql:"skewness(%c)"},kurtosis:{pushable:!0,class:"identical",sql:"kurtosis(%c)"},geomean:{pushable:!0,class:"identical",sql:"exp(avg(ln(%c)))"},harmean:{pushable:!0,class:"identical",sql:"(count(%c) / sum(1.0 / %c))"},entropy:{pushable:!0,class:"identical",sql:"entropy(%c)",blankAware:!0},correlation:{pushable:!0,class:"identical",sql:"corr(%w, %c)",twoColumn:!0},hhi:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_transform(map_values(histogram(%c)), lambda v: (v::DOUBLE/count(%c))*(v::DOUBLE/count(%c)))) END"},evenness:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL WHEN count(DISTINCT %c)<2 THEN 1.0 ELSE entropy(%c)/log2(count(DISTINCT %c)) END"},top3Share:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,3))::DOUBLE/count(%c) END"},top10Share:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,10))::DOUBLE/count(%c) END"},gini:{pushable:!0,class:"identical",sql:"CASE WHEN list_min(list(%c) FILTER (WHERE isfinite(%c)))<0 THEN NULL WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL WHEN list_sum(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN 0 ELSE 2.0*list_sum(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v, i: i*v))/(len(list(%c) FILTER (WHERE isfinite(%c)))*list_sum(list(%c) FILTER (WHERE isfinite(%c))))-(len(list(%c) FILTER (WHERE isfinite(%c)))+1.0)/len(list(%c) FILTER (WHERE isfinite(%c))) END"},trimmedMean:{pushable:!0,class:"identical",sql:"CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE list_avg(list_slice(list_sort(list(%c) FILTER (WHERE isfinite(%c))), floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1, len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT)) END"},winsorizedMean:{pushable:!0,class:"identical",sql:"CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE list_avg(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v: least(list_sort(list(%c) FILTER (WHERE isfinite(%c)))[len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT], greatest(list_sort(list(%c) FILTER (WHERE isfinite(%c)))[floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1], v)))) END"},robustOutliers:{pushable:!0,class:"identical",sql:"(SELECT CASE WHEN len(d.a)=0 THEN NULL WHEN d.mad=0 THEN NULL ELSE len(list_filter(d.a, lambda v: abs(0.6745*(v-d.med)/d.mad)>3.5)) END FROM (SELECT xs AS a, list_median(xs) AS med, list_median(list_transform(xs, lambda w: abs(w-list_median(xs)))) AS mad FROM (SELECT list(%c) FILTER (WHERE isfinite(%c)) AS xs)) d)"},jarqueBera:{pushable:!0,class:"identical",sql:"CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))<8 THEN NULL WHEN list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2)))=0 THEN NULL ELSE (len(list(%c) FILTER (WHERE isfinite(%c)))/6.0)*(power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),3)))/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),1.5),2)+power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),4)))/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),2)-3,2)/4.0) END"},weightedAvg:{pushable:!0,class:"identical",twoColumn:!0,sql:"sum(%c*%w) FILTER (WHERE isfinite(%c) AND isfinite(%w))/nullif(sum(%w) FILTER (WHERE isfinite(%c) AND isfinite(%w)),0)"},mode:{pushable:!0,class:"may-differ",sql:"mode(%c)",note:"DuckDB returns a modal value even for an all-distinct column; the grid returns null. Tie-breaking can also differ, and on a text column an empty string counts as a value. Under pushdown you will see a value."},weightedQuantile:{pushable:!1,class:"fallback",note:"No SQL equivalent for the grid's weighted-quantile midpoint convention; always computed client-side (needs a full-dataset pull for a correct figure over a remote source)."}});function F(){const W=new Set;for(const[B,J]of Object.entries(ye))J.pushable&&W.add(B);return W}function le(W,B,J){let te=W.split("%c").join(B);return J!==void 0&&(te=te.split("%w").join(J)),te}function be(W){const B=W||{},J=B.default==="engine"||B.default==="engine-if-identical"?B.default:"client",te={};if(B.overrides&&typeof B.overrides=="object")for(const[G,ne]of Object.entries(B.overrides))(ne==="engine"||ne==="client")&&(te[G]=ne);return{default:J,overrides:te}}function oe(W,B){const J=ye[W];if(!J||!J.pushable)return"client";const te=B.overrides[W];return te==="engine"||te==="client"?te:B.default==="client"?"client":B.default==="engine-if-identical"?J.class==="identical"?"engine":"client":"engine"}function Pe(W,B){const J=be(B),te=[],G=[];for(const ne of W||[]){const $=ye[ne.fn],ee=oe(ne.fn,J),O={id:ne.id,col:ne.col,fn:ne.fn,class:$?$.class:"fallback"};ne.weight!==void 0&&(O.weight=ne.weight),ne.params!==void 0&&(O.params=ne.params),ee==="engine"?te.push(O):(O.reason=$&&!$.pushable?$.note||"the engine cannot express this stat":"client by config",G.push(O))}return{engine:te,client:G,config:J}}const D=/^[A-Za-z_][A-Za-z0-9_$]*$/;function Y(W,B=[]){return(W||[]).every(te=>{if(typeof te=="string")return D.test(te);if(!te||typeof te!="object")return!1;const G=te;return Array.isArray(B)&&B.includes(G.bucket)&&typeof G.col=="string"&&D.test(G.col)&&typeof G.size=="number"&&Number.isFinite(G.size)&&G.size>0})}function ae(){return Object.entries(ye).map(([W,B])=>({stat:W,class:B.class,sql:B.sql?le(B.sql,"col",B.twoColumn?"weight":void 0):"",note:B.note||(B.class==="identical"?"Pushes to DuckDB with the same result.":"")}))}}),mt("packages/core/src/source/abort.js",function(w,Te){"use strict";Object.defineProperty(w,"SupersededError",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(w,"RequestToken",{enumerable:!0,get:function(){return F}}),Object.defineProperty(w,"AbortScope",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"createAbortScope",{enumerable:!0,get:function(){return be}}),Object.defineProperty(w,"isAbortError",{enumerable:!0,get:function(){return oe}});class ye extends Error{constructor(D,Y="superseded"){super(`[lattice] request ${D?`"${D}" `:""}${Y}`),this.name="SupersededError",this.superseded=!0,this.key=D}}class F{#e;constructor(D,Y,ae,W){this.#e=D,this.key=Y,this.controller=ae,this.signal=ae.signal,this.seq=W}get current(){return!this.signal.aborted&&this.#e.tokenFor(this.key)===this}settle(){this.#e.settle(this)}abort(D){this.signal.aborted||this.controller.abort(new ye(this.key,D)),this.#e.settle(this)}}class le{#e=new Map;#t=0;begin(D="",Y="superseded"){const ae=this.#e.get(D);ae&&!ae.signal.aborted&&ae.controller.abort(new ye(D,Y));const W=new F(this,D,new AbortController,++this.#t);return this.#e.set(D,W),W}tokenFor(D){return this.#e.get(D)}pending(D=""){const Y=this.#e.get(D);return!!Y&&!Y.signal.aborted}get size(){return this.#e.size}settle(D){this.#e.get(D.key)===D&&this.#e.delete(D.key)}abort(D="",Y="superseded"){const ae=this.#e.get(D);ae&&ae.abort(Y)}abortAll(D="superseded"){for(const Y of[...this.#e.values()])Y.abort(D);this.#e.clear()}}function be(){return new le}function oe(Pe){if(!Pe||typeof Pe!="object")return!1;const D=Pe;return D.superseded===!0||D.name==="AbortError"||D.name==="SupersededError"}}),mt("packages/core/src/source/pushdown.js",function(w,Te){"use strict";Object.defineProperty(w,"FOREGROUND_WAIT_MS",{enumerable:!0,get:function(){return $}}),Object.defineProperty(w,"NO_CAPABILITIES",{enumerable:!0,get:function(){return O}}),Object.defineProperty(w,"resolveMutate",{enumerable:!0,get:function(){return R}}),Object.defineProperty(w,"capabilitiesOf",{enumerable:!0,get:function(){return H}}),Object.defineProperty(w,"splitFilters",{enumerable:!0,get:function(){return z}}),Object.defineProperty(w,"LEAF_COUNT_ID",{enumerable:!0,get:function(){return de}}),Object.defineProperty(w,"PIVOT_UNSUPPORTED",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(w,"GROUP_UNSUPPORTED",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(w,"UNGROUPED_LEVEL",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(w,"planQuery",{enumerable:!0,get:function(){return He}}),Object.defineProperty(w,"applyResidual",{enumerable:!0,get:function(){return f}}),Object.defineProperty(w,"DEFAULT_WHERE_ROW_LIMIT",{enumerable:!0,get:function(){return V}}),Object.defineProperty(w,"createPushdownSource",{enumerable:!0,get:function(){return nt}});const ye=Te("packages/core/src/internal/util.js"),F=ye.defaultCompare,le=ye.isFunction,be=ye.toArray,oe=ye.warnOnce,Pe=Te("packages/core/src/source/filterwire.js"),D=Pe.isGroup,Y=Pe.warnWherePageRelative,ae=Pe.warnWhereOverThreshold,W=Te("packages/core/src/source/aggregates.js"),B=W.resolveAggregatePlan,J=W.groupKeysPushable,te=W.STAT_PUSHDOWN,ne=Te("packages/core/src/source/abort.js").SupersededError,$=1e3;function ee(a){const y=a&&a.signal;if(!y||!y.aborted)return;const I=y.reason;throw I instanceof Error?I:new ne("","superseded before it was sent")}const O=Object.freeze({filter:!1,operators:Object.freeze([]),sort:!1,quick:!1,range:!1,total:!1,group:!1,pivot:!1,mutate:!1});function R(a){if(!a||typeof a!="object")return!1;const y=a.returning==="row"||a.returning==="key"?a.returning:"none";return{append:a.append===!0,update:a.update===!0,delete:a.delete===!0,returning:y}}function j(a,y){if(!a||typeof y!="string")return;if(!y.includes("."))return a[y];let I=a;for(const _ of y.split(".")){if(I===null||typeof I!="object")return;I=I[_]}return I}function N(a){if(a===!0)return!0;if(!a||typeof a!="object")return!1;const y=a;return y.enabled===!1?!1:y.enabled===!0||le(y.commit)}function H(a){const y={...O,...a||{}};return y.operators=new Set(y.operators||[]),y.mutate=R(y.mutate),y}function q(a,y){return!a||!a.op||!y.operators.size?!1:y.operators.has(a.op)}function z(a,y){if(!a)return{pushed:null,residual:null};if(!y.filter)return{pushed:null,residual:a};if(y.filter==="term"){if(D(a)){const X=a.conditions||[];if(String(a.op)!=="and")return{pushed:null,residual:a};const Q=X.findIndex(u=>!D(u)&&q(u,y));if(Q<0)return{pushed:null,residual:a};const l=X.filter((u,k)=>k!==Q);return{pushed:X[Q],residual:l.length?{op:"and",conditions:l}:null}}return q(a,y)?{pushed:a,residual:null}:{pushed:null,residual:a}}if(!D(a))return q(a,y)?{pushed:a,residual:null}:{pushed:null,residual:a};if(String(a.op)!=="and")return(a.conditions||[]).every(Q=>D(Q)?z(Q,y).residual===null:q(Q,y))?{pushed:a,residual:null}:{pushed:null,residual:a};const I=[],_=[];for(const X of a.conditions||[]){if(D(X)){if(y.filter==="flat"){_.push(X);continue}const Q=z(X,y);Q.pushed&&I.push(Q.pushed),Q.residual&&_.push(Q.residual);continue}(q(X,y)?I:_).push(X)}const P=X=>X.length===0?null:X.length===1?X[0]:{op:"and",conditions:X};return{pushed:P(I),residual:P(_)}}const de="__lattice_leaves";function qe(a){return a.aggregates?a.aggregates instanceof Set?a.aggregates:new Set(be(a.aggregates)):new Set}function Ce(a){const y=qe(a);return y.size?y.has("count")?a.filter!=="tree"||!a.operators||!a.operators.has("eq")?"the adapter does not declare the `group` capability, and cannot narrow a group's rows by its key (that needs a `tree` filter with the `eq` operator)":"":"the adapter does not declare the `group` capability, and its declared aggregates have no `count` to give each group its row count":"the adapter does not declare the `group` capability"}function $e(a,y,I,_,P,X,Q){const l=Array.isArray(a.groupBy)?a.groupBy:[],u=Array.isArray(a.groupPath)?a.groupPath:[],k=Array.isArray(a.groupValues)?a.groupValues:null;if(!y.group){const M=Ce(y);if(M)return M}return J(l)?I.residual?"the filter did not fully push, so the engine would group a superset of the matching rows":_?P?X?"a host `where` predicate can only run in the browser, over rows the engine grouped":Q?"fullDataset holds the whole matching set, so the grid groups it itself":!k||k.length!==u.length?"the request carries no typed `groupValues` for its group path, and the string `groupPath` cannot be compared against a typed column":"":"a quick search did not push, so the engine would group unsearched rows":"the sort did not push, so the engine would order the groups differently":"a grouping key is not a plain column the engine can name in a GROUP BY"}const pe="pushdown:pivot-unsupported",ie="pushdown:group-unsupported",Ke=Symbol("lattice.remote.ungroupedLevel");function kt(a,y,I,_,P,X){const Q=Array.isArray(a.pivotBy)?a.pivotBy:[],l=Array.isArray(a.groupBy)?a.groupBy:[],u=Array.isArray(a.groupPath)?a.groupPath:[],k=Array.isArray(a.groupValues)?a.groupValues:null;return y.pivot?J(Q)?l.length&&!J(l)?"a grouping key is not a plain column the engine can name in a GROUP BY":I.residual?"the filter did not fully push, so the engine would pivot a superset of the matching rows":_?P?X?"a host `where` predicate can only run in the browser, over rows the engine pivoted":!k||k.length!==u.length?"the request carries no typed `groupValues` for its group path, and the string `groupPath` cannot be compared against a typed column":"":"a quick search did not push, so the engine would pivot unsearched rows":"the sort did not push, so the engine would order the rows differently":"a pivot column is not a plain column the engine can name in a GROUP BY":"the adapter does not declare the `pivot` capability"}function He(a,y,I=!1){const _=z(a.filters||null,y),P=[];_.residual&&P.push("filter");const X=a.sort||[],Q=X.length===0||y.sort==="multi"&&X.length>=1||y.sort==="single"&&X.length===1;!Q&&X.length&&P.push("sort");const l=a.quick?String(a.quick):"",u=!l||!!y.quick;u||P.push("quick");const k=a.where&&a.where.active?a.where:null;k&&P.push("where");const M={filters:_.residual,sort:Q?null:X,quick:u?"":l,where:k},Re=!!I,se=Array.isArray(a.groupBy)&&a.groupBy.length>0,ke=se?$e(a,y,_,Q,u,k,Re):"",ve=a.pivotMode!==!1&&Array.isArray(a.pivotBy)&&a.pivotBy.length>0,Ve=ve?kt(a,y,_,Q,u,k):"",Ne=ve&&Ve==="";ve&&!Ne&&P.push("pivot");const _e=ve?Ne&&se:se&&ke==="";se&&!ve&&!_e&&P.push("group");const Me=(_e||Ne)&&Array.isArray(a.groupValues)?a.groupValues.length:0,yt=_e||ve?!1:Re||!!(M.filters||M.sort||M.quick||M.where)||!y.range;return{pushed:{...a,filters:_.pushed,sort:Q?X:[],quick:u?l:"",range:yt?null:a.range},residual:M,needsAll:yt,unpushed:P,full:Re,grouped:_e,groupLevel:Me,groupReason:ve?"":ke,pivoted:Ne,pivotReason:Ve}}function g(a){const y=Array.isArray(a.totals)?a.totals:[],I=a.totalFns&&typeof a.totalFns=="object"?a.totalFns:{},_=[],P=[];for(const X of y){const Q=String(X),l=typeof I[Q]=="string"?I[Q]:null,u=l?te[l]:null;l?!u||!u.pushable||!u.sql?P.push({id:Q,fn:l,class:u?u.class:"fallback",reason:u&&u.note?u.note:`the pushdown map cannot express "${l}"`}):u.twoColumn?P.push({id:Q,fn:l,class:u.class,reason:`"${l}" reduces two columns, and a grouped request carries no weight column`}):_.push({id:Q,col:Q,fn:l,class:u.class}):P.push({id:Q,fn:null,class:"fallback",reason:"the column totals with a host function, so there is no named statistic to push"})}return{engine:_,client:P}}const d=Object.freeze({items:a=>a==null?[]:Array.isArray(a)?a:[a]});function f(a,y,I){if(!y)return a;let _=a;if(y.filters&&le(I.evaluateFilters)){const P=_,X={count:_.length,handle:u=>({id:u,get:k=>j(P[k],u)}),itemwise:u=>P.some(k=>Array.isArray(j(k,u)))?d:null},Q=I.evaluateFilters(y.filters,X),l=[];for(let u=0;u<_.length;u++)Q[u]&&l.push(_[u]);_=l}if(y.where&&y.where.active&&(y.whole||Y(y.where.names,"pushdown"),_=_.filter(P=>y.where.passes(P))),y.quick){const P=y.quick.toLowerCase();_=_.filter(X=>{if(!X||typeof X!="object")return!1;for(const Q of Object.values(X))if(Q!=null&&String(Q).toLowerCase().includes(P))return!0;return!1})}if(y.sort&&y.sort.length&&le(I.sortMulti)){const P=[...new Set(y.sort.map(u=>u.col))],X=_,Q=P.map(u=>({id:u,get:k=>j(X[k],u)})),l=I.sortMulti(Q,y.sort.map(u=>({col:u.col,dir:u.dir})),Uint32Array.from({length:_.length},(u,k)=>k),{});_=Array.from(l,u=>X[u])}return _}function b(a){return JSON.stringify({filters:a.filters||null,sort:a.sort||[],quick:a.quick||"",groupBy:a.groupBy||[],groupPath:a.groupPath||[],context:a.context??null})}function E(a){if(!a||typeof a!="object")return 16;let y="";try{y=JSON.stringify(a)}catch{return 200}return y.length*2+64}function K(a){const y=a||{};return{enabled:!!y.enabled,maxRows:Number.isFinite(y.maxRows)?y.maxRows:1e6,maxBytesEstimate:Number.isFinite(y.maxBytesEstimate)?y.maxBytesEstimate:512*1024*1024}}const V=5e4;function ze(a){return Number.isFinite(a)&&a>=0?a:V}function ut(a){return!!a&&le(a.then)}async function De(a){if(!a||a.total!==void 0||!ut(a.pendingTotal))return a;const y=await a.pendingTotal,{pendingTotal:I,..._}=a;return typeof y=="number"?{..._,total:y}:_}function nt(a={}){const y=a.adapter;if(!y||!le(y.execute))return oe("source.pushdown.adapter","createPushdownSource needs an `adapter` with an `execute(query)` function."),{...a,mode:"remote",fetch:async()=>({rows:[],total:0})};const I=H(y.capabilities),_=y.capabilities&&Object.getOwnPropertyDescriptor(y.capabilities,"operators");_&&le(_.get)&&Object.defineProperty(I,"operators",{enumerable:!0,configurable:!0,get:()=>new Set(y.capabilities.operators||[]),set:()=>{}});const P=y.name||"adapter";let X=null;const Q=()=>le(y.ready)?(X||(X=Promise.resolve(y.ready()).then(()=>{Object.assign(I,H(y.capabilities))},x=>{throw X=null,x})),X):null,l=K(a.fullDataset),u=!!a.allowPartialResults,k=ze(a.whereRowLimit);let M=null;const Re=a.aggregates;let se=null,ke=null,ve=null,Ve=null,Ne=null,_e,Me=null,yt=0,bt=null;const dt=()=>!l.enabled||!se?null:(bt!==se.key&&(yt++,bt=se.key),{rows:se.rows,version:yt}),Ft=async x=>{const C=x.where&&x.where.active?x.where:null;if(!C)return{request:x,probe:null};const{where:U,...re}=x,T=He(re,I,l.enabled);if(T.needsAll)return{request:x,probe:null};const we=b(T.pushed);let fe=null;return(!M||M.key!==we)&&(I.total?(ee(x),fe=await De(await y.execute(T.pushed,x)),M={key:we,size:fe&&typeof fe.total=="number"?fe.total:null}):M={key:we,size:null}),M.size!==null&&M.size<k?{request:x,probe:null}:(ae(C.names,P,M.size,k),{request:re,probe:fe})},xt=async(x,C)=>{Me=null;const U=g(x.pushed);ve={engine:U.engine,client:U.client,groupBy:x.pushed.groupBy},U.client.length&&oe(`source.pushdown.group.totals.${P}.${U.client.map(we=>we.id).join(".")}`,`the ${P} adapter cannot compute the group subtotal for ${U.client.map(we=>`"${we.id}" (${we.reason})`).join(", ")}, so those group rows carry no value for that column. A figure computed over anything other than the group would be wrong, so none is shown; \`lastPlan().aggregates.client\` names them.`);const re=await y.executeGroupLevel(x.pushed,U.engine,C)||{};let T=re.rows||[];return!I.range&&C.range&&(T=T.slice(C.range.start,C.range.end)),ct(re),re.total===void 0?{rows:T}:{rows:T,total:re.total}},pt=new Map,mn=64,Pt=async(x,C)=>{Me=null;const U=x.pushed,re=U.groupBy,T=Array.isArray(U.groupValues)?U.groupValues:[],we=T.length,fe=[...U.filters?[U.filters]:[],...re.slice(0,we).map((Z,Qe)=>({col:Z,op:"eq",value:T[Qe]===void 0?null:T[Qe],caseSensitive:!0}))],We=fe.length===0?null:fe.length===1?fe[0]:{op:"and",conditions:fe},Fe=C.range?C.range.start:0;if(we>=re.length){const Z={...U,filters:We,groupBy:[],groupPath:[],groupValues:[],totals:[],totalFns:{}},Qe=await De(await y.execute(Z,C))||{};let it=Qe.rows||[];return!I.range&&C.range&&(it=it.slice(C.range.start,C.range.end)),typeof Qe.total=="number"?{rows:it,total:Qe.total}:{rows:it}}const ue=re[we],et=g(U),ft=qe(I),Ee=et.engine.filter(Z=>ft.has(Z.fn)),Ge=[...et.engine.filter(Z=>!ft.has(Z.fn)).map(Z=>({id:Z.id,fn:Z.fn,class:Z.class,reason:`the ${P} adapter does not compute "${Z.fn}"`})),...et.client];ve={engine:Ee,client:Ge,groupBy:re},Ge.length&&oe(`source.pushdown.group.totals.${P}.${Ge.map(Z=>Z.id).join(".")}`,`the ${P} adapter cannot compute the group subtotal for ${Ge.map(Z=>`"${Z.id}" (${Z.reason})`).join(", ")}, so those group rows carry no value for that column. A figure computed over anything other than the group would be wrong, so none is shown; \`lastPlan().aggregates.client\` names them.`);const me=[...Ee.map(Z=>({id:Z.id,col:Z.col,fn:Z.fn})),{id:de,col:ue,fn:"count"}],xe={...U,filters:We,range:null},je=JSON.stringify([b(xe),T,ue,me]);let Be=Fe>0?pt.get(je):void 0;if(!Be){for(Be=Promise.resolve(y.executeGroupedAggregates(xe,[ue],me)),pt.delete(je),pt.set(je,Be);pt.size>mn;)pt.delete(pt.keys().next().value);Be.catch(()=>{pt.get(je)===Be&&pt.delete(je)})}const ht=await Be||[];ee(C);const Le=Z=>{const Qe={};for(const it of Ee)Qe[it.id]=Z?Z[it.id]:void 0;return Qe},Oe=(U.sort||[]).find(Z=>Z&&Z.col===ue),St=Oe&&Oe.dir==="desc"?-1:1,Et=ht.filter(Z=>Z&&Z.level===1).map(Z=>({[ue]:Z.keys[0]===void 0?null:Z.keys[0],leafCount:Number(Z.values&&Z.values[de])||0,totals:Le(Z.values)})).sort((Z,Qe)=>St*F(Z[ue],Qe[ue]));if(we===0){const Z=ht.find(it=>it&&it.level===0),Qe=Z?Number(Z.values&&Z.values[de]):NaN;ct({matchCount:Number.isFinite(Qe)?Qe:Et.reduce((it,wn)=>it+wn.leafCount,0),...Z?{grand:Le(Z.values)}:{}})}const bn=C.range?C.range.end:Et.length;return{rows:Et.slice(Fe,bn),total:Et.length}},ct=x=>{typeof x.matchCount=="number"&&(Ve=x.matchCount,Ne=x.grand?{totals:x.grand,leafCount:x.matchCount}:null,_e===void 0&&le(y.unfilteredCount)&&(_e=null,Promise.resolve(y.unfilteredCount()).then(C=>{_e=typeof C=="number"?C:null}).catch(C=>{oe(`source.pushdown.group.unfiltered.${P}`,`the ${P} adapter could not count the unfiltered set (${C&&C.message?C.message:C}), so "N of M" falls back to the display count for its denominator.`)})))},vt=async(x,C)=>{Me=null;const U=g(x.pushed);ve={engine:U.engine,client:U.client,groupBy:x.pushed.groupBy,pivotBy:x.pushed.pivotBy},U.client.length&&oe(`source.pushdown.pivot.totals.${P}.${U.client.map(We=>We.id).join(".")}`,`the ${P} adapter cannot compute the pivot cells for ${U.client.map(We=>`"${We.id}" (${We.reason})`).join(", ")}, so those cells are empty. A figure computed over anything other than the cell would be wrong, so none is shown; \`lastPlan().aggregates.client\` names them.`);const re=await y.executePivotLevel(x.pushed,U.engine,C)||{};let T=re.rows||[];!I.range&&C.range&&(T=T.slice(C.range.start,C.range.end)),ct(re);const we=re.pivot&&typeof re.pivot=="object"?re.pivot:{},fe={cells:Array.isArray(we.cells)?we.cells:[],...Array.isArray(we.axis)?{axis:we.axis}:{}};return re.total===void 0?{rows:T,pivot:fe}:{rows:T,total:re.total,pivot:fe}},$t=x=>{oe(`source.pushdown.pivot.${P}.${x}`,`pushdown:pivot-unsupported: the ${P} adapter cannot pivot this query because ${x}, so no rows are fetched rather than every leaf row being pulled into the browser to pivot there. \`lastPlan().pivotReason\` says the same.`);const C=new Error(`[lattice] ${pe}: the ${P} adapter cannot pivot this query because ${x}, so no rows are fetched rather than every leaf row being pulled into the browser to pivot there. \`lastPlan().pivotReason\` says the same.`);throw C.code=pe,C.reason=x,C},yn=(x,C)=>{const U={key:C,state:"pending",value:null};return Me=U,x.then(re=>(Me===U&&(Me={key:C,state:"settled",value:typeof re=="number"?re:null}),re),re=>{throw Me===U&&(Me={key:C,state:"failed",value:null}),re})};let Xe=0,Ye=[];const rt=()=>Xe===0?null:new Promise(x=>{const C=setTimeout(x,$);Ye.push(()=>{clearTimeout(C),x()})});let Ue;const Rt=async x=>{const C=Q();C&&await C;const re=x&&x.pivotMode!==!1&&Array.isArray(x.pivotBy)&&x.pivotBy.length>0?{request:x,probe:null}:await Ft(x);ee(x);let T=He(re.request,I,l.enabled);if(I.group&&T.grouped&&!T.pivoted&&!le(y.executeGroupLevel)&&(oe(`source.pushdown.group.method.${P}`,`the ${P} adapter declares the \`group\` capability but has no \`executeGroupLevel(query, aggregates, request)\`, so grouping is not pushed and the grid stays ungrouped unless it holds the whole matching set. Implement the method or drop the capability.`),T=He(re.request,{...I,group:!1,aggregates:null},l.enabled)),T.pivoted&&!le(y.executePivotLevel)&&(T=He(re.request,{...I,pivot:!1},l.enabled),T.pivotReason="the adapter declares the `pivot` capability but has no `executePivotLevel(query, aggregates, request)`"),T.grouped&&!T.pivoted&&!I.group&&!le(y.executeGroupedAggregates)&&(oe(`source.pushdown.group.aggregates.method.${P}`,`the ${P} adapter declares \`aggregates\` but has no \`executeGroupedAggregates(query, groupBy, aggregates)\`, so the grouped view cannot be built from grouped aggregates and the grid stays ungrouped unless it holds the whole matching set. Implement the method, or declare \`group\` and implement \`executeGroupLevel\`.`),T=He(re.request,{...I,aggregates:null},l.enabled)),ke=T,T.pivoted)return vt(T,x);if(T.pivotReason&&$t(T.pivotReason),T.grouped)return I.group?xt(T,x):Pt(T,x);const fe=!!T.groupReason&&!T.full;fe?oe(`source.pushdown.group-unsupported.${P}.${T.groupReason}`,`pushdown:group-unsupported: the ${P} adapter was not asked to group this query because ${T.groupReason}, so the grid stays ungrouped rather than building group rows, counts and subtotals from a window of leaf rows. \`lastPlan().groupReason\` says the same.`):T.groupReason&&oe(`source.pushdown.group.${P}.${T.groupReason}`,`the ${P} adapter was not asked to group this query because ${T.groupReason}. The engine returns rows and the grouping is the grid's to do, which needs every matching row in the browser — correct where the grid holds them, and wrong-looking where it holds a window. \`lastPlan().unpushed\` names it.`);const We=me=>fe?{...me,[Ke]:!0}:me;if(!T.needsAll){const me=re.probe||await y.execute(T.pushed,x),xe=me.rows||[];return ut(me.pendingTotal)&&me.total===void 0?We({rows:xe,pendingTotal:yn(me.pendingTotal,b(T.pushed))}):(Me=null,!I.total&&me.total===void 0?We({rows:xe}):We({rows:xe,total:me.total??xe.length}))}T.unpushed.length&&oe(`source.pushdown.residual.${P}.${T.unpushed.join(".")}`,`the ${P} adapter cannot push ${T.unpushed.join(" or ")}, so every matching row is fetched and the rest is applied in the browser. Correct, and slower than it needs to be: widening the adapter is the fix.`);const Fe=b(T.pushed);if(!se||se.key!==Fe){const me=await De(await y.execute(T.pushed,x));Me=null;const xe=me.rows||[];if(T.full){const je=typeof me.total=="number"?Math.max(me.total,xe.length):xe.length;if(je>l.maxRows)throw new Error(`[lattice] fullDataset refused: the ${P} adapter's matching set is ${je.toLocaleString()} rows, past the configured maxRows of ${l.maxRows.toLocaleString()}. The whole set cannot be held client-side, so it is refused rather than truncated — a fraction shown as the whole would make every total and statistic silently wrong. Narrow the filter or raise maxRows.`);const Be=xe.length*E(xe[0]);if(Be>l.maxBytesEstimate)throw new Error(`[lattice] fullDataset refused: the ${P} adapter's matching set is an estimated ${Math.round(Be/(1024*1024)).toLocaleString()} MB across ${xe.length.toLocaleString()} rows, past the configured maxBytesEstimate of ${Math.round(l.maxBytesEstimate/(1024*1024)).toLocaleString()} MB. The whole set cannot be held client-side, so it is refused rather than truncated. Narrow the filter or raise maxBytesEstimate.`)}if(typeof me.total=="number"&&xe.length<me.total){const je=!!(T.residual.filters||T.residual.quick||T.residual.sort&&T.residual.sort.length);if(je&&!u)throw new Error(`[lattice] the ${P} adapter returned ${xe.length} of ${me.total} matching rows when asked for the whole result, and the query has residual ${T.unpushed.join(" and ")||"work"} to finish in the browser. Filtering or sorting a fraction of the result would return wrong rows, so the result is refused. Fix the adapter to follow the engine's own paging before returning, hold the data in memory, or set \`allowPartialResults: true\` on the source config to accept this knowingly.`);je?oe(`source.pushdown.partial.residual.${P}`,`the ${P} adapter returned ${xe.length} of ${me.total} matching rows when asked for the whole result, and residual work will run over that fraction. allowPartialResults is set, so the result is used as-is — it may be wrong. The adapter must follow the engine's own paging to be correct.`):oe(`source.pushdown.partial.${P}`,`the ${P} adapter returned ${xe.length} of ${me.total} matching rows when asked for the whole result. The adapter must follow the engine's own paging before returning.`)}se={key:Fe,rows:xe,total:typeof me.total=="number"?me.total:null}}let ue=T;if(T.residual.where){const me=se.total??se.rows.length;if(me>=k){ae(T.residual.where.names,P,me,k);const{where:xe,...je}=re.request;ue=He(je,I,l.enabled),ke=ue}}const et=se.total!==null&&se.rows.length>=se.total,ft=f(se.rows,{...ue.residual,whole:et},a.compute||{}),Ee=x.range?x.range.start:0,Ge=x.range?x.range.end:ft.length;return We({rows:ft.slice(Ee,Ge),total:ft.length})},Dt=async(x,C,U)=>{const T=U&&U.waitForPage&&Ue&&le(Ue.pageForegroundIdle)?Ue.pageForegroundIdle():rt();T&&await T;const we=Q();we&&await we;const fe=He(x,I,l.enabled);ke=fe;const We=B(C,Re),Fe=Array.isArray(x.groupBy)?x.groupBy:[],ue=Fe.length>0,et=!fe.residual.filters&&!fe.residual.quick,ft=!ue||J(Fe,I.buckets);let Ee=We.engine,Ge=We.client;if(I.aggregates&&Ee.length){const Be=I.aggregates instanceof Set?I.aggregates:new Set(be(I.aggregates)),ht=Ee.filter(Le=>!Be.has(Le.fn));ht.length&&(Ee=Ee.filter(Le=>Be.has(Le.fn)),Ge=[...ht.map(Le=>({...Le,reason:`the ${P} adapter does not compute "${Le.fn}"`})),...Ge])}const me=Be=>{Ge=[...Ee.map(ht=>({...ht,reason:Be})),...Ge],Ee=[]};Ee.length&&!et?me(fe.residual.quick&&!fe.residual.filters?"a quick search the adapter cannot push forces all-client (no mixed provenance)":"residual filter forces all-client (no mixed provenance)"):Ee.length&&!ft&&me("a grouping key the engine cannot form forces all-client (no mixed provenance)");let xe={},je;return Ee.length&&(le(ue?y.executeGroupedAggregates:y.executeAggregates)?ue?je=await y.executeGroupedAggregates(fe.pushed,Fe,Ee)||[]:xe=await y.executeAggregates(fe.pushed,Ee)||{}:(oe(`source.pushdown.aggregates.${P}${ue?".grouped":""}`,`the ${P} adapter cannot compute ${ue?"grouped ":""}aggregates, so every requested statistic is computed client-side. Correct, and slower than it needs to be.`),me(`adapter cannot compute ${ue?"grouped ":""}aggregates`))),ve={engine:Ee,client:Ge,...ue?{groupBy:Fe}:{}},{values:xe,engine:Ee,client:Ge,...je!==void 0?{groups:je}:{}}},wt=async x=>{Xe++;try{return await Rt(x)}finally{if(Xe--,Xe===0&&Ye.length){const C=Ye;Ye=[];for(const U of C)U()}}},ot=N(a.edit),Tt=a.edit&&typeof a.edit=="object"&&le(a.edit.commit);let It=a.edit;if(ot&&!Tt)if(I.mutate&&I.mutate.update){const x=C=>{if(!I.mutate||!I.mutate.update)throw new Error(`[lattice] the ${P} adapter cannot update rows (mutate.update is not declared), so this edit cannot be persisted. The cell is reverted rather than left looking saved.`);const U={kind:"update",key:String(C.key),patch:{[C.colId]:C.value}};return y.mutate(U,C.request||{})};It={...a.edit===!0?{}:a.edit,commit:x}}else oe(`source.pushdown.readonly.${P}`,`edit is enabled but the ${P} adapter declares mutate: ${I.mutate?"without update":"false"} (read-only by declaration), so no commit is synthesised and the grid stays read-only. Declare \`mutate: { update: true }\` on the adapter to allow cell edits.`);const ce=ot&&I.mutate&&(I.mutate.append||I.mutate.delete)?{append:I.mutate.append===!0,remove:I.mutate.delete===!0,returning:I.mutate.returning,mutate:(x,C)=>y.mutate(x,C||{})}:null,Se=async x=>{const C=Q();C&&await C;const{range:U,signal:re,export:T,...we}=x||{},fe={...we,groupBy:[],groupPath:[],groupValues:[],pivotBy:[],pivotMode:!1,totals:[]};return{plan:He(fe,I,l.enabled),signal:re}};async function*Ut(x,C={}){const{plan:U,signal:re}=await Se(x),T=Math.max(1,Math.floor(Number(C.pageSize))||5e3),we={signal:re,stream:!0};if(!U.needsAll)for(let Fe=0;;Fe+=T){ee(we);const ue=await y.execute({...U.pushed,range:{start:Fe,end:Fe+T}},we);ue&&ut(ue.pendingTotal)&&ue.pendingTotal.then(null,()=>{});const et=ue&&ue.rows||[];if(et.length&&(yield et),et.length<T)return}ee(we);const fe=await De(await y.execute({...U.pushed,range:void 0},we)),We=f(fe&&fe.rows||[],{...U.residual,whole:!0},a.compute||{});for(let Fe=0;Fe<We.length;Fe+=T)yield We.slice(Fe,Fe+T)}return Ue={...a,edit:It,rowMutate:ce,mode:"remote",fetch:wt,foregroundIdle:rt,aggregate:Dt,countMatching:async x=>{const{plan:C,signal:U}=await Se(x);if(!C.needsAll&&I.total){ee({signal:U});const T=await De(await y.execute({...C.pushed,range:{start:0,end:0}},{signal:U}));if(T&&typeof T.total=="number")return T.total}let re=0;for await(const T of Ut(x))re+=T.length;return re},streamMatching:Ut,lastPlan:()=>ke?{...ke,...ve?{aggregates:ve}:{},...Me?{total:{deferred:!0,state:Me.state,value:Me.value}}:{}}:null,fullFrame:dt,counts:()=>({match:Ve,total:_e??null,pending:!!Me&&Me.state==="pending"}),grandTotals:()=>Ne},Ue}}),mt("packages/core/src/model/rowkey.js",function(w,Te){"use strict";Object.defineProperty(w,"KEY_DEPENDENT_FEATURES",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(w,"compositeKey",{enumerable:!0,get:function(){return ae}}),Object.defineProperty(w,"createRowKey",{enumerable:!0,get:function(){return W}}),Object.defineProperty(w,"warnMissingKeys",{enumerable:!0,get:function(){return te}}),Object.defineProperty(w,"groupPathKey",{enumerable:!0,get:function(){return G}}),Object.defineProperty(w,"splitPathKey",{enumerable:!0,get:function(){return ne}});const ye=Te("packages/core/src/internal/util.js"),F=ye.warnOnce,le=ye.pathGetter,be=ye.isFunction,oe=ye.isBlank,Pe=["changes (rows.apply / rows.queue)","streaming dedupe","selection persistence","remote reload","cell comments"],D="";function Y($){if($===null)return"\0n";if($===void 0)return"\0u";const ee=typeof $;if(ee==="string")return $;if(ee==="number"||ee==="bigint"||ee==="boolean")return String($);if($ instanceof Date)return`\0d${$.getTime()}`;try{return`\0o${JSON.stringify($)}`}catch{return"\0o?"}}function ae($){if($.length===1)return Y($[0]);let ee="";for(let O=0;O<$.length;O++)O&&(ee+=D),ee+=Y($[O]);return ee}function W($,ee={}){const O=ee.warn!==!1;if(be($)){const R=$;return{stable:!0,fields:[],disabled:[],key(j,N){try{const H=R(j);return Array.isArray(H)?ae(H):Y(H)}catch(H){return F("rowKey.throw","rowKey function threw; falling back to index identity for the affected rows.",H),`#${N??-1}`}},keyEmpty(j){try{const N=R(j);return Array.isArray(N)?N.length===0||N.some(oe):oe(N)}catch{return!1}},missingFields(){return[]}}}if(Array.isArray($)&&$.length>0){const R=$.filter(H=>typeof H=="string"),j=R.map(H=>le(H)),N=j.length;return{stable:!0,fields:R,disabled:[],key(H){const q=new Array(N);for(let z=0;z<N;z++)q[z]=j[z](H);return ae(q)},keyEmpty(H){for(let q=0;q<N;q++)if(oe(j[q](H)))return!0;return!1},missingFields(H){const q=[];for(let z=0;z<N;z++)oe(j[z](H))&&q.push(R[z]);return q}}}if(typeof $=="string"&&$.length>0){const R=le($);return{stable:!0,fields:[$],disabled:[],key(j){return Y(R(j))},keyEmpty(j){return oe(R(j))},missingFields(j){return oe(R(j))?[$]:[]}}}return O&&F("rowKey.missing",`no rowKey configured, so rows are identified by object identity. This disables: ${Pe.join(", ")}. Set rowKey to a field name, an array of field names, or a function.`),{stable:!1,fields:[],disabled:Pe.slice(),key(R,j){if(R===null||typeof R!="object")return`#${j??0}:${String(R)}`;let N=B.get(R);return N===void 0&&(N=`#${J++}`,B.set(R,N)),N}}}const B=new WeakMap;let J=0;function te($,ee){if(!$||$.stable===!1||!be($.keyEmpty)||!Array.isArray(ee)||ee.length===0)return;let O=0,R=null,j;for(let z=0;z<ee.length;z++){const de=ee[z];$.keyEmpty(de)&&(O++,R===null&&(R=be($.missingFields)?$.missingFields(de):[],j=de))}if(O===0)return;const N=$.fields.length?$.fields.join(","):"(function)",H=R&&R.length?R.join(", "):$.fields.length?$.fields.join(", "):"the rowKey function",q=j!==null&&typeof j=="object"?Object.keys(j).join(", ")||"(no fields)":String(j);F(`rowKey.emptyValue:${N}`,`rowKey ${H} is missing on ${O} of ${ee.length} rows; the first such row has: ${q}. Rows without a key value collapse onto one key, so selection, edits and rows.apply updates land on whichever row now shares it. Set rowKey to a field present on every row, or fix the source data.`)}function G($){return ae($)}function ne($){return $.split(D)}}),mt("packages/modules/data-router/devtools.js",function(w,Te){"use strict";Object.defineProperty(w,"mountRouterDevtools",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(w,"default",{enumerable:!0,get:function(){return ae}});const F=Te("packages/core/src/internal/util.js").warnOnce,le="lat-router-devtools";function be(W,B,J){const te=W.createElement(B);return te.textContent=J==null?"—":String(J),te}function oe(W){return Number.isFinite(W)?`${Math.round(W*10)/10}/s`:"—"}function Pe(W,B,J,te){const G=W.createElement("section");G.className=`${le}-section`;const ne=W.createElement("h4");ne.textContent=B,G.appendChild(ne);const $=W.createElement("table"),ee=W.createElement("tr");for(const O of J)ee.appendChild(be(W,"th",O));$.appendChild(ee);for(const O of te){const R=W.createElement("tr");for(const j of O)R.appendChild(be(W,"td",j));$.appendChild(R)}return G.appendChild($),G}function D(W,B,J){B.textContent="";const te=Pe(W,"Router",["metric","value"],[["throughput",oe(J.throughput)],["unrouted",J.unrouted],["dropped (duplicate)",J.dropped],["buffer depth",J.buffered],["lag (deltas behind)",J.lag]]);B.appendChild(te),B.appendChild(Pe(W,"Routes",["#","label","kind","rows","shown","rows/sec"],J.routes.map(G=>[G.index,G.label,G.kind,G.rows,G.shown,oe(G.throughput)]))),J.sources.length&&B.appendChild(Pe(W,"Sources",["id","rows","ingested","rows/sec"],J.sources.map(G=>[G.id,G.rows,G.ingested,oe(G.throughput)])))}function Y(W,B,J={}){const te=B&&B.ownerDocument||(typeof document<"u"?document:null);if(!W||typeof W.metrics!="function"||typeof W.on!="function"||!B||!te)return F("data-router:devtools-target","router.mountDevtools(el) needs a router with metrics()/on() and a DOM element to render into; the panel was not mounted."),{destroy(){},refresh(){}};const G=te.createElement("div");G.className=le,B.appendChild(G);const ne=()=>D(te,G,W.metrics());ne();const $=W.on("metrics",()=>ne());return{refresh:ne,destroy(){$(),G.parentNode&&G.parentNode.removeChild(G)}}}const ae=Y}),mt("packages/core/src/format/date.js",function(w,Te){"use strict";Object.defineProperty(w,"scanPattern",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"toDate",{enumerable:!0,get:function(){return D}}),Object.defineProperty(w,"compilePattern",{enumerable:!0,get:function(){return W}}),Object.defineProperty(w,"compileDate",{enumerable:!0,get:function(){return J}}),Object.defineProperty(w,"toIsoDate",{enumerable:!0,get:function(){return te}}),Object.defineProperty(w,"toIsoDateTime",{enumerable:!0,get:function(){return G}}),Object.defineProperty(w,"compareIso",{enumerable:!0,get:function(){return ee}});const ye=Te("packages/core/src/internal/util.js"),F=ye.isNil,le=ye.warnOnce,be=["yyyy","yy","MMMM","MMM","MM","M","dd","d","EEEE","EEE","HH","H","hh","h","mm","m","ss","s","SSS","a"];function oe(O){const R=[];let j=0,N="";const H=()=>{N&&(R.push({token:null,text:N}),N="")};for(;j<O.length;){const q=O[j];if(q==="'"){if(O[j+1]==="'"){N+="'",j+=2;continue}const de=O.indexOf("'",j+1);if(de===-1){N+=O.slice(j+1),j=O.length;continue}N+=O.slice(j+1,de),j=de+1;continue}const z=be.find(de=>O.startsWith(de,j));if(z){H(),R.push({token:z,text:z}),j+=z.length;continue}/[A-Za-z]/.test(q)&&le(`date.pattern.token:${q}`,`the date pattern "${O}" contains '${q}', which is not a supported token, so it is rendered as text. Quote it as a literal to silence this. Supported: ${be.join(" ")}.`),N+=q,j+=1}return H(),R}const Pe=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?(?:\.\d+)?)?$/;function D(O){if(F(O)||O==="")return null;if(O instanceof Date)return Number.isNaN(O.getTime())?null:O;if(typeof O=="number")return Number.isNaN(O)?null:new Date(O);if(typeof O=="string"){const R=Pe.exec(O.trim());if(R){const[,N,H,q,z="0",de="0",qe="0"]=R;return new Date(+N,+H-1,+q,+z,+de,+qe)}const j=new Date(O);return Number.isNaN(j.getTime())?null:j}return null}function Y(O,R){return String(O).padStart(R,"0")}function ae(O){if(!O)return N=>({year:N.getFullYear(),month:N.getMonth()+1,day:N.getDate(),hour:N.getHours(),minute:N.getMinutes(),second:N.getSeconds(),ms:N.getMilliseconds(),weekday:N.getDay()});const R=new Intl.DateTimeFormat("en-US",{timeZone:O,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,weekday:"short"}),j={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};return N=>{const H={year:0,month:1,day:1,hour:0,minute:0,second:0,ms:N.getMilliseconds(),weekday:0};for(const q of R.formatToParts(N))switch(q.type){case"year":H.year=Number(q.value);break;case"month":H.month=Number(q.value);break;case"day":H.day=Number(q.value);break;case"hour":H.hour=Number(q.value)%24;break;case"minute":H.minute=Number(q.value);break;case"second":H.second=Number(q.value);break;case"weekday":H.weekday=j[q.value]??0;break;default:break}return H}}function W(O,R,j){const N=oe(O),H=ae(j),q=new Set(N.filter($e=>$e.token).map($e=>$e.token)),z=q.has("MMM")?new Intl.DateTimeFormat(R,{month:"short",timeZone:j}):null,de=q.has("MMMM")?new Intl.DateTimeFormat(R,{month:"long",timeZone:j}):null,qe=q.has("EEE")?new Intl.DateTimeFormat(R,{weekday:"short",timeZone:j}):null,Ce=q.has("EEEE")?new Intl.DateTimeFormat(R,{weekday:"long",timeZone:j}):null;return $e=>{const pe=H($e);let ie="";for(const Ke of N){if(!Ke.token){ie+=Ke.text;continue}switch(Ke.token){case"yyyy":ie+=Y(pe.year,4);break;case"yy":ie+=Y(pe.year%100,2);break;case"MMMM":ie+=de.format($e);break;case"MMM":ie+=z.format($e);break;case"MM":ie+=Y(pe.month,2);break;case"M":ie+=String(pe.month);break;case"dd":ie+=Y(pe.day,2);break;case"d":ie+=String(pe.day);break;case"EEEE":ie+=Ce.format($e);break;case"EEE":ie+=qe.format($e);break;case"HH":ie+=Y(pe.hour,2);break;case"H":ie+=String(pe.hour);break;case"hh":ie+=Y(pe.hour%12===0?12:pe.hour%12,2);break;case"h":ie+=String(pe.hour%12===0?12:pe.hour%12);break;case"mm":ie+=Y(pe.minute,2);break;case"m":ie+=String(pe.minute);break;case"ss":ie+=Y(pe.second,2);break;case"s":ie+=String(pe.second);break;case"SSS":ie+=Y(pe.ms,3);break;case"a":ie+=pe.hour<12?"AM":"PM";break;default:ie+=Ke.text;break}}return ie}}const B=[["year",365*24*36e5],["month",720*36e5],["week",168*36e5],["day",24*36e5],["hour",36e5],["minute",6e4],["second",1e3]];function J(O,R){const j=O||{},N=j.locale||R||void 0,H=j.nullDisplay??"",q=j.timeZone;let z;if(j.pattern)z=W(j.pattern,N,q);else if(j.dateStyle||j.timeStyle){const pe={timeZone:q};j.dateStyle&&(pe.dateStyle=j.dateStyle),j.timeStyle&&(pe.timeStyle=j.timeStyle);const ie=new Intl.DateTimeFormat(N,pe);z=Ke=>ie.format(Ke)}else{const pe=new Intl.DateTimeFormat(N,{dateStyle:"medium",timeZone:q});z=ie=>pe.format(ie)}const de=j.relative?new Intl.RelativeTimeFormat(N,{numeric:"auto"}):null,Ce=(typeof j.relative=="object"&&j.relative?j.relative.threshold??7:7)*24*36e5,$e=(pe,ie)=>{const Ke=D(pe);if(!Ke)return H;if(de){const kt=ie&&typeof ie.now=="number"?ie.now:Date.now(),He=Ke.getTime()-kt;if(Math.abs(He)<Ce){for(const[g,d]of B)if(Math.abs(He)>=d||g==="second")return de.format(Math.round(He/d),g)}}return z(Ke)};return $e.spec=j,$e}function te(O){if(F(O)||O==="")return null;if(typeof O=="string"){const N=/^(\d{4}-\d{2}-\d{2})/.exec(O.trim());if(N)return N[1];const H=D(O);return H?te(H):null}const R=D(O);if(!R)return null;const j=N=>String(N).padStart(2,"0");return`${R.getFullYear()}-${j(R.getMonth()+1)}-${j(R.getDate())}`}function G(O,R){if(F(O)||O==="")return null;if(typeof O=="string"){const N=O.trim();if(ne.test(N)){const z=D(N);return z?$(z,R):null}const H=/^(\d{4}-\d{2}-\d{2})[T ](\d{2}):(\d{2})(?::(\d{2}))?/.exec(N);if(H){const[,z,de,qe,Ce]=H;return`${z}T${de}:${qe}${Ce&&Ce!=="00"?`:${Ce}`:""}`}if(/^\d{4}-\d{2}-\d{2}$/.test(N))return`${N}T00:00`;const q=D(N);return q?G(q):null}const j=D(O);return j?$(j,R):null}const ne=/(?:Z|[+-]\d{2}:?\d{2})$/i;function $(O,R){const j=z=>String(z).padStart(2,"0");if(R)try{const z=new Intl.DateTimeFormat("en-CA",{timeZone:R,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(O).reduce((Ce,$e)=>($e.type!=="literal"&&(Ce[$e.type]=$e.value),Ce),{}),de=z.hour==="24"?"00":z.hour,qe=Number(z.second);return`${z.year}-${z.month}-${z.day}T${de}:${z.minute}`+(qe?`:${z.second}`:"")}catch{}const N=`${O.getFullYear()}-${j(O.getMonth()+1)}-${j(O.getDate())}`,H=O.getSeconds(),q=`${j(O.getHours())}:${j(O.getMinutes())}${H?`:${j(H)}`:""}`;return`${N}T${q}`}function ee(O,R){const j=F(O)||O===""?null:String(O),N=F(R)||R===""?null:String(R);return j===null?N===null?0:1:N===null||j<N?-1:j>N?1:0}}),mt("packages/core/src/format/boolean.js",function(w,Te){"use strict";Object.defineProperty(w,"toTriState",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"compileBoolean",{enumerable:!0,get:function(){return Pe}});const F=Te("packages/core/src/internal/util.js").isNil,le={true:"☑",false:"☐",null:""},be={true:"◉",false:"◯",null:""};function oe(D){if(F(D)||D==="")return null;if(typeof D=="boolean")return D;if(typeof D=="number")return D!==0;const Y=String(D).trim().toLowerCase();return Y==="true"||Y==="yes"||Y==="y"||Y==="1"?!0:Y==="false"||Y==="no"||Y==="n"||Y==="0"?!1:null}function Pe(D,Y){const ae=D||{},W=ae.display||"text",B=ae.trueLabel??"Yes",J=ae.falseLabel??"No",te=ae.nullLabel??"";let G=B,ne=J;const $=te;W==="checkbox"?(G=le.true,ne=le.false):W==="switch"?(G=be.true,ne=be.false):W==="icon"&&(G=ae.trueIcon??B,ne=ae.falseIcon??J);const ee=O=>{const R=oe(O);return R===null?$:R?G:ne};return ee.display=W,ee.labels={true:B,false:J,null:te},ee.locale=Y,ee.spec=ae,ee}}),mt("packages/modules/data-router/index.js",function(w,Te){"use strict";Object.defineProperty(w,"createDataRouter",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(w,"default",{enumerable:!0,get:function(){return He}});const F=Te("packages/core/src/internal/util.js").warnOnce,le=Te("packages/core/src/source/pushdown.js"),be=le.planQuery,oe=le.capabilitiesOf,D=Te("packages/core/src/model/rowkey.js").compositeKey,ae=Te("packages/modules/data-router/devtools.js").mountRouterDevtools,W=Te("packages/core/src/format/date.js"),B=W.toIsoDate,J=W.scanPattern,G=Te("packages/core/src/format/boolean.js").toTriState;function ne(g,d){return typeof g=="function"?g:typeof g=="string"?f=>f[g]:d}function $(g,d){if(!g||typeof g!="object"||typeof d!="string")return;if(!d.includes("."))return g[d];let f=g;for(const b of d.split(".")){if(!f||typeof f!="object")return;f=f[b]}return f}function ee(g,d){const f=d.split(".");if(f.length===1){delete g[d];return}let b=g;for(let E=0;E<f.length-1;E+=1)if(b=b[f[E]],!b||typeof b!="object")return;delete b[f[f.length-1]]}function O(g){return Array.isArray(g)?"array":g===null?"null":typeof g}function R(g,d){if(g===void 0||typeof g=="string"&&g.length>0)return g;if(typeof g=="function")return f=>{const b=g(f);if(typeof b=="string"||typeof b=="number"&&Number.isFinite(b))return b;throw new Error(`lattice-data-router: rowKey function must return a string or number; got ${O(b)}.`)};throw new Error(`lattice-data-router: rowKey must be a property name or a function; composite keys are not supported on ${d}.`)}function j(g){if(typeof g=="function")return g;if(g&&typeof g=="object"&&typeof g.key=="string"){const d=g.dir==="desc"?-1:1,{key:f}=g;return(b,E)=>{const K=b?b[f]:void 0,V=E?E[f]:void 0;return K<V?-1*d:K>V?1*d:0}}return null}function N(g){if(!g||typeof g!="object")return null;let d=0;Number.isFinite(g.minInterval)&&g.minInterval>0?d=Number(g.minInterval):Number.isFinite(g.maxHz)&&g.maxHz>0&&(d=1e3/Number(g.maxHz));const f=Number.isFinite(g.sample)&&g.sample>1?Math.floor(Number(g.sample)):1,b=Number.isFinite(g.maxLag)&&g.maxLag>=0?Math.floor(Number(g.maxLag)):null;return d===0&&f===1&&b===null?null:{minInterval:d,sample:f,maxLag:b}}let H=0;function q(){return H+=1,`r${H}`}function z(g){const f=(Array.isArray(g)?g:[g]).map(b=>({name:typeof b=="string"?b:null,get:ne(b,()=>{})}));return b=>{const E={},K=[];for(const V of f){const ze=V.get(b);K.push(ze),V.name&&(E[V.name]=ze)}return{key:D(K),fields:E}}}function de(g,d){if(typeof g=="function")return g(d);if(g&&typeof g=="object"){const{op:f,field:b}=g;if(f==="count")return d.length;const E=b!=null?d.map(K=>Number(K[b])).filter(K=>Number.isFinite(K)):[];if(f==="sum")return E.reduce((K,V)=>K+V,0);if(f==="avg")return E.length?E.reduce((K,V)=>K+V,0)/E.length:0;if(f==="min")return E.length?Math.min(...E):void 0;if(f==="max")return E.length?Math.max(...E):void 0}}function qe(g){return g&&typeof g=="object"&&typeof g.from=="string"&&typeof g.to=="string"?{from:g.to,to:g.from}:(F("data-router:mutual-fn","relate({ mutual: true }) with a function relation cannot be inverted; the same predicate is applied in both directions. Use a { from, to } key map for a mutual edge."),g)}function Ce(g,d){return g?d?{op:"and",conditions:[g,d]}:g:d||null}const $e=Object.freeze(["eq","ne","lt","lte","gt","gte","between","notBetween","in","notIn","contains","notContains","startsWith","endsWith","blank","notBlank"]);function pe(g,d){const f=d?d[g.col]:void 0,b=g.value,E=K=>g.caseSensitive?String(K):String(K).toLowerCase();switch(g.op){case"eq":return f===b;case"ne":return f!==b;case"lt":return f<b;case"lte":return f<=b;case"gt":return f>b;case"gte":return f>=b;case"between":return Array.isArray(b)&&f>=b[0]&&f<=b[1];case"notBetween":return!(Array.isArray(b)&&f>=b[0]&&f<=b[1]);case"in":return Array.isArray(b)&&b.includes(f);case"notIn":return!(Array.isArray(b)&&b.includes(f));case"contains":return f!=null&&E(f).includes(E(b));case"notContains":return f==null||!E(f).includes(E(b));case"startsWith":return f!=null&&E(f).startsWith(E(b));case"endsWith":return f!=null&&E(f).endsWith(E(b));case"blank":return f==null||f==="";case"notBlank":return!(f==null||f==="");default:throw new Error(`[lattice] query() cannot evaluate the residual filter operator "${String(g.op)}" on column "${String(g.col)}" client-side, so the query is refused rather than returning rows the filter excludes. Push it down to an adapter that implements it, or use an operator this router evaluates: ${$e.join(", ")}.`)}}function ie(g,d){return g?Array.isArray(g.conditions)?g.op==="or"?g.conditions.some(f=>ie(f,d)):g.op==="not"?!g.conditions.every(f=>ie(f,d)):g.conditions.every(f=>ie(f,d)):pe(g,d):!0}function Ke(g={}){const d=ne(g.key,()=>{}),f=ne(R(g.rowKey,"routes"),e=>e.rowKey),b=typeof g.key=="string"?g.key:null,E=!!g.overlap,K=typeof g.onUnrouted=="function"?g.onUnrouted:null,V=Number.isFinite(g.selectionDebounce)?Number(g.selectionDebounce):16,ze=typeof g.onWrite=="function"?g.onWrite:null,ut=typeof g.onConflict=="function"?g.onConflict:null,De=g.seq!=null?ne(g.seq,()=>{}):null,nt=De?g.dedupe!==!1:!1,a=f;let y=null;typeof g.batch=="number"?y=g.batch:g.batch&&Number.isFinite(g.batch.intervalMs)&&(y=Number(g.batch.intervalMs));const I=y!==null||!!g.coalesce,_=new Map;let P,X=0;const Q=[];let l=null;const u=g.time!=null?ne(g.time,()=>{}):null,k=typeof g.now=="function"?g.now:Date.now,M=1e4;let Re=!1,se=null,ke=null,ve="time",Ve=new Map;const Ne=[];let _e=0,Me,yt,bt=!1,dt=null,Ft=[],xt=0,pt=0,mn="time",Pt=!1,ct=null,vt=null;const $t=e=>{if(e&&Number.isFinite(e.seq))return e.seq;if(De&&e&&e.row){const n=De(e.row);return Number.isFinite(n)?n:void 0}},yn=e=>{if(e&&Number.isFinite(e.t))return e.t;if(u&&e&&e.row){const n=u(e.row);if(Number.isFinite(n))return n}return k()},Xe=[];let Ye=null;const rt=[],Ue=[],Rt=new Map,Dt=new Set;let wt=null,ot=0;const Tt=new Map,It=new Set,ce=typeof g.rowKey=="string"?g.rowKey:"rowKey",Se=new Map;let Ut=0;const Xt=new Set,x=[],C=new Map,U=(e,n)=>{C.set(e,(C.get(e)||0)+n)};let re=0;const T=new Map,we=new Map;let fe=null;const We=Number.isFinite(g.metricsInterval)?Number(g.metricsInterval):1e3;let Fe=0,ue=null,et="lattice-router",ft=250,Ee=null,Ge=null,me=!1,xe=!1,je=null,Be=!1,ht=null;const Le=[],Oe=()=>Ye?[...Xe,Ye]:Xe,St=e=>Oe().find(n=>n.grid===e)||null,Et=e=>{const n=[];for(const t of Xe)if(t.match(e)&&(n.push(t),!E))break;return n.length?n:Ye?[Ye]:[]},bn=e=>e.hasPartValue?e.partValue:e.label!=null?e.label:e.grid,Z=e=>{for(const n of Oe())if(n.grid===e)return n;for(const n of Oe())if(n.hasPartValue&&n.partValue===e||n.label!=null&&n.label===e)return n;return null},Qe=(e,n)=>{if(n.add.length||n.update.length||n.remove.length){const t=e.sink(n);it(e,t)}return{added:n.add.length,updated:n.update.length,removed:n.remove.length}},it=(e,n)=>{const t=n?.rejected;if(!Array.isArray(t)||!t.length)return;const r=t.filter(i=>i&&i.operation==="remove");if(!r.length)return;const o=e.label||`route ${e.routeId}`;F(`data-router:remove-rejected:${e.routeId}`,`route "${o}" asked its target to remove ${r.length} row(s) the target does not have (for example ${JSON.stringify(String(r[0].id))}). The rows are still on screen. This is a key mismatch: the key the route derives for a row is not the key the grid derives for it. Check that the route's \`rowKey\` names the same value as the grid's.`)},wn=(e,n)=>{for(const t of rt)if(t.to===e.grid&&t.predicate&&!t.predicate(n))return!1;if(e.graphPreds){for(const t of e.graphPreds)if(!t(n))return!1}return!0},jt=e=>{const n=qt(),t=[];for(const h of e.partition.values()){if(e.filter&&!e.filter(h)){if(he){const m=String(h[ce]);at(m,{kind:"filter",passed:!1}),st(m,"filter-rejected","the route's filter rejected this row.")}continue}if(!wn(e,h)){if(he){const m=String(h[ce]);at(m,{kind:"filter",passed:!1}),st(m,"filter-rejected","a cross-grid link/graph predicate rejected this row.")}continue}he&&at(String(h[ce]),{kind:"filter",passed:!0}),t.push(h)}if(e.explain.filterIn=e.partition.size,e.explain.filterOut=t.length,Xt.size){const h=new Map;for(const L of t)for(const S of Object.keys(L))Xt.has(S)&&L[S]!==void 0&&!h.has(S)&&h.set(S,!0);const m=e.spreadFields||(e.spreadFields=new Map),v=[],A=[];for(const L of h.keys())m.has(L)||v.push(L);for(const L of m.keys())h.has(L)||A.push(L);v.length||A.length?(e.spreadFields=h,cr("fields:changed",{route:bn(e),added:v,removed:A})):e.spreadFields=h}let r;const o=he&&!e.rollup?new Map:null;if(e.rollup){const h=new Map;for(const v of t){const{key:A,fields:L}=e.rollup.group(v);let S=h.get(A);S||(S={key:A,fields:L,rows:[]},h.set(A,S)),S.rows.push(v)}if(he)for(const v of h.values())for(const A of v.rows)at(String(A[ce]),{kind:"rollup",groupKey:v.key,memberCount:v.rows.length});let m=[];for(const v of h.values()){const A={...v.fields};for(const[L,S]of e.rollup.specs)A[L]=de(S,v.rows);m.push({gkey:v.key,row:A})}e.explain.rollupIn=t.length,e.explain.rollupGroups=h.size,e.explain.rollupOut=m.length,e.sort&&(e.explain.sortCount=m.length,m.sort((v,A)=>e.sort(v.row,A.row))),e.explain.transformIn=m.length,e.transform&&(m=m.map(v=>({gkey:v.gkey,row:e.transform(v.row)}))),e.explain.transformOut=m.length,r=new Map(m.map(v=>[v.gkey,v.row]))}else{let h=t;if(e.sort&&(e.explain.sortCount=h.length,h=h.slice().sort(e.sort),he))for(const m of h)at(String(m[ce]),{kind:"sort",passed:!0});e.explain.transformIn=h.length,e.explain.transformOut=h.length,r=new Map;for(const m of h){const v=D([e.keyOf(m)]);he&&(e.transform&&at(String(m[ce]),{kind:"transform",passed:!0}),o.set(v,String(m[ce]))),r.set(v,e.transform?e.transform(m):m)}}const i=[],s=[],c=[];for(const[h,m]of r)e.keys.has(h)?kt(e.keys.get(h),m)||(s.push(m),he&&o&&gr(o.get(h),e,"update")):(i.push(m),he&&o&&gr(o.get(h),e,"add"));for(const h of e.keys.keys())r.has(h)||c.push(h);e.keys=r;const p=Qe(e,{add:i,update:s,remove:c});return e.explain.writeAdd=p.added,e.explain.writeUpdate=p.updated,e.explain.writeRemove=p.removed,e.explain.timingMs+=qt()-n,p},en=e=>{e.bpTimer&&(clearTimeout(e.bpTimer),e.bpTimer=null),jt(e),e.bpPending=0,e.bpLastFlush=k()},br=(e,n)=>{if(e.bpTimer)return;const t=e.bp.minInterval>0?Math.max(e.bp.minInterval-(n-e.bpLastFlush),0):0;e.bpTimer=setTimeout(()=>{e.bpTimer=null,At();try{en(e)}finally{Nt()}},t),e.bpTimer&&typeof e.bpTimer.unref=="function"&&e.bpTimer.unref()},wr=(e,n,t)=>{if(!e.bp){jt(e);return}e.bpPending+=n,e.bpCoalesced+=n;const r=e.bp;if(r.maxLag!=null&&e.bpPending<=r.maxLag&&!e.bpTimer){en(e);return}const o=k(),i=o-e.bpLastFlush>=r.minInterval,s=e.bpPending>=r.sample;if(i&&s){en(e);return}if(he&&t)for(const c of t)st(String(c[ce]),"not-yet-flushed","this route is backpressured; the write is deferred to a trailing flush.");br(e,o)},kr=e=>{e.bpTimer&&(clearTimeout(e.bpTimer),e.bpTimer=null),e.bpPending=0,e.bpLastFlush=k()},kn=(e,n)=>{if(typeof e=="function"){const t=e(n);return typeof t=="function"?t:null}if(e&&typeof e=="object"){const t=e.from,r=e.to,o=new Set(n.map(i=>i&&i[t]));return i=>o.has(i&&i[r])}return null},vn=e=>{const n=St(e),t=e&&e.selection,r=t&&typeof t.keys=="function"?t.keys():[];return!r.length||!n?[]:r.map(o=>n.partition.get(String(o))).filter(o=>o!==void 0)},vr=e=>{const n=e&&e.selection;if(!n||typeof n.predicate!="function")return null;const t=n.predicate();if(!t||t.all!==!0)return null;const r=typeof n.count=="function"?n.count():Promise.resolve(null);return{predicate:t,count:r}},Ht=e=>{const n=vr(e.from);if(n){if(typeof e.relation=="function"&&e.relation.length>=2){const r=e.relation(vn(e.from),n);e.predicate=typeof r=="function"?r:null}else F("data-router:link-predicate-unsupported","link()/relate() source grid has every row matching a filter selected on a source that holds only the rows it has loaded. The relation does not declare it accepts a predicate selection — a function taking (selected, { predicate, count }) as its second parameter — so the link cannot build a target-row predicate from a truncated key list and imposes no constraint."),e.predicate=null;return}const t=vn(e.from);e.predicate=t.length?kn(e.relation,t):null},Gt=()=>{const e=new Set;for(const n of Ue)e.add(n.from),e.add(n.to);return e},Mt=()=>{for(const i of Oe())i.graphPreds=null;if(!Ue.length)return;const e=Gt(),n=new Map;for(const i of e){const s=vn(i);s.length&&n.set(i,s)}const t=new Map(n);let r=!0,o=(e.size+1)*2;for(;r&&o-- >0;){r=!1;for(const i of e){if(n.has(i))continue;const s=Ue.filter(v=>v.to===i&&t.has(v.from));if(!s.length)continue;const c=St(i);if(!c)continue;const p=s.map(v=>kn(v.rel,t.get(v.from))).filter(Boolean),h=[];for(const v of c.partition.values())p.every(A=>A(v))&&h.push(v);const m=t.get(i);if(!m||m.length!==h.length)t.set(i,h),r=!0;else{const v=new Set(m);h.some(A=>!v.has(A))&&(t.set(i,h),r=!0)}}}for(const i of Ue){if(!t.has(i.from))continue;const s=kn(i.rel,t.get(i.from));if(!s)continue;const c=St(i.to);c&&(c.graphPreds||(c.graphPreds=[])).push(s)}},zn=e=>{const n=Rt.get(e);if(n){n.count+=1;return}const t=e&&typeof e.on=="function"?e.on("selection:changed",()=>Sr(e)):()=>{};Rt.set(e,{off:t,count:1})},Sn=()=>{wt&&(clearTimeout(wt),wt=null);const e=Dt;if(!e.size)return;const n=new Set;for(const t of rt)e.has(t.from)&&(Ht(t),n.add(t.to));if(Dt.clear(),Ue.length){Mt();for(const t of Gt())n.add(t)}for(const t of n){const r=St(t);r&&jt(r)}},Sr=e=>{if(Dt.add(e),V<=0){Sn();return}wt||(wt=setTimeout(Sn,V))},Un=e=>{const n=Rt.get(e);n&&(n.count-=1,n.count<=0&&(n.off(),Rt.delete(e)))},Er=e=>typeof e=="function"?n=>e(n):e&&e.rows&&typeof e.rows.apply=="function"?n=>e.rows.apply(n):(F("data-router:bad-target","attach/subscribe target has no rows.apply and is not a function; its slice goes nowhere. Pass a grid or a handler(change) function."),()=>{}),En=(e,n,t)=>({grid:e,routeId:q(),sink:Er(e),match:n,keyOf:ne(R(t.rowKey,"routes"),f),partition:new Map,keys:new Map,transform:typeof t.transform=="function"?t.transform:null,filter:typeof t.filter=="function"?t.filter:null,sort:j(t.sort),rollup:t.rollup&&t.rollup.groupBy!=null?{group:z(t.rollup.groupBy),specs:Object.entries(t.rollup.aggregate||{})}:null,where:t.where&&typeof t.where=="object"?t.where:null,graphPreds:null,onWrite:typeof t.onWrite=="function"?t.onWrite:null,onConflict:typeof t.onConflict=="function"?t.onConflict:null,writable:t.writable===!0,readonly:!!(t.rollup&&t.rollup.groupBy!=null||typeof t.transform=="function"),label:typeof t.label=="string"?t.label:null,metricRows:0,bp:N(t.backpressure),bpPending:0,bpTimer:null,bpLastFlush:-1/0,bpCoalesced:0,explain:hr()}),Gn=e=>{if(!E){for(const n of Xe)if(n.hasPartValue&&n.partValue===e){F(`data-router:overlap:${String(e)}`,`Data Router: value ${JSON.stringify(e)} already routes to another viewer; with overlap:false only the first receives rows. Pass createDataRouter({ overlap: true }) to fan one value to several viewers.`);return}}},Vn=(e,n)=>`${String(e)}${String(n)}`,jr=e=>{const n=e&&e.row;if(!n)return null;const t=n.data&&typeof n.data=="object"?n.data:n;return t?{...t}:null},tn=(e,n)=>{const t=e.grid;if(!t||!t.edit||typeof t.edit.setCells!="function")return;const r=Vn(n.key,n.colId);It.add(r);try{t.edit.setCells([{key:n.key,colId:n.colId,value:n.before}],"cell")}finally{It.delete(r)}U("writeReverted",1)},_n=e=>{e&&tt.apply([{op:"upsert",row:e}])},Jn=(e,n,t)=>{const r=t&&typeof t=="object"?t:null,o=r&&r.conflict!==void 0?r.conflict:null;if(o){const i=e.onConflict||ut;if(i)try{i(n,{serverRow:o})}catch{}U("writeConflicted",1),_n(r&&r.row?r.row:n.row);return}if(t===!1||r&&r.ok===!1){U("writeRejected",1),tn(e,n);return}U("writeAccepted",1),_n(r&&r.row?r.row:n.row)},Or=e=>{const n=String(e);for(const t of Se.values())if(t.live.has(n))return t.handle;return null},Pr=(e,n)=>{if(!n||n.key===void 0||n.colId===void 0||It.has(Vn(n.key,n.colId)))return;const t=jr(n),r={key:String(n.key),colId:String(n.colId),value:n.value,before:n.oldValue,row:t};if(U("writeRouted",1),e.readonly){F("data-router:readonly-write","an edit on a derived (rollup/transform) route is read-only and was reverted; a derived row cannot be inverted to a source row. Make the source route writable instead."),tn(e,r);return}const o=e.onWrite||ze;if(!o){F("data-router:no-onwrite","a route attached with { writable: true } has no onWrite handler (per-route or router-global); the edit was left in place but not persisted. Pass onWrite to route the write.");return}let i;try{i=o(r,{route:e.grid,source:Or(r.key)})}catch{tn(e,r),U("writeRejected",1);return}i&&typeof i.then=="function"?i.then(s=>Jn(e,r,s),()=>{tn(e,r),U("writeRejected",1)}):Jn(e,r,i)},Rr=e=>{const n=e.grid;if(!n||typeof n.on!="function"||!n.edit||typeof n.edit.setCells!="function"){F("data-router:writable-target","attach({ writable: true }) needs a grid exposing grid.on and grid.edit.setCells; write-back is off for this route.");return}if(Tt.has(n))return;const t=n.on("cell:changed",r=>Pr(e,r));Tt.set(n,typeof t=="function"?t:()=>{})},Tr=e=>{const n=[];for(const t of e.partition.values())e.filter&&!e.filter(t)||n.push(t);return e.explain&&(e.explain.filterIn=e.partition.size,e.explain.filterOut=n.length),n},nn=e=>{const n=Tr(e);if(e.kind==="monitor"){let r;try{r=e.evaluate(n)}catch{r=void 0}e.handler(r,n);return}let t;try{t=e.condition(n)}catch{t=!1}if(t){if(!e.armed)return;e.debounceMs>0?(e.pending={signal:t,rows:n},e.timer||(e.timer=setTimeout(()=>{e.timer=null;const r=e.pending;e.pending=null,r&&(e.armed=!1,e.handler(r.signal,r.rows))},e.debounceMs))):(e.armed=!1,e.handler(t,n))}else e.armed=!0,e.timer&&(clearTimeout(e.timer),e.timer=null),e.pending=null},jn=(e,n)=>{e.partition=new Map;for(const t of n)e.match(t)&&e.partition.set(String(e.keyOf(t)),t);e.explain&&(e.explain.whenRouted=e.partition.size)},Ar=(e,n)=>{for(const t of n){const r=t&&t.row;if(!r)continue;const o=String(e.keyOf(r));if(t.op==="delete"){e.partition.delete(o);continue}e.match(r)?(e.partition.set(o,r),e.explain&&(e.explain.whenRouted+=1)):e.partition.delete(o)}},Vt=()=>{const e=new Map;for(const n of Oe())for(const t of n.partition.values())e.set(String(a(t)),t);return[...e.values()]},Yn=()=>{Ve=new Map;for(const e of Oe())for(const n of e.partition.values())Ve.set(String(a(n)),n);Ne.length=0,_e=0,Me=P,yt=void 0},Qn=()=>{const e=Ne.shift();e&&(e.op==="del"?Ve.delete(e.key):Ve.set(e.key,e.row),Me=e.seq,yt=e.t)},Nr=()=>{if(se!=null)for(;Ne.length>se;)Qn();if(ke!=null&&Ne.length){const e=Ne[Ne.length-1].t;for(;Ne.length>1&&e-Ne[0].t>ke;)Qn()}},Fr=e=>{!e||!e.row||Ne.push({pos:_e++,seq:$t(e),t:yn(e),op:e.op==="delete"?"del":"set",key:String(a(e.row)),row:e.row})},On=(e,n)=>n==="seq"?e.seq:e.t,rn=(e,n)=>{const t=new Map(Ve);for(const r of Ne){const o=On(r,n);if(e!==void 0&&o!==void 0&&o>e)break;r.op==="del"?t.delete(r.key):t.set(r.key,r.row)}return t},on=e=>{const n=new Map(Oe().map(t=>[t,[]]));for(const t of e)for(const r of Et(t))n.get(r).push(t);for(const t of Oe())t.partition=new Map(n.get(t).map(r=>[String(t.keyOf(r)),r]));for(const t of rt)Ht(t);Mt();for(const t of Oe())jt(t)},Pn=e=>Re?!0:(F("data-router:no-buffer",`${e}() needs a buffered window; call router.buffer({ window, max }) first to record one.`),!1),sn=()=>{if(ct&&(clearTimeout(ct),ct=null),Pt=!1,Ft=[],xt=0,vt){const e=vt;vt=null,e()}},xr=()=>{if(Ft=[],xt=0,vt){const e=vt;vt=null,e()}},$r=()=>{ct=null;const e=Ft[xt++];e.op==="del"?dt.delete(e.key):dt.set(e.key,e.row),on([...dt.values()]),Fe=e.pos+1,Rn()};function Rn(){if(!Pt){if(xt>=Ft.length){xr();return}ct=setTimeout($r,pt)}}function ln(e){if(je)try{je.postMessage(e)}catch{}}function Zn(){return{t:"snapshot",rows:Vt(),seq:P,checkpoint:Object.fromEntries(_)}}function Dr(e){const n=e&&e.data;if(!(!n||typeof n!="object")){if(n.t==="hello"){Vt().length&&ln(Zn());return}Be=!0;try{n.t==="delta"?tt.apply(n.deltas||[]):n.t==="snapshot"&&(tt.load(n.rows||[]),n.checkpoint&&tt.seenThrough(n.checkpoint))}finally{Be=!1}}}function Ir(e,n){e.partition=new Map(n.map(t=>[String(e.keyOf(t)),t]))}function Mr(e,n){const t=n.filter(o=>!o.isDefault),r=n.find(o=>o.isDefault)||null;for(const o of n)o.partition=new Map;for(const o of e){const i=[];for(const c of t)if(c.match(o)&&(i.push(c),!E))break;const s=i.length?i:r?[r]:[];if(!s.length){ot+=1,K&&K(o);continue}for(const c of s)c.partition.set(String(c.keyOf(o)),o)}}const Lr=(e,n)=>{if(typeof n=="function")return r=>n(r);let t=null;return n===!0?t=String(e):typeof n=="string"&&(t=n),t==null?null:(r,o=ce)=>`${t}:${r[o]}`},Xn=(e,n)=>{const t={...e.map?e.map(n):n},r=he&&e.fields?[]:null;if(e.fields&&Gr(e,t,r),e.ns){const o=Cr(e,t),i=e.ns(t,o||ce);o&&(t[o]=i),t[ce]=i}if(he){const o=n?.[ce],i=String(t[ce]),s=Qt(e.id,o,i);r&&r.length&&s.steps.push({kind:"fields",changes:r}),s.lastRow=t,t[ce]==null&&st(i,"coerced-invalid-key",`source "${e.id}": the row's key resolved to ${String(t[ce])}, so it cannot be routed.`)}return t},Cr=(e,n)=>{if(typeof g.rowKey!="function")return null;if(e.keyProp!==void 0)return e.keyProp;const t=new Set;try{g.rowKey(new Proxy(n,{get(r,o,i){return typeof o=="string"&&t.add(o),Reflect.get(r,o,i)}}))}catch{}return e.keyProp=t.size===1?[...t][0]:null,e.keyProp===null&&F(`data-router:function-key-namespace:${e.id}`,`addSource("${e.id}") sets \`key\` but the rowKey function does not read exactly one row property, so its ids cannot be namespaced and rows from different feeds sharing an id will replace one another. Use a property-name rowKey, or give each feed ids that are already distinct.`),e.keyProp},er=(e,n)=>{const t=[];for(const r of n||[]){if(!r||!r.row)continue;const o=Xn(e,r.row),i=String(o[ce]);r.op==="delete"?(e.live.delete(i),e.explain.rowsRemoved+=1):(e.live.set(i,o),e.explain.rowsApplied+=1),t.push({...r,row:o})}return e.ingested+=t.length,U(`source:${e.id}`,t.length),t},tr=e=>({get id(){return e.id},get size(){return e.live.size},load(n){At();try{const t=(n||[]).map(i=>Xn(e,i)),r=new Map(t.map(i=>[String(i[ce]),i])),o=[];for(const[i,s]of e.live)r.has(i)||o.push({op:"delete",row:s});for(const i of t)o.push({op:"upsert",row:i});return e.live=r,e.ingested+=t.length,U(`source:${e.id}`,t.length),e.explain.rowsLoaded+=t.length,e.explain.rowsRemoved+=o.length-t.length,_t(e,o,i=>tt.apply(i)),this}finally{Nt()}},apply(n){At();try{return _t(e,er(e,n),t=>tt.apply(t)),this}finally{Nt()}},push(n){At();try{return _t(e,er(e,Array.isArray(n)?n:[n]),t=>tt.push(t)),this}finally{Nt()}},remove(){At();try{const n=[];for(const t of e.live.values())n.push({op:"delete",row:t});return e.explain.rowsRemoved+=n.length,e.live.clear(),Se.delete(e.id),n.length&&tt.apply(n),tt}finally{Nt()}}}),an=new Set(["text","number","integer","boolean","date","json"]),nr=(e,n=".")=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;let t=e.trim();if(t===""||/\d\s*[*/^]\s*[\d.(]/.test(t)||(t=t.replace(/[\s\u00a0\u202f\u2009']/g,""),n===","?t=t.split(".").join("").replace(",","."):t=t.split(",").join(""),t=t.replace(/[^0-9eE+\-.]/g,""),t===""||t==="-"||t==="+"||t==="."||t==="-."||t==="+."))return null;const r=Number(t);return Number.isFinite(r)?r:null},Wr=e=>{if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean"||e==null)return String(e);try{return JSON.stringify(e)}catch{return String(e)}},Br=(e,n,t)=>{F(`router:coerce-failed:${e.id}:${n.name}`,`source "${e.id}" field "${n.name}": could not coerce ${Wr(t)} to ${n.type}; the value is stored as null.`)},Kr=(e,n)=>{if(typeof n=="string")return an.has(n)?{name:e,type:n,format:null,decimal:null,trueSet:null,falseSet:null,nulls:null}:(F("data-router:field-type",`addSource field "${e}" names an unknown type "${n}" (expected ${[...an].join(", ")}); the field passes through uncoerced.`),null);if(n&&typeof n=="object"&&!Array.isArray(n)){const t=n.type==null?null:String(n.type);return t!=null&&!an.has(t)?(F("data-router:field-type",`addSource field "${e}" names an unknown type "${t}" (expected ${[...an].join(", ")}); the field passes through uncoerced.`),null):{name:e,type:t,format:typeof n.format=="string"?n.format:null,decimal:n.decimal===","||n.decimal==="."?n.decimal:null,trueSet:Array.isArray(n.true)&&n.true.length?new Set(n.true.map(String)):null,falseSet:Array.isArray(n.false)&&n.false.length?new Set(n.false.map(String)):null,nulls:Array.isArray(n.nulls)&&n.nulls.length?new Set(n.nulls.map(String)):null}}return F("data-router:field-spec",`addSource field "${e}" has an unusable fields declaration (a type string or an options object); the field passes through uncoerced.`),null},Hr=e=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const n=[];for(const[t,r]of Object.entries(e)){const o=Kr(t,r);o&&n.push(o)}return n.length?n:null},qr=(e,n)=>{if(e==null)return null;const t=String(e).trim();if(t==="")return null;const r={yyyy:"(\\d{4})",yy:"(\\d{2})",MM:"(\\d{1,2})",M:"(\\d{1,2})",dd:"(\\d{1,2})",d:"(\\d{1,2})",HH:"(\\d{1,2})",mm:"(\\d{1,2})",ss:"(\\d{1,2})"},o=m=>m.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");let i="^";const s=[];for(const m of J(n))if(m.token&&r[m.token])i+=r[m.token],s.push(m.token);else{if(m.token)return null;i+=o(m.text)}i+="$";const c=new RegExp(i).exec(t);if(!c)return null;const p={year:0,month:1,day:1,hour:0,minute:0,second:0};for(let m=0;m<s.length;m+=1){const v=Number(c[m+1]);if(Number.isNaN(v))return null;const A=s[m];A==="yyyy"?p.year=v:A==="yy"?p.year=2e3+v:A==="MM"||A==="M"?p.month=v:A==="dd"||A==="d"?p.day=v:A==="HH"?p.hour=v:A==="mm"?p.minute=v:A==="ss"&&(p.second=v)}const h=new Date(p.year,p.month-1,p.day,p.hour,p.minute,p.second);return Number.isNaN(h.getTime())?null:B(h)},zr=(e,n)=>{switch(e.type){case"text":return{ok:!0,value:typeof n=="string"?n:String(n)};case"number":{const t=nr(n,e.decimal===","?",":".");return t==null?{ok:!1}:{ok:!0,value:t}}case"integer":{const t=nr(n,e.decimal===","?",":".");return t==null||!Number.isInteger(t)?{ok:!1}:{ok:!0,value:t}}case"boolean":{if(typeof n=="boolean")return{ok:!0,value:n};if(e.trueSet||e.falseSet){const r=String(n);return e.trueSet&&e.trueSet.has(r)?{ok:!0,value:!0}:e.falseSet&&e.falseSet.has(r)?{ok:!0,value:!1}:{ok:!1}}const t=G(n);return t==null?{ok:!1}:{ok:!0,value:t}}case"date":{const t=e.format||"iso";if(t==="epoch-s"){const o=Number(n),i=o*1e3;if(!Number.isFinite(o)||!Number.isFinite(i))return{ok:!1};const s=B(new Date(i));return s==null?{ok:!1}:{ok:!0,value:s}}if(t==="epoch-ms"){const o=Number(n);if(!Number.isFinite(o))return{ok:!1};const i=B(new Date(o));return i==null?{ok:!1}:{ok:!0,value:i}}if(t==="iso"){const o=B(n);return o==null?{ok:!1}:{ok:!0,value:o}}const r=qr(n,t);return r==null?{ok:!1}:{ok:!0,value:r}}case"json":{if(typeof n!="string")return{ok:!0,value:n};try{return{ok:!0,value:JSON.parse(n)}}catch{return{ok:!1}}}default:return{ok:!0,value:n}}},Ur=(e,n,t,r)=>{const o=t[n.name],i=o;let s;if(i==null||typeof i=="number"&&Number.isNaN(i))s=null;else if(n.nulls&&n.nulls.has(String(i)))s=null;else if(n.type==null)s=i;else if(n.type!=="text"&&typeof i=="string"&&i.trim()==="")s=null;else{const c=zr(n,i),p=e.explain.fields.get(n.name);c.ok?(p&&(p.coerced+=1),s=c.value):(Br(e,n,i),p&&(p.invalid+=1,Yt(p.samples,i)),s=null)}t[n.name]=s,r&&r.push({field:n.name,before:o,after:s})},Gr=(e,n,t)=>{for(const r of e.fields)Ur(e,r,n,t)},Lt=e=>e==null?null:String(e),Tn=(e,n)=>{if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t+=1)if(!Tn(e[t],n[t]))return!1;return!0}if(e&&n&&typeof e=="object"&&typeof n=="object"){const t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(const o of t)if(!Tn(e[o],n[o]))return!1;return!0}return!1},An=(e,n)=>{if(e===n)return!0;if(!e||!n)return!1;const t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(const o of t)if(!Tn(e[o],n[o]))return!1;return!0},Vr=Object.freeze(["count","sum","avg","min","max","distinctCount","first","last"]),_r=Object.freeze(["sum","avg","min","max","distinctCount","first","last"]),Jr=e=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const n=[];for(const[t,r]of Object.entries(e)){if(!r||typeof r!="object"||typeof r.fn!="string"){F("data-router:join-aggregate-bad-spec",`join aggregate "${t}" is not a { fn, field? } reducer; the aggregate is skipped.`);continue}if(!Vr.includes(r.fn)){F("data-router:join-aggregate-bad-fn",`join aggregate "${t}" uses fn "${r.fn}", which is not count|sum|avg|min|max|distinctCount|first|last; the aggregate is skipped.`);continue}const o=typeof r.field=="string"&&r.field?r.field:null;if(_r.includes(r.fn)&&!o){F("data-router:join-aggregate-no-field",`join aggregate "${t}" (${r.fn}) needs a field; the aggregate is skipped.`);continue}const i=r.fn==="first"||r.fn==="last"?typeof r.orderBy=="string"&&r.orderBy?r.orderBy:o:null;n.push([t,{fn:r.fn,field:o,orderBy:i}])}return n.length?n:null},Nn=(e,n)=>{if(!(!e||typeof e!="object"))return n in e||F(`data-router:collect-select-field:${n}`,`a collect join's \`select\` names "${n}", which the collected rows do not have; it is collected as undefined.`),e[n]},Yr=(e,n)=>{if(!e||typeof e!="object")return null;const t=e.from!=null?String(e.from):null;if(!t)return F("data-router:join-no-from","join needs a `from` (the lookup source id); ignoring the join."),null;const r=e.many===!0||e.spread!=null;let o=e.localKey!=null?e.localKey:e.on;o==null&&r&&(o=ce);let i;if(typeof o=="function")i=o;else if(typeof o=="string")i=L=>L[o];else return F("data-router:join-no-localkey","join needs a `localKey` (a field name or fn); ignoring the join."),null;const s=e.foreignKey!=null?e.foreignKey:e.fromKey;let c,p;if(typeof s=="function")c=s,p=s;else if(typeof s=="string")c=L=>L[s],p=s;else if(typeof o=="string")c=L=>L[o],p=o;else return F("data-router:join-no-foreignkey","join with a fn `localKey` needs an explicit string/fn `foreignKey`; ignoring the join."),null;if(r){if(e.spread!=null){const Ae=e.spread&&typeof e.spread=="object"?e.spread:{},Ie=Ae.name,Ze=Ae.value;let Zt,Wn;if(typeof Ie=="function")Zt=Ie;else if(typeof Ie=="string"&&Ie.length)Zt=Ot=>Ot[Ie];else return F("data-router:spread-no-name","a spread join needs a `name` (the attribute-name field or fn); ignoring the join."),null;if(typeof Ze=="function")Wn=Ze;else if(typeof Ze=="string"&&Ze.length)Wn=Ot=>Ot[Ze];else return F("data-router:spread-no-value","a spread join needs a `value` (the attribute-value field or fn); ignoring the join."),null;const vo=typeof Ae.prefix=="string"?Ae.prefix:"";let Bn=null;const hn=Ae.include;if(typeof hn=="function")Bn=hn;else if(Array.isArray(hn)){const Ot=new Set(hn.map(zt=>String(zt)));Bn=zt=>Ot.has(zt)}const mr=new Map;if(Ae.type&&typeof Ae.type=="object"&&!Array.isArray(Ae.type))for(const[Ot,zt]of Object.entries(Ae.type))io.includes(zt)&&mr.set(Ot,zt);return{many:!0,spread:!0,from:t,localKey:i,foreignKeyFn:c,ffKey:p,nameFn:Zt,valueFn:Wn,prefix:vo,includeFn:Bn,typeOf:Ot=>mr.get(Ot),keyIndex:new Map,lastFk:new Map,owner:n,probe:null,spreadPrev:new Map,ex:Ct()}}let L=e.missing;if(L!=="hold"&&L!=="passthrough"&&L!=="null"&&(L!=null&&F("data-router:join-bad-missing",`join.missing "${L}" is not hold|passthrough|null; using "passthrough".`),L="passthrough"),e.aggregate!=null){const Ae=Jr(e.aggregate);if(!Ae)return F("data-router:join-aggregate-invalid","a join aggregate must be a non-empty object of named reducers; ignoring the join."),null;const Ie=typeof e.where=="function"?e.where:null;return{many:!0,aggregate:Ae,whereFn:Ie,from:t,localKey:i,foreignKeyFn:c,ffKey:p,missing:L,keyIndex:new Map,lastFk:new Map,owner:n,probe:null,ex:Ct()}}if(typeof e.as!="string"||!e.as)return F("data-router:join-no-as","a collect join (many: true) needs an `as` (the field to put the collected array into); ignoring the join."),null;let S=null;const ge=e.select!=null?e.select:e.fields;typeof ge=="function"?S=ge:typeof ge=="string"&&ge?S=Ae=>Nn(Ae,ge):Array.isArray(ge)&&ge.length?S=Ae=>{const Ie={};for(const Ze of ge)Ie[String(Ze)]=Nn(Ae,String(Ze));return Ie}:ge&&typeof ge=="object"&&!Array.isArray(ge)&&Object.keys(ge).length&&(S=Ae=>{const Ie={};for(const[Ze,Zt]of Object.entries(ge))Ie[String(Zt)]=Nn(Ae,Ze);return Ie}),S||(S=Ae=>Ae);const lt=e.distinct===!0,Bt=e.sort===!0?!0:typeof e.sort=="function"?e.sort:!1,Kt=e.onParentDelete==="cascade"||e.onParentDelete==="orphan"?e.onParentDelete:"keep";return{many:!0,from:t,localKey:i,foreignKeyFn:c,ffKey:p,as:e.as,selectFn:S,distinct:lt,sort:Bt,missing:L,onParentDelete:Kt,keyIndex:new Map,lastFk:new Map,owner:n,probe:null,ex:Ct()}}let h=null;const m=[],v=e.fields!=null?e.fields:e.select;if(typeof v=="function")h=v;else if(Array.isArray(v))for(const L of v)m.push([String(L),String(L)]);else if(v&&typeof v=="object")for(const[L,S]of Object.entries(v))m.push([L,String(S)]);else F("data-router:join-no-fields","join has no `fields`/`select`; rows pass through unenriched.");let A=e.missing;return A!=="hold"&&A!=="passthrough"&&A!=="null"&&(A!=null&&F("data-router:join-bad-missing",`join.missing "${A}" is not hold|passthrough|null; using "passthrough".`),A="passthrough"),{many:!1,from:t,localKey:i,foreignKeyFn:c,ffKey:p,pairs:m,selectFn:h,missing:A,keyIndex:new Map,lastFk:new Map,owner:n,probe:null,ex:Ct()}},Qr=(e,n)=>{const t=new Set,r=[e];for(;r.length;){const o=r.pop();if(o===n)return!0;if(t.has(o))continue;t.add(o);const i=Se.get(o);if(i)for(const s of i.joins)r.push(s.from)}return!1},rr=(e,n)=>{if(e==null)return[];const t=[];for(const o of Array.isArray(e)?e:[e]){const i=Yr(o,n);i&&t.push(i)}const r=[];for(const o of t){if(o.from===n.id||Qr(o.from,n.id)){F("router:join-cycle",`join from "${n.id}" to "${o.from}" would close a join cycle; the join is refused.`);continue}r.push(o)}return r},Zr=(e,n)=>{const t=new Set;let r=Se.get(e);for(;r&&r.unnestParentId!=null&&!t.has(r.id);){if(t.add(r.id),r.unnestParentId===n)return!0;r=Se.get(r.unnestParentId)}return!1},Xr=(e,n)=>{if(!e||typeof e!="object")return null;const t=typeof e.path=="string"&&e.path?e.path:null;if(!t)return F("data-router:unnest-no-path","an unnest needs a `path` (the dotted array field on the row); ignoring the unnest."),null;const r=typeof e.as=="string"&&e.as?e.as:null;if(!r)return F("data-router:unnest-no-as","an unnest needs an `as` (the child row type); ignoring the unnest."),null;if(r===n.id||Zr(n.id,r))return F("router:unnest-cycle",`unnest "${n.id}" → "${r}" would close an unnest cycle; the unnest is refused.`),null;const o=typeof e.parentKey=="string"&&e.parentKey?e.parentKey:`${n.id}Id`,i=e.keep===!0;let s;if(typeof e.key=="function")s=e.key;else if(typeof e.key=="string"&&e.key){const h=e.key;s=m=>m[h]}else s=null;let c=Se.get(r);if(!c){c={id:r,map:null,fields:null,ns:null,live:new Map,out:new Map,ingested:0,joins:[],unnests:[],unnestParentId:n.id},c.handle=tr(c),Se.set(r,c),c.joins=rr(e.join,c),c.hasSpread=c.joins.some(h=>h.spread),c.unnests=or(e.unnest,c);for(const h of c.joins)Se.has(h.from)&&un(Se.get(h.from),h);for(const h of Se.values())if(h!==c)for(const m of h.joins)m.from===r&&m.probe==null&&un(c,m);c.explain=Dn(c),Jt.set(r,In(c))}const p=e.onParentDelete==="orphan"||e.onParentDelete==="keep"?e.onParentDelete:"cascade";return{path:t,as:r,keyFn:s,parentKeyField:o,keep:i,owner:n,child:c,onParentDelete:p,prevChildren:new Map}},or=(e,n)=>{if(e==null)return[];const t=[];for(const r of Array.isArray(e)?e:[e]){const o=Xr(r,n);o&&t.push(o)}return t},eo=(e,n)=>{const t=[];let r=0;const o=e.owner.explain.unnest.get(e.as);o&&(o.parentIn+=(n||[]).length);for(const i of n||[]){if(!i||!i.row)continue;const s=String(i.row[ce]),c=e.prevChildren.get(s)||new Map;if(i.op==="delete"){for(const[v,A]of c)if(e.onParentDelete==="orphan"){if(A.__orphan===!0)continue;const L={...A,__orphan:!0};e.child.live.set(v,L),t.push({op:"upsert",row:L}),r+=1}else e.onParentDelete==="keep"||(e.child.live.delete(v),t.push({op:"delete",row:A}),he&&st(v,"removed-by-cascade",`the parent row (key ${JSON.stringify(s)}) was deleted, cascading the delete to this unnested child.`,{parentKey:s}));e.prevChildren.delete(s);continue}const p=$(i.row,e.path),h=Array.isArray(p)?p:[],m=new Map;for(let v=0;v<h.length;v+=1){const A=h[v],L=e.keyFn?e.keyFn(A,i.row,v):null,S=L==null?`${s}:${v}`:String(L);m.has(S)&&F("router:unnest-duplicate-key",`the unnest "${e.as}" produced the child key "${S}" more than once for one parent; the later child (source order) wins.`);const ge={...A&&typeof A=="object"?A:{}};ge[e.parentKeyField]=i.row[ce],ge[ce]=S,b&&(ge[b]=e.as);const lt=e.child.live.get(S);lt&<.__orphan===!0&&(ge.__orphan=void 0),m.set(S,ge)}for(const[v,A]of c)m.has(v)||(e.child.live.delete(v),t.push({op:"delete",row:A}),he&&st(v,"removed-by-cascade",`the parent row (key ${JSON.stringify(s)}) no longer lists this child at "${e.path}".`,{parentKey:s}));for(const[v,A]of m){const L=c.get(v);if((L===void 0||!An(L,A))&&(e.child.live.set(v,A),t.push({op:"upsert",row:A}),he)){const S=Qt(e.as,v,v);S.lastRow=A,S.steps.push({kind:"unnest",parentKey:s})}}e.prevChildren.set(s,m)}return r>0&&F("router:orphaned-rows",`${r} child row(s) were orphaned when their parent was deleted; they are kept and marked __orphan: true (onParentDelete: 'orphan').`),o&&(o.childOut+=t.length),t},ir=(e,n,t)=>{const r={...n};if(e.selectFn){const o=e.selectFn(t,n);return o&&typeof o=="object"&&Object.assign(r,o),r}for(const[o,i]of e.pairs)r[i]=t?t[o]:null;return r},to=(e,n,t)=>{const r=Se.get(e.from),o=[];if(t!=null&&r&&e.probe){const c=e.probe.index.get(t);if(c)for(const p of c){const h=r.out?r.out.get(p):void 0;h!==void 0&&o.push(e.selectFn(h,n))}}const i=o.length>0;if(e.missing==="hold"&&o.length===0)return{hold:!0,matched:i};if(e.missing==="null"&&o.length===0)return{hold:!1,value:null,matched:i};let s=o;if(e.distinct){const c=new Map,p=[];for(const h of s){const m=typeof h=="object"&&h!==null?JSON.stringify(h):`${typeof h}:${String(h)}`;c.has(m)||(c.set(m,!0),p.push(h))}s=p}return e.sort&&(s=s.slice().sort(e.sort===!0?sr:e.sort)),{hold:!1,value:s,matched:i}},sr=(e,n)=>{if(e===n)return 0;if(e==null)return-1;if(n==null)return 1;if(typeof e=="number"&&typeof n=="number")return e-n;const t=String(e),r=String(n);return t<r?-1:t>r?1:0},no=(e,n)=>{const{fn:t,field:r,orderBy:o}=e;if(t==="count")return n.length;if(t==="first"||t==="last"){if(!n.length)return null;let s=n[0];for(let c=1;c<n.length;c+=1){const p=sr(n[c][o],s[o]);(t==="first"&&p<0||t==="last"&&p>0)&&(s=n[c])}return r?s[r]:s}if(t==="distinctCount"){if(!n.length)return null;const s=new Set;for(const c of n)s.add(c[r]);return s.size}const i=r?n.map(s=>Number(s[r])).filter(s=>Number.isFinite(s)):[];return t==="sum"?i.reduce((s,c)=>s+c,0):t==="avg"?i.length?i.reduce((s,c)=>s+c,0)/i.length:null:t==="min"?i.length?Math.min(...i):null:t==="max"&&i.length?Math.max(...i):null},ro=(e,n)=>e.map(([t,r])=>[t,no(r,n)]),oo=(e,n)=>{const t=Se.get(e.from),r=[];let o=!1;if(n!=null&&t&&e.probe){const i=e.probe.index.get(n);if(i)for(const s of i){const c=t.out?t.out.get(s):void 0;c!==void 0&&(o=!0,(!e.whereFn||e.whereFn(c))&&r.push(c))}}return e.missing==="hold"&&!o?{hold:!0,matched:o}:{hold:!1,values:ro(e.aggregate,r),matched:o}},io=Object.freeze(["number","date","boolean","text"]);function so(e,n){if(e==null)return e;if(n==="number"){if(typeof e=="number")return e;const t=Number(e);return Number.isFinite(t)?t:e}if(n==="date"){if(e instanceof Date)return e;const t=new Date(e);return Number.isNaN(t.getTime())?e:t}if(n==="boolean"){if(typeof e=="boolean")return e;if(typeof e=="string"){const t=e.trim().toLowerCase();if(t==="true"||t==="1"||t==="yes")return!0;if(t==="false"||t==="0"||t==="no"||t==="")return!1}return!!e}return n==="text"?String(e):e}const lo=(e,n)=>{const t=Se.get(e.from),r=new Map;if(n!=null&&t&&e.probe){const o=e.probe.index.get(n);if(o)for(const i of o){const s=t.out?t.out.get(i):void 0;if(s===void 0)continue;const c=e.nameFn(s);if(c==null)continue;const p=String(c);if(e.includeFn&&!e.includeFn(p,s))continue;const h=e.prefix+p;r.has(h)&&F("router:spread-duplicate",`a spread join wrote the field "${h}" more than once for one parent; the last attribute row (source order) wins.`),r.set(h,so(e.valueFn(s),e.typeOf?e.typeOf(p):void 0))}}return r},Fn=(e,n,t)=>{const r=e.lastFk.get(n);if(r!==void 0&&r!==t){const i=e.keyIndex.get(r);i&&(i.delete(n),i.size||e.keyIndex.delete(r))}if(t==null){e.lastFk.set(n,null);return}let o=e.keyIndex.get(t);o||(o=new Set,e.keyIndex.set(t,o)),o.add(n),e.lastFk.set(n,t)},xn=(e,n,t)=>{const r=e.joins.indexOf(t);for(let o=r+1;o<e.joins.length;o+=1){const i=e.joins[o];Fn(i,n,null),i.lastFk.delete(n)}},lr=(e,n,t)=>{let r={...n};if(e.unnests&&e.unnests.length)for(const o of e.unnests)o.keep||ee(r,o.path);for(const o of e.joins){const i=o.localKey(r),s=Lt(i);if(Fn(o,t,s),o.spread){e.explain.spread.touched+=1,he&&at(t,{kind:"spread",origin:o.from});const c=lo(o,s),p=o.spreadPrev.get(t)||new Set,h=new Set;for(const[m,v]of c){if(Object.prototype.hasOwnProperty.call(n,m)){F("router:spread-collision",`a spread join skipped the field "${m}" because the parent row already carries it; a spread field never overwrites a base parent field.`),h.add(m);continue}r[m]=v,Xt.add(m),h.add(m)}for(const m of p)h.has(m)||(r[m]=void 0);o.spreadPrev.set(t,h)}else if(o.many)if(o.aggregate){const c=oo(o,s);if(c.matched?o.ex.matched+=1:(o.ex.unmatchedCount+=1,Yt(o.ex.unmatchedSamples,i)),he&&at(t,{kind:"join",from:o.from,matchedKey:s,matched:c.matched}),c.hold)return he&&st(t,"join-no-partner",`no row in source "${o.from}" matches key ${JSON.stringify(s)}; the row is withheld (missing: 'hold').`,{key:s,source:o.from}),xn(e,t,o),{emit:!1,row:n};for(const[p,h]of c.values)r[p]=h}else{const c=to(o,r,s);if(c.matched?o.ex.matched+=1:(o.ex.unmatchedCount+=1,Yt(o.ex.unmatchedSamples,i)),he&&at(t,{kind:"collect",from:o.from,matchedKey:s,matched:c.matched}),c.hold)return he&&st(t,"join-no-partner",`no row in source "${o.from}" matches key ${JSON.stringify(s)}; the row is withheld (missing: 'hold').`,{key:s,source:o.from}),xn(e,t,o),{emit:!1,row:n};r[o.as]=c.value}else{const c=s!=null&&o.probe?o.probe.index.get(s):null;let p=null;if(c&&c.size){c.size>1&&(o.ex.duplicateCount+=1,Yt(o.ex.duplicateSamples,i));const h=Se.get(o.from);if(h&&h.out){let m;for(m of c);p=h.out.get(m)||null}}if(p)o.ex.matched+=1,he&&at(t,{kind:"join",from:o.from,matchedKey:s,matched:!0}),r=ir(o,r,p);else{if(o.ex.unmatchedCount+=1,Yt(o.ex.unmatchedSamples,i),he&&at(t,{kind:"join",from:o.from,matchedKey:s,matched:!1}),o.missing==="hold")return he&&st(t,"join-no-partner",`no row in source "${o.from}" matches key ${JSON.stringify(s)}; the row is withheld (missing: 'hold').`,{key:s,source:o.from}),xn(e,t,o),{emit:!1,row:n};o.missing==="null"&&(r=ir(o,r,null))}}}return{emit:!0,row:r}},un=(e,n)=>{e.probes||(e.probes=new Map);let t=e.probes.get(n.ffKey);if(!t){t={fn:n.foreignKeyFn,index:new Map,prev:new Map,specs:new Set},e.probes.set(n.ffKey,t);for(const[r,o]of e.live){const i=Lt(t.fn(o));if(i==null)continue;let s=t.index.get(i);s||(s=new Set,t.index.set(i,s)),s.add(r),t.prev.set(r,i)}}t.specs.add(n),n.probe=t},ar=(e,n,t,r)=>{const o=e.live.get(n);if(!o)return;he&&r&&at(n,{kind:"cascade",origin:r});const i=e.out.get(n),s=lr(e,o,n);let c=!1;s.emit?(e.out.set(n,s.row),(i===void 0||!An(i,s.row))&&(t.push({op:"upsert",row:s.row}),c=!0)):(e.out.delete(n),i!==void 0&&(t.push({op:"delete",row:i}),c=!0)),e.hasSpread&&c&&(e.explain.spread.reemitted+=1),c&&ur(e,new Set([n]),t)},ur=(e,n,t)=>{if(!(!e.probes||!e.probes.size))for(const r of e.probes.values()){const o=new Set;for(const i of n){const s=e.live.get(i),c=s?Lt(r.fn(s)):null;c!=null&&o.add(c)}if(o.size)for(const i of r.specs)for(const s of o){const c=i.keyIndex.get(s);if(c)for(const p of[...c]){const h=t.length;ar(i.owner,p,t,e.id),e.explain.cascade.touched+=1,t.length>h&&(e.explain.cascade.reemitted+=1)}}}},_t=(e,n,t)=>{const r=qt();if(e.unnests&&e.unnests.length)for(const p of e.unnests){const h=eo(p,n);h.length&&_t(p.child,h,t)}{const p=[],h=[];for(const m of n)!m||!m.row||(m.op==="delete"?p.push(m.row):h.push(m.row));if(p.length||h.length){const m=[];for(const S of e.joins)if(S.many&&!S.aggregate&&!S.spread&&(S.onParentDelete==="cascade"||S.onParentDelete==="orphan")){const ge=Se.get(S.from);m.push({childSource:ge,pkFn:S.localKey,fkFn:S.foreignKeyFn,index:S.probe?S.probe.index:null,mode:S.onParentDelete,writeBack:!1})}for(const S of x)S.parentId===e.id&&m.push({childSource:Se.get(S.childId),pkFn:S.pkFn,fkFn:S.fkFn,index:S.probe?S.probe.index:null,mode:S.onParentDelete,writeBack:S.writeBack,ex:S.ex});const v=new Map;let A=0;const L=S=>{let ge=v.get(S.id);return ge||(ge={source:S,deltas:[],writeBack:[]},v.set(S.id,ge)),ge};for(const S of m)if(!(!S.childSource||!S.index)){for(const ge of p){const lt=Lt(S.pkFn(ge));if(lt==null)continue;const Bt=S.index.get(lt);if(!Bt)continue;const Kt=L(S.childSource);for(const Ae of[...Bt]){const Ie=S.childSource.live.get(Ae);if(Ie){if(S.ex&&(S.ex.matched+=1),he&&at(Ae,{kind:"relate",parentKey:lt,matchedKey:lt}),S.mode==="cascade")S.childSource.live.delete(Ae),Kt.deltas.push({op:"delete",row:Ie}),he&&st(Ae,"removed-by-cascade",`the parent row (key ${JSON.stringify(lt)}) was deleted, cascading the delete to this child.`,{parentKey:lt}),S.writeBack&&Kt.writeBack.push(Ie);else if(Ie.__orphan!==!0){const Ze={...Ie,__orphan:!0};S.childSource.live.set(Ae,Ze),Kt.deltas.push({op:"upsert",row:Ze}),A+=1}}}}if(S.mode==="orphan")for(const ge of h){const lt=Lt(S.pkFn(ge));if(lt==null)continue;const Bt=S.index.get(lt);if(!Bt)continue;const Kt=L(S.childSource);for(const Ae of[...Bt]){const Ie=S.childSource.live.get(Ae);if(!Ie||Ie.__orphan!==!0)continue;const Ze={...Ie,__orphan:void 0};S.childSource.live.set(Ae,Ze),Kt.deltas.push({op:"upsert",row:Ze})}}}A>0&&F("router:orphaned-rows",`${A} child row(s) were orphaned when their parent was deleted; they are kept and marked __orphan: true (onParentDelete: 'orphan').`);for(const S of v.values())if(S.deltas.length&&_t(S.source,S.deltas,t),S.writeBack.length&&ze)for(const ge of S.writeBack)try{ze({op:"delete",key:String(ge[ce]),row:ge},{route:null,source:S.source.handle})}catch{}}}const o=new Map;if(e.probes&&e.probes.size)for(const p of e.probes.values()){const h=new Set;for(const m of n){const v=String(m.row[ce]);if(m.op==="delete"){const S=p.prev.get(v);if(S!=null){const ge=p.index.get(S);ge&&(ge.delete(v),ge.size||p.index.delete(S)),h.add(S)}p.prev.delete(v);continue}const A=Lt(p.fn(m.row)),L=p.prev.get(v);if(L!=null&&L!==A){const S=p.index.get(L);S&&(S.delete(v),S.size||p.index.delete(L)),h.add(L)}if(A!=null){let S=p.index.get(A);S||(S=new Set,p.index.set(A,S)),S.add(v),h.add(A)}p.prev.set(v,A)}h.size&&o.set(p,h)}const i=[],s=new Set;for(const p of n){const h=String(p.row[ce]);if(p.op==="delete"){for(const L of e.joins)Fn(L,h,null),L.lastFk.delete(h),L.spread&&L.spreadPrev.delete(h);const A=e.out.get(h);e.out.delete(h),A!==void 0&&(i.push(p),s.add(h));continue}const m=e.out.get(h),v=lr(e,p.row,h);v.emit?(e.out.set(h,v.row),(m===void 0||!An(m,v.row))&&(i.push({...p,row:v.row}),s.add(h),e.hasSpread&&(e.explain.spread.reemitted+=1))):(e.out.delete(h),m!==void 0&&(i.push({op:"delete",row:m}),s.add(h)))}t(i);const c=[];if(o.size)for(const[p,h]of o)for(const m of p.specs)for(const v of h){const A=m.keyIndex.get(v);if(A)for(const L of[...A]){const S=c.length;ar(m.owner,L,c,e.id),e.explain.cascade.touched+=1,c.length>S&&(e.explain.cascade.reemitted+=1)}}s.size&&ur(e,s,c),e.explain.timingMs+=qt()-r,c.length&&tt.apply(c)},$n=(e,n,t)=>{const r=T.get(e);if(T.set(e,{cur:n,t}),!r)return 0;const o=(t-r.t)/1e3;return o<=0?0:(n-r.cur)/o},ao=()=>{if(!Re)return 0;let e=0;for(const n of Ne)n.pos>=Fe&&(e+=1);return e},cr=(e,n)=>{const t=we.get(e);if(t)for(const r of t)try{r(n)}catch{}},uo=()=>{fe||We<=0||(fe=setInterval(()=>cr("metrics",tt.metrics()),We),fe&&typeof fe.unref=="function"&&fe.unref())},fr=()=>{fe&&(clearInterval(fe),fe=null)};let cn=0,dr=0,pr=0;const Jt=new Map,gt=new Map,qt=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),Yt=(e,n)=>{e.length<5&&e.push(n)},Ct=()=>({matched:0,unmatchedCount:0,unmatchedSamples:[],duplicateCount:0,duplicateSamples:[]}),Dn=e=>{const n=new Map;if(e.fields)for(const r of e.fields)n.set(r.name,{coerced:0,invalid:0,samples:[]});const t=new Map;if(e.unnests)for(const r of e.unnests)t.set(r.as,{parentIn:0,childOut:0});return{rowsLoaded:0,rowsApplied:0,rowsRemoved:0,fields:n,unnest:t,spread:{touched:0,reemitted:0},cascade:{touched:0,reemitted:0},timingMs:0}},hr=()=>({whenRouted:0,filterIn:0,filterOut:0,transformIn:0,transformOut:0,sortCount:0,rollupIn:0,rollupOut:0,rollupGroups:0,writeAdd:0,writeUpdate:0,writeRemove:0,timingMs:0}),At=()=>{if(cn+=1,!(cn>1)){dr=qt(),Wt+=1;for(const e of Se.values()){e.explain=Dn(e);for(const n of e.joins)n.ex=Ct()}for(const e of x)e.ex=Ct();for(const e of Oe())e.explain=hr();for(const e of Le)e.explain={whenRouted:0,filterIn:0,filterOut:0}}},Nt=()=>{if(cn-=1,!(cn>0)){pr=qt()-dr;for(const e of Se.values())Jt.set(e.id,In(e));for(const e of Oe())gt.set(e.routeId,fn(e));for(const e of Le)gt.set(e.routeId,Mn(e))}},co=e=>e.label!=null?e.label:e.hasPartValue?e.partValue:e.routeId,fo=e=>{const n=[];for(const t of e.joins){if(t.spread)continue;const r=t.aggregate?"rollup":t.as?"collect":"lookup",o=[];if(t.probe)for(const i of t.probe.index.keys())t.keyIndex.has(i)||o.push(i);n.push({kind:r,from:t.from,as:t.as||null,matched:t.ex.matched,unmatched:{left:{count:t.ex.unmatchedCount,samples:t.ex.unmatchedSamples.slice()},right:{count:o.length,samples:o.slice(0,5)}},duplicates:{count:t.ex.duplicateCount,samples:t.ex.duplicateSamples.slice()}})}for(const t of x)t.childId===e.id&&n.push({kind:"relateRows",from:t.parentId,as:null,matched:t.ex.matched,unmatched:{left:{count:0,samples:[]},right:{count:0,samples:[]}},duplicates:{count:0,samples:[]}});return n},In=e=>{const n={};for(const[r,o]of e.explain.fields)n[r]={coerced:o.coerced,invalid:o.invalid,samples:o.samples.slice()};const t={};for(const[r,o]of e.explain.unnest)t[r]={parentRowsIn:o.parentIn,childRowsOut:o.childOut};return{source:e.id,rows:{loaded:e.explain.rowsLoaded,applied:e.explain.rowsApplied,removed:e.explain.rowsRemoved},fields:n,unnest:t,joins:fo(e),spread:{touched:e.explain.spread.touched,reemitted:e.explain.spread.reemitted},cascade:{touched:e.explain.cascade.touched,reemitted:e.explain.cascade.reemitted},timingMs:e.explain.timingMs}},fn=e=>({route:co(e),label:e.label||null,when:{routed:e.explain.whenRouted,unrouted:ot},filter:{in:e.explain.filterIn,out:e.explain.filterOut},transform:{in:e.explain.transformIn,out:e.explain.transformOut},sort:{count:e.explain.sortCount},rollup:e.rollup?{in:e.explain.rollupIn,out:e.explain.rollupOut,groups:e.explain.rollupGroups}:null,write:{add:e.explain.writeAdd,update:e.explain.writeUpdate,remove:e.explain.writeRemove},timingMs:e.explain.timingMs}),Mn=e=>({route:e.label!=null?e.label:e.routeId,label:e.label||null,kind:e.kind==="monitor"?"monitor":"alert",when:{routed:e.explain.whenRouted,unrouted:ot},filter:{in:e.explain.filterIn,out:e.explain.filterOut},transform:null,sort:null,rollup:null,write:null,timingMs:0});let he=!!g.trace,Wt=0,po=Number.isFinite(g.traceLimit)?Math.max(0,Number(g.traceLimit)):1e4;const Je=new Map,dn=new Map,ho=()=>{for(;Je.size>po;){const e=Je.keys().next().value,n=Je.get(e);Je.delete(e),n&&dn.delete(`${n.source.id}::${n.source.key}`)}},Qt=(e,n,t)=>{let r=Je.get(t);return r?(Je.delete(t),Je.set(t,r),r.settleGen!==Wt&&(r.dropped=null,r.settleGen=Wt),r):(r={source:{id:e,key:n},steps:[],write:null,dropped:null,lastRow:null,lastSeq:void 0,settleGen:Wt},Je.set(t,r),dn.set(`${e}::${n}`,t),ho(),r)},at=(e,n)=>{const t=Je.get(e);t&&(t.steps.push(n),t.settleGen=Wt)},st=(e,n,t,r)=>{const o=Je.get(e);o&&(o.dropped||(o.dropped={reason:n,message:t,...r||{}}),o.settleGen=Wt)},gr=(e,n,t)=>{const r=Je.get(e);r&&(r.dropped=null,r.settleGen=Wt,r.write={op:t,label:n.label||null,routeId:n.routeId,seq:r.lastSeq},r.steps.push({kind:"route",label:n.label||null,op:t,seq:r.lastSeq}))},go=(e,n)=>{const t=Je.get(String(n));return t?{known:!0,source:[{id:t.source.id,key:t.source.key}],steps:t.steps.map(r=>({...r})),route:t.write?{label:t.write.label}:null,write:t.write?{op:t.write.op,seq:t.write.seq}:null}:{known:!1,reason:"not-traced"}},mo=(e,n,t)=>{const r=dn.get(`${String(e)}::${String(n)}`),o=r!=null?Je.get(r):null;if(!o)return{known:!1,reason:"not-traced"};const i=t!==void 0?[Z(t)].filter(Boolean):Oe();if(o.lastRow)for(const s of i){const c=D([s.keyOf(o.lastRow)]);if(s.keys&&s.keys.has(c))return{known:!0,present:!0,message:"this row is in the grid.",route:{label:s.label||null}}}if(t!==void 0){const s=Z(t);if(s&&o.lastRow&&!s.match(o.lastRow))return{known:!0,present:!1,reason:"predicate-false",label:s.label||null,message:`the row did not match route "${s.label||s.routeId}"'s predicate.`}}return o.dropped?{known:!0,present:!1,...o.dropped}:{known:!0,present:!1,reason:"unrouted",message:"no route (and no default sink) matched this row."}},pn=(e,n)=>go(e,n);pn.enable=()=>{he=!0},pn.disable=()=>{he=!1},pn.missing=(e,n,t)=>mo(e,n,t);const yo=e=>{const n=e.indexedDB||(typeof indexedDB<"u"?indexedDB:null);if(!n)return null;const t=typeof e.dbName=="string"?e.dbName:"lattice-router",r=typeof e.storeName=="string"?e.storeName:"snapshots";let o=null;const i=()=>o||(o=new Promise((s,c)=>{let p;try{p=n.open(t,1)}catch(h){c(h);return}p.onupgradeneeded=()=>{const h=p.result;h.objectStoreNames.contains(r)||h.createObjectStore(r)},p.onsuccess=()=>s(p.result),p.onerror=()=>c(p.error)}),o);return{set(s,c){return i().then(p=>new Promise((h,m)=>{const v=p.transaction(r,"readwrite");v.objectStore(r).put(c,s),v.oncomplete=()=>h(),v.onerror=()=>m(v.error),v.onabort=()=>m(v.error)}))},get(s){return i().then(c=>new Promise((p,h)=>{const v=c.transaction(r,"readonly").objectStore(r).get(s);v.onsuccess=()=>p(v.result),v.onerror=()=>h(v.error)}))},close(){o&&o.then(s=>{try{s.close()}catch{}},()=>{})}}},bo=()=>Re?[...rn(void 0,ve).values()]:Vt(),wo=()=>({v:1,world:bo(),maxSeq:P,checkpoint:Object.fromEntries(_),buffer:Re?{on:!0,max:se,window:ke,domain:ve,pos:_e,baseSeq:Me,baseT:yt,base:[...Ve.entries()],log:Ne.map(e=>({pos:e.pos,seq:e.seq,t:e.t,op:e.op,key:e.key,row:e.row}))}:{on:!1}}),ko=e=>{if(!e||typeof e!="object")return!1;xe=!0;try{tt.load(Array.isArray(e.world)?e.world:[])}finally{xe=!1}e.checkpoint&&tt.seenThrough(e.checkpoint),Number.isFinite(e.maxSeq)&&(P===void 0||e.maxSeq>P)&&(P=e.maxSeq);const n=e.buffer;if(n&&n.on){Re=!0,se=Number.isFinite(n.max)?n.max:null,ke=Number.isFinite(n.window)?n.window:null,ve=n.domain==="seq"||n.domain==="time"?n.domain:De?"seq":"time",Ve=new Map(Array.isArray(n.base)?n.base:[]),Ne.length=0;for(const t of Array.isArray(n.log)?n.log:[])Ne.push({...t});_e=Number.isFinite(n.pos)?n.pos:Ne.length,Me=n.baseSeq,yt=n.baseT,Fe=_e}return!0},Ln=()=>{if(!ue)return Promise.resolve();const e=wo(),n=Promise.resolve().then(()=>ue.set(et,e)).catch(()=>{});return Ge=n,n.then(()=>{Ge===n&&(Ge=null)})},Cn=()=>{if(!(!me||!ue||xe)){if(ft<=0){Ln();return}Ee||(Ee=setTimeout(()=>{Ee=null,Ln()},ft),Ee&&typeof Ee.unref=="function"&&Ee.unref())}},tt={attach(e,n,t={}){const r=typeof n!="function",o=r?s=>d(s)===n:n;r&&Gn(n);const i=En(e,o,t);return r&&(i.hasPartValue=!0,i.partValue=n),Xe.push(i),gt.set(i.routeId,fn(i)),i.writable&&Rr(i),this},attachDefault(e,n={}){return Ye=En(e,()=>!1,n),Ye.isDefault=!0,gt.set(Ye.routeId,fn(Ye)),this},subscribe(e,n,t={}){const r=typeof e!="function",o=r?s=>d(s)===e:e;r&&Gn(e);const i=En(n,o,t);return r&&(i.hasPartValue=!0,i.partValue=e),Xe.push(i),gt.set(i.routeId,fn(i)),this},alert(e,n,t,r={}){const o=typeof e=="function"?e:s=>d(s)===e,i={routeId:q(),label:typeof r.label=="string"?r.label:null,match:o,keyOf:ne(R(r.rowKey,"alerts"),f),filter:typeof r.filter=="function"?r.filter:null,condition:typeof n=="function"?n:()=>!1,handler:typeof t=="function"?t:()=>{},debounceMs:Number.isFinite(r.debounce)?Number(r.debounce):0,armed:!0,timer:null,pending:null,partition:new Map,explain:{whenRouted:0,filterIn:0,filterOut:0}};return Le.push(i),jn(i,Vt()),nn(i),gt.set(i.routeId,Mn(i)),this},monitor(e,n,t,r={}){const o=typeof e=="function"?e:s=>d(s)===e,i={kind:"monitor",routeId:q(),label:typeof r.label=="string"?r.label:null,match:o,keyOf:ne(R(r.rowKey,"alerts"),f),filter:typeof r.filter=="function"?r.filter:null,evaluate:typeof n=="function"?n:()=>{},handler:typeof t=="function"?t:()=>{},armed:!0,timer:null,pending:null,partition:new Map,explain:{whenRouted:0,filterIn:0,filterOut:0}};return Le.push(i),jn(i,Vt()),nn(i),gt.set(i.routeId,Mn(i)),()=>{const s=Le.indexOf(i);s>=0&&Le.splice(s,1),i.timer&&(clearTimeout(i.timer),i.timer=null),i.partition.clear()}},configure(e={}){const n=t=>({rowKey:t.rowKey,transform:t.transform,filter:t.filter,sort:t.sort,rollup:t.rollup,debounce:t.debounce,where:t.where,writable:t.writable,onWrite:t.onWrite,onConflict:t.onConflict,backpressure:t.backpressure,label:t.label});for(const t of e.routes||[])if(t){if(t.default!==void 0){this.attachDefault(t.default,n(t));continue}if(t.alert!==void 0){this.alert(t.when,t.condition,t.alert,n(t));continue}if(t.subscribe!==void 0){this.subscribe(t.when,t.subscribe,n(t));continue}this.attach(t.grid,t.when,n(t))}for(const t of e.links||[])t&&t.from&&t.to&&this.link(t.from,t.to,t.on!==void 0?t.on:t.relation);return e.relate&&this.relate(e.relate),e.buffer&&this.buffer(e.buffer),this},link(e,n,t){const r={from:e,to:n,relation:t,predicate:null};rt.push(r),zn(e),Ht(r);const o=St(n);return o&&jt(o),this},relate(e){for(const n of e||[]){if(!n||!n.from||!n.to)continue;const t=n.on!==void 0?n.on:n.relation!==void 0?n.relation:n.rel;Ue.push({from:n.from,to:n.to,rel:t}),n.mutual&&Ue.push({from:n.to,to:n.from,rel:qe(t)})}for(const n of Gt())zn(n);Mt();for(const n of Gt()){const t=St(n);t&&jt(t)}return this},flush(){return Sn(),this},detach(e){const n=new Set;for(let o=rt.length-1;o>=0;o--){const i=rt[o];(i.from===e||i.to===e)&&(i.to!==e&&n.add(i.to),Un(i.from),rt.splice(o,1))}let t=!1;for(let o=Ue.length-1;o>=0;o--)(Ue[o].from===e||Ue[o].to===e)&&(Un(Ue[o].from),Ue.splice(o,1),t=!0);for(let o=Xe.length-1;o>=0;o--)Xe[o].grid===e&&Xe.splice(o,1);Ye&&Ye.grid===e&&(Ye=null),Dt.delete(e);const r=Tt.get(e);if(r&&(r(),Tt.delete(e)),t){Mt();for(const o of Gt())n.add(o)}for(const o of n){const i=St(o);i&&jt(i)}return this},load(e){At();try{ot=0;const n=new Map(Oe().map(r=>[r,[]]));for(const r of e||[]){he&&(Qt("router",r[ce],String(r[ce])).lastRow=r);const o=Et(r);if(!o.length){ot+=1,K&&K(r),he&&st(String(r[ce]),"unrouted","no route (and no default sink) matched this row.");continue}for(const i of o)n.get(i).push(r)}for(const r of Oe()){const o=n.get(r);r.partition=new Map(o.map(i=>[String(r.keyOf(i)),i])),r.metricRows+=o.length,r.explain.whenRouted+=o.length,re+=o.length}if(De)for(const r of e||[]){const o=De(r);if(!Number.isFinite(o))continue;const i=String(a(r)),s=_.get(i);(s===void 0||o>s)&&_.set(i,o),(P===void 0||o>P)&&(P=o)}for(const r of rt)Ht(r);Mt();for(const r of Le)jn(r,e||[]),nn(r);for(const r of Oe())r.bp&&kr(r);const t=Oe().map(r=>jt(r));return Re&&Yn(),Fe=_e,je&&!Be&&ln(Zn()),Cn(),t}finally{Nt()}},apply(e){At();try{let n=(e||[]).filter(o=>o&&o.row);if(he)for(const o of n)Qt("router",o.row[ce],String(o.row[ce]));if(nt){n=n.map((i,s)=>[i,s]).sort((i,s)=>{const c=$t(i[0]),p=$t(s[0]);return c===void 0||p===void 0?i[1]-s[1]:c-p||i[1]-s[1]}).map(i=>i[0]);const o=[];for(const i of n){const s=$t(i);if(s!==void 0){const c=String(a(i.row)),p=_.get(c);if(p!==void 0&&s<=p){X+=1,he&&st(String(i.row[ce]),"deduped-stale-seq",`seq ${s} is not newer than the last applied seq ${p} for this row; the delta was dropped.`);continue}_.set(c,s),(P===void 0||s>P)&&(P=s)}o.push(i)}n=o}if(he)for(const o of n){if(!o.row)continue;const i=$t(o);if(i===void 0)continue;const s=Je.get(String(o.row[ce]));s&&(s.lastSeq=i)}if(je&&!Be&&n.length&&ln({t:"delta",deltas:n.map(o=>({op:o.op,row:o.row,seq:o.seq}))}),Re){for(const o of n)Fr(o);Nr()}for(const o of Le)Ar(o,n),nn(o);if(bt){Cn();return}const t=new Map(Oe().map(o=>[o,new Map]));for(const o of n){const i=o&&o.row;if(!i)continue;if(o.op==="delete"){let c=!1;for(const p of Oe()){const h=String(p.keyOf(i));(p.partition.has(h)||t.get(p).has(h))&&(t.get(p).set(h,{op:"del"}),c=!0)}!c&&!Et(i).length&&(ot+=1,K&&K(o));continue}if(he){const c=Je.get(String(i[ce]));c&&(c.lastRow=i)}const s=Et(i);if(!s.length){ot+=1,K&&K(o),he&&st(String(i[ce]),"unrouted","no route (and no default sink) matched this row.");continue}for(const c of Oe()){if(s.includes(c))continue;const p=String(c.keyOf(i));(c.partition.has(p)||t.get(c).get(p)?.op==="set")&&t.get(c).set(p,{op:"del"})}for(const c of s)t.get(c).set(String(c.keyOf(i)),{op:"set",row:i})}const r=new Map;for(const o of Oe()){let i=0;const s=t.get(o).size;for(const[c,p]of t.get(o)){if(p.op==="del"){o.partition.delete(c);continue}o.partition.set(c,p.row),i+=1}o.metricRows+=i,o.explain.whenRouted+=i,re+=i,r.set(o,s)}for(const o of rt)Ht(o);Mt();for(const o of Oe()){const i=he?[...t.get(o).values()].filter(s=>s.op==="set").map(s=>s.row):null;wr(o,r.get(o)||0,i)}Fe=_e,Cn()}finally{Nt()}},push(e){const n=Array.isArray(e)?e:[e];if(!I)return this.apply(n),this;for(const t of n)if(Q.push(t),he&&t&&t.row){const r=String(t.row[ce]),o=Je.has(r)?Je.get(r):Qt("router",t.row[ce],r);o.lastRow=t.row,st(r,"not-yet-flushed","the delta is buffered for batch/coalesce and has not been applied yet.")}return y!==null&&(y<=0?this.flushStream():l||(l=setTimeout(()=>this.flushStream(),y))),this},flushStream(){if(l&&(clearTimeout(l),l=null),!Q.length)return this;const e=Q.splice(0,Q.length);return this.apply(e),this},flushBackpressure(){At();try{for(const e of Oe())e.bp&&(e.bpTimer||e.bpPending>0)&&en(e)}finally{Nt()}return this},addSource(e,n){let t,r;e&&typeof e=="object"?(r=e,t=r.id!=null?String(r.id):`source${++Ut}`):(t=e!=null?String(e):`source${++Ut}`,r=n||{});const o=Se.get(t);if(o)return F("data-router:duplicate-source",`addSource("${t}") was already registered; returning the existing source handle. Use a distinct id per feed.`),o.handle;const i={id:t,map:typeof r.map=="function"?r.map:null,fields:Hr(r.fields),ns:Lr(t,r.key),live:new Map,out:new Map,ingested:0,joins:[],unnests:[]};i.handle=tr(i),i.joins=rr(r.join,i),i.hasSpread=i.joins.some(s=>s.spread),Se.set(t,i);for(const s of i.joins)Se.has(s.from)&&un(Se.get(s.from),s);for(const s of Se.values())if(s!==i)for(const c of s.joins)c.from===t&&c.probe==null&&un(i,c);return i.unnests=or(r.unnest,i),i.explain=Dn(i),Jt.set(t,In(i)),i.handle},removeSource(e){const n=e&&typeof e=="object"&&e.id!==void 0?String(e.id):String(e),t=Se.get(n);return t&&t.handle.remove(),this},sources(){return[...Se.keys()]},relateRows(e={}){const n=m=>m&&typeof m=="object"&&m.id!==void 0?String(m.id):String(m),t=n(e.child),r=n(e.parent),o=Se.get(t),i=Se.get(r);if(!o||!i)return F("data-router:relaterows-missing-source","relateRows needs both `child` and `parent` to be registered source ids (or the handles addSource returned); the rule was ignored."),this;let s,c;if(typeof e.foreignKey=="function")s=e.foreignKey,c=`fn:${s.toString()}`;else if(typeof e.foreignKey=="string"&&e.foreignKey)s=m=>m[e.foreignKey],c=e.foreignKey;else return F("data-router:relaterows-no-foreignkey","relateRows needs a `foreignKey` (the child field holding the parent key); the rule was ignored."),this;const p=e.onParentDelete==="cascade"||e.onParentDelete==="orphan"?e.onParentDelete:null;if(!p)return this;o.probes||(o.probes=new Map);let h=o.probes.get(c);if(!h){h={fn:s,index:new Map,prev:new Map,specs:new Set},o.probes.set(c,h);for(const[m,v]of o.live){const A=Lt(h.fn(v));if(A==null)continue;let L=h.index.get(A);L||(L=new Set,h.index.set(A,L)),L.add(m),h.prev.set(m,A)}}return x.push({parentId:r,childId:t,fkFn:s,pkFn:m=>m[ce],onParentDelete:p,writeBack:e.writeBack===!0,probe:h,ex:Ct()}),this},fieldsOf(e){const n=Z(e);return!n||!n.spreadFields?[]:[...n.spreadFields.keys()]},metrics(){const e=k(),n=Oe().map((r,o)=>({index:o,label:r.label||(r.isDefault?"default":null),kind:typeof r.grid=="function"?"view":"grid",rows:r.partition.size,shown:r.keys.size,routed:r.metricRows,throughput:$n(`route:${o}`,r.metricRows,e),backpressure:r.bp?{pending:r.bpPending,coalesced:r.bpCoalesced}:null})),t=[...Se.values()].map(r=>({id:r.id,rows:r.live.size,ingested:r.ingested,throughput:$n(`source:${r.id}`,r.ingested,e)}));return{routes:n,sources:t,unrouted:ot,dropped:X,buffered:Ne.length,lag:ao(),throughput:$n("total",re,e)}},explain(e={}){const n=e&&e.source!=null?String(e.source):null,t=e&&e.route!==void 0?e.route:void 0;if(n!=null||t!==void 0){const o={};if(n!=null&&(o.source=Jt.get(n)||null),t!==void 0){const i=Z(t);if(i)o.route=gt.get(i.routeId)||null;else{const s=Le.find(c=>c.handler===t||c.label!=null&&c.label===t);o.route=s&>.get(s.routeId)||null}}return o}const r=[];for(const o of Oe()){const i=gt.get(o.routeId);i&&r.push(i)}for(const o of Le){const i=gt.get(o.routeId);i&&r.push(i)}return{sources:Object.fromEntries(Jt),routes:r,unrouted:ot,timingMs:pr}},trace:pn,on(e,n){if(typeof n!="function")return()=>{};let t=we.get(e);return t||(t=new Set,we.set(e,t)),t.add(n),e==="metrics"&&uo(),()=>{t.delete(n),e==="metrics"&&t.size===0&&fr()}},mountDevtools(e,n={}){return ae(this,e,n)},get unrouted(){return ot},get dropped(){return X},lastSeq(){return P},checkpoint(){return new Map(_)},seenThrough(e){const n=e instanceof Map?e.entries():Object.entries(e||{});for(const[t,r]of n){const o=Number(r);if(!Number.isFinite(o))continue;const i=_.get(String(t));(i===void 0||o>i)&&_.set(String(t),o),(P===void 0||o>P)&&(P=o)}return this},persist(e={}){if(me=!0,typeof e.key=="string"&&(et=e.key),Number.isFinite(e.debounce)&&(ft=Number(e.debounce)),e.storage&&typeof e.storage.get=="function"&&typeof e.storage.set=="function")ue=e.storage;else{let n=null;try{n=yo(e)}catch{n=null}n?ue=n:(ue=null,F("data-router:no-indexeddb","router.persist() found no usable IndexedDB (a non-browser runtime, private mode, or blocked storage); the router runs in-memory with no durable resume. Pass { storage } to use another backend."))}return this},async restore(){if(!ue)return!1;let e;try{e=await ue.get(et)}catch{return!1}return e==null?!1:ko(e)},async flushPersist(){return Ee&&(clearTimeout(Ee),Ee=null),await Ln(),Ge&&await Ge,this},get persisting(){return me&&!!ue},buffer(e={}){return Re=!0,Number.isFinite(e.max)?se=Number(e.max):"max"in e&&e.max==null&&(se=null),Number.isFinite(e.window)?ke=Number(e.window):"window"in e&&e.window==null&&(ke=null),se==null&&ke==null&&(se=M,F("data-router:buffer-default-cap",`buffer() called with no window or max; applying a default cap of ${M} deltas so the buffer stays bounded. Pass { window } or { max } to size it.`)),ve=De?"seq":"time",Yn(),this},scrubTo(e,n={}){if(!Pn("scrubTo"))return this;sn(),bt=!0;const t=n.by||ve;dt=rn(e,t),on([...dt.values()]),Fe=0;for(const r of Ne){const o=On(r,t);if(e!==void 0&&o!==void 0&&o>e)break;Fe=r.pos+1}return this},replay(e,n,t={}){if(!Pn("replay"))return Promise.resolve();sn(),bt=!0;const r=t.by||ve;return mn=r,pt=Number.isFinite(t.speed)?Number(t.speed):0,dt=rn(e,r),on([...dt.values()]),Ft=Ne.filter(o=>{const i=On(o,r);return i!==void 0&&i>e&&i<=n}).slice().sort((o,i)=>o.pos-i.pos),xt=0,Pt=!1,new Promise(o=>{vt=o,Rn()})},pause(){return Pt=!0,ct&&(clearTimeout(ct),ct=null),this},resume(){return Pt?(Pt=!1,Rn(),this):this},live(){return Pn("live")?(sn(),bt=!1,dt=null,on([...rn(void 0,ve).values()]),Fe=_e,this):this},get traveling(){return bt},get buffered(){return Ne.length},broadcast(e={}){if(typeof BroadcastChannel!="function")return F("data-router:no-broadcastchannel","router.broadcast() needs the BroadcastChannel API, which this runtime does not provide; cross-tab mirroring is off."),this;const n=e&&typeof e.channel=="string"?e.channel:"";return n?(je&&(je.close(),je=null),je=new BroadcastChannel(n),je.onmessage=Dr,ln({t:"hello"}),this):(F("data-router:broadcast-channel","router.broadcast({ channel }) needs a string channel name; nothing was mirrored."),this)},get broadcasting(){return!!je},async query(e,n={}){if(!e||typeof e.execute!="function")return F("data-router:bad-query-source","router.query(adapter) needs an adapter with an execute(query) function (a DFQL/DuckDB adapter or a pushdown source); nothing was fetched."),this;const t=oe(e.capabilities),r=n||{},o=r.filters||null,i=[];ot=0;const s=Oe().filter(p=>p.where),c=Oe().filter(p=>!p.where);for(const p of s){const h=Ce(o,p.where),m=be({...r,filters:h},t);let A=((await e.execute(m.pushed,r)).rows||[]).slice();m.residual&&m.residual.filters&&(A=A.filter(L=>ie(m.residual.filters,L))),A=A.filter(L=>p.match(L)),Ir(p,A),i.push({route:p.grid,pushedFilter:!!(m.pushed&&m.pushed.filters),residual:m.unpushed.slice()})}if(c.length){const p=be(r,t);let m=((await e.execute(p.pushed,r)).rows||[]).slice();p.residual&&p.residual.filters&&(m=m.filter(v=>ie(p.residual.filters,v))),Mr(m,c),i.push({base:!0,pushedFilter:!!(p.pushed&&p.pushed.filters),residual:p.unpushed.slice()})}ht=i;for(const p of rt)Ht(p);Mt();for(const p of Oe())jt(p);return this},lastQueryPlan(){return ht?ht.map(e=>({...e})):null},destroy(){if(wt&&(clearTimeout(wt),wt=null),l&&(clearTimeout(l),l=null),Ee&&(clearTimeout(Ee),Ee=null),ue&&typeof ue.close=="function")try{ue.close()}catch{}me=!1,ue=null,je&&(je.close(),je=null),Be=!1,sn(),Re=!1,bt=!1,dt=null,Ne.length=0,Ve.clear();for(const e of Rt.values())e.off();Rt.clear();for(const e of Tt.values())e();Tt.clear(),It.clear(),Se.clear(),fr(),we.clear(),T.clear();for(const e of Le)e.timer&&(clearTimeout(e.timer),e.timer=null);Le.length=0;for(const e of Oe())e.bpTimer&&(clearTimeout(e.bpTimer),e.bpTimer=null);rt.length=0,Ue.length=0,Dt.clear(),Q.length=0,_.clear(),Xe.length=0,Ye=null,Je.clear(),dn.clear()}};return g.config&&tt.configure(g.config),tt}function kt(g,d){if(g===d)return!0;if(!g||!d)return!1;const f=Object.keys(g),b=Object.keys(d);if(f.length!==b.length)return!1;for(const E of f)if(g[E]!==d[E])return!1;return!0}const He=Ke});var gn=qn("packages/modules/data-router/index.js");typeof module=="object"&&module.exports?module.exports=gn:typeof define=="function"&&define.amd?define(function(){return gn}):yr.LatticeGridDataRouter=gn})(typeof globalThis<"u"?globalThis:this);
|
|
6
|
+
(function(yr){"use strict";var Kn=Object.create(null),Hn=Object.create(null);function mt(w,Te){Kn[w]=Te}function qn(w){var Te=Hn[w];if(Te)return Te;var ye=Object.create(null);Hn[w]=ye;var F=Kn[w];if(!F)throw new Error("[lattice] missing module: "+w);return F(ye,qn),ye}mt("packages/core/src/internal/util.js",function(w,Te){"use strict";Object.defineProperty(w,"VERSION",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"reportedWarnings",{enumerable:!0,get:function(){return B}}),Object.defineProperty(w,"warnOnce",{enumerable:!0,get:function(){return te}}),Object.defineProperty(w,"infoOnce",{enumerable:!0,get:function(){return G}}),Object.defineProperty(w,"resetWarnings",{enumerable:!0,get:function(){return ne}}),Object.defineProperty(w,"fail",{enumerable:!0,get:function(){return $}}),Object.defineProperty(w,"invariant",{enumerable:!0,get:function(){return ee}}),Object.defineProperty(w,"DEV",{enumerable:!0,get:function(){return O}}),Object.defineProperty(w,"isObject",{enumerable:!0,get:function(){return R}}),Object.defineProperty(w,"isFunction",{enumerable:!0,get:function(){return j}}),Object.defineProperty(w,"isNil",{enumerable:!0,get:function(){return N}}),Object.defineProperty(w,"isBlank",{enumerable:!0,get:function(){return H}}),Object.defineProperty(w,"isCtor",{enumerable:!0,get:function(){return q}}),Object.defineProperty(w,"pathGetter",{enumerable:!0,get:function(){return de}}),Object.defineProperty(w,"pathSetter",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(w,"getPath",{enumerable:!0,get:function(){return $e}}),Object.defineProperty(w,"setPath",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(w,"humanise",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(w,"escapeHtml",{enumerable:!0,get:function(){return kt}}),Object.defineProperty(w,"titleCase",{enumerable:!0,get:function(){return He}}),Object.defineProperty(w,"expand",{enumerable:!0,get:function(){return g}}),Object.defineProperty(w,"toArray",{enumerable:!0,get:function(){return d}}),Object.defineProperty(w,"merge",{enumerable:!0,get:function(){return b}}),Object.defineProperty(w,"mergeRow",{enumerable:!0,get:function(){return E}}),Object.defineProperty(w,"Lru",{enumerable:!0,get:function(){return K}}),Object.defineProperty(w,"collator",{enumerable:!0,get:function(){return ze}}),Object.defineProperty(w,"defaultCompare",{enumerable:!0,get:function(){return ut}}),Object.defineProperty(w,"now",{enumerable:!0,get:function(){return De}}),Object.defineProperty(w,"nextFrame",{enumerable:!0,get:function(){return a}}),Object.defineProperty(w,"cancelFrame",{enumerable:!0,get:function(){return y}}),Object.defineProperty(w,"frameBatched",{enumerable:!0,get:function(){return I}}),Object.defineProperty(w,"settleDebounce",{enumerable:!0,get:function(){return _}}),Object.defineProperty(w,"whenIdle",{enumerable:!0,get:function(){return P}}),Object.defineProperty(w,"uid",{enumerable:!0,get:function(){return Q}});const ye="1.89.1";async function F(){return ye}const le="1.89.1",be=new Set,oe=2e3;function Pe(l){if(be.add(l),be.size>oe){const u=be.values().next().value;u!==void 0&&be.delete(u)}}const D=[],Y=500;function ae(l,u,k){D.push({key:l,level:u,message:k.map(M=>typeof M=="string"?M:W(M)).join(" "),at:Date.now()}),D.length>Y&&D.shift()}function W(l){if(l instanceof Error)return l.message;try{return JSON.stringify(l)}catch{return String(l)}}function B(){return D.map(l=>({...l}))}function J(l){if(l.length===0||typeof l[0]!="string")return l;const u=l[0].replace(/^\[lattice\]\s*/,"");return u===l[0]?l:[u,...l.slice(1)]}function te(l,...u){if(be.has(l))return;Pe(l);const k=J(u);ae(l,"warn",k),console.warn("[lattice]",...k)}function G(l,...u){if(be.has(l))return;Pe(l);const k=J(u);ae(l,"info",k),console.info("[lattice]",...k)}function ne(){be.clear(),D.length=0}function $(l,u){const k=new Error(`[lattice] ${l}`);throw u!==void 0&&(k.cause=u),k}function ee(l,u){l||$(u)}const O=(()=>{try{return!(typeof process<"u"&&process.env&&process.env.NODE_ENV==="production")}catch{return!0}})();function R(l){return l!==null&&typeof l=="object"&&!Array.isArray(l)}function j(l){return typeof l=="function"}function N(l){return l==null}function H(l){return l==null||l===""}function q(l){return typeof l!="function"?!1:/^class[\s{]/.test(Function.prototype.toString.call(l))?!0:!!(l.prototype&&Object.getOwnPropertyNames(l.prototype).length>1)}const z=new Map;function de(l){let u=z.get(l);if(u)return u;if(!l.includes("."))u=k=>k?.[l];else{const k=l.split("."),M=k.length;u=Re=>{let se=Re;for(let ke=0;ke<M;ke++){if(se==null)return;se=se[k[ke]]}return se}}return z.set(l,u),u}const qe=new Map;function Ce(l){let u=qe.get(l);if(u)return u;if(!l.includes("."))u=(k,M)=>{k!=null&&(k[l]=M)};else{const k=l.split("."),M=k.length-1;u=(Re,se)=>{let ke=Re;for(let ve=0;ve<M;ve++){if(ke==null)return;const Ve=k[ve];ke[Ve]==null&&(ke[Ve]={}),ke=ke[Ve]}ke!=null&&(ke[k[M]]=se)}}return qe.set(l,u),u}function $e(l,u){return de(u)(l)}function pe(l,u,k){Ce(u)(l,k)}function ie(l){return l?(l.includes(".")?l.slice(l.lastIndexOf(".")+1):l).replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").replace(/\s+/g," ").trim().replace(/^./,k=>k.toUpperCase()):""}const Ke={"&":"&","<":"<",">":">",'"':""","'":"'"};function kt(l){const u=l==null?"":String(l);return/[&<>"']/.test(u)?u.replace(/[&<>"']/g,k=>Ke[k]):u}function He(l){return String(l).replace(/\w\S*/g,u=>u[0].toUpperCase()+u.slice(1).toLowerCase())}function g(l,u,k){if(l!==void 0)return l===!0?{enabled:!0,...k}:l===!1?{enabled:!1}:R(l)?l:{[u]:l,enabled:!0}}function d(l){return l==null?[]:Array.isArray(l)?l:[l]}const f=Object.freeze(new Set(["__proto__","constructor","prototype"]));function b(l,u){if(!R(l))return R(u)?{...u}:u;if(!R(u))return u===void 0?l:u;const k={...l};for(const M of Object.keys(u)){if(f.has(M))continue;const Re=u[M];Re!==void 0&&(k[M]=R(Re)&&R(k[M])?b(k[M],Re):Re)}return k}function E(l,u){if(!R(l)||!R(u)||l===u)return u;const k=Object.create(Object.getPrototypeOf(l));return Object.assign(k,l,u),k}class K{#e;#t=new Map;#n;constructor(u=256,k=null){this.#e=u,this.#n=k}get size(){return this.#t.size}get max(){return this.#e}set max(u){this.#e=u,this.#r()}has(u){return this.#t.has(u)}get(u){const k=this.#t;if(!k.has(u))return;const M=k.get(u);return k.delete(u),k.set(u,M),M}peek(u){return this.#t.get(u)}set(u,k){const M=this.#t;return M.has(u)&&M.delete(u),M.set(u,k),this.#r(),k}delete(u){const k=this.#t.get(u);return this.#t.delete(u)&&this.#n&&this.#n(k,u),k}clear(){if(this.#n)for(const[u,k]of this.#t)this.#n(k,u);this.#t.clear()}keys(){return this.#t.keys()}values(){return this.#t.values()}#r(){const u=this.#t;for(;u.size>this.#e;){const k=u.keys().next().value,M=u.get(k);u.delete(k),this.#n&&this.#n(M,k)}}}const V=new Map;function ze(l,u){const k=`${l||""}|${u?JSON.stringify(u):""}`;let M=V.get(k);return M||(M=new Intl.Collator(l||void 0,{numeric:!0,sensitivity:"variant",...u}),V.set(k,M)),M}function ut(l,u){if(l===u)return 0;if(l==null)return 1;if(u==null)return-1;if(typeof l=="number"&&typeof u=="number")return Number.isNaN(l)?Number.isNaN(u)?0:1:Number.isNaN(u)||l<u?-1:l>u?1:0;const k=String(l),M=String(u);return k<M?-1:k>M?1:0}function De(){return typeof performance<"u"&&performance.now?performance.now():Date.now()}const nt=typeof requestAnimationFrame=="function";function a(l){return nt?requestAnimationFrame(l):setTimeout(()=>l(De()),16)}function y(l){l!=null&&(nt?cancelAnimationFrame(l):clearTimeout(l))}function I(l){let u=null,k=null;const M=()=>{u=null;const se=k;k=null,l(...se||[])},Re=(...se)=>{k=se,u===null&&(u=a(M))};return Re.cancel=()=>{y(u),u=null,k=null},Re.flush=()=>{u!==null&&(y(u),M())},Re}function _(l,u){let k=null,M=null;const Re=()=>{if(k=null,M===null)return;const ve=M;M=null,l(...ve),se()},se=()=>{k=setTimeout(Re,u),typeof k?.unref=="function"&&k.unref()},ke=(...ve)=>{k===null?(l(...ve),se()):(M=ve,clearTimeout(k),se())};return ke.flush=()=>{if(k!==null&&clearTimeout(k),k=null,M===null)return;const ve=M;M=null,l(...ve)},ke.cancel=()=>{k!==null&&clearTimeout(k),k=null,M=null},ke.pending=()=>k!==null||M!==null,ke}function P(l,u=50){return typeof requestIdleCallback=="function"?requestIdleCallback(l,{timeout:u}):setTimeout(()=>l({timeRemaining:()=>0,didTimeout:!0}),1)}let X=0;function Q(l="l"){return`${l}${(++X).toString(36)}`}}),mt("packages/core/src/source/filterwire.js",function(w,Te){"use strict";Object.defineProperty(w,"HOST_FILTER_WARN_ID",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"WHERE_PAGE_RELATIVE_WARN_ID",{enumerable:!0,get:function(){return be}}),Object.defineProperty(w,"warnWherePageRelative",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"warnHostFilterNotApplied",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(w,"WHERE_NOT_APPLIED_WARN_ID",{enumerable:!0,get:function(){return D}}),Object.defineProperty(w,"warnWhereNotApplied",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(w,"WHERE_OVER_THRESHOLD_WARN_ID",{enumerable:!0,get:function(){return ae}}),Object.defineProperty(w,"warnWhereOverThreshold",{enumerable:!0,get:function(){return W}}),Object.defineProperty(w,"RELATIVE_TOKENS",{enumerable:!0,get:function(){return O}}),Object.defineProperty(w,"parseRelativeToken",{enumerable:!0,get:function(){return R}}),Object.defineProperty(w,"resolveRelativeRange",{enumerable:!0,get:function(){return j}}),Object.defineProperty(w,"relativeTokenOf",{enumerable:!0,get:function(){return N}}),Object.defineProperty(w,"relativeTokenHelp",{enumerable:!0,get:function(){return H}}),Object.defineProperty(w,"isResolvableRelative",{enumerable:!0,get:function(){return q}}),Object.defineProperty(w,"resolveRelativeCondition",{enumerable:!0,get:function(){return z}}),Object.defineProperty(w,"isGroup",{enumerable:!0,get:function(){return de}}),Object.defineProperty(w,"forEachCondition",{enumerable:!0,get:function(){return qe}}),Object.defineProperty(w,"mapConditions",{enumerable:!0,get:function(){return Ce}}),Object.defineProperty(w,"normaliseFilterSet",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(w,"buildFilterSet",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(w,"wireFilters",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(w,"querySignature",{enumerable:!0,get:function(){return kt}});const F=Te("packages/core/src/internal/util.js").warnOnce,le="source.remote.hostFilter",be="source.where.pageRelative";function oe(d,f){!Array.isArray(d)||!d.length||F(be,`filters.where (${d.join(", ")}) runs over the rows the ${f} source fetched,`,"not the whole dataset: match counts and totals are page-relative.","Give the predicate a { condition } twin so the engine can narrow the fetch itself.")}function Pe(d){const f=(d||{}).config;!f||!f.hostFilter||F(le,"config.hostFilter is not sent to a server-delegated source (paged/remote) and is not applied:","filtering only the fetched window would give wrong counts and totals.","Express the filter as a FilterSet condition, or send it through config.context.")}const D="source.where.notApplied";function Y(d,f){F(`${D}:${d}`,`filters.where("${d}") is registered but the ${f} source holds only its fetched window`,"and cannot run the predicate over it: the predicate is not applied there, and rows it would","exclude stay on screen.","Give it a { condition } twin so the engine can narrow the fetch itself — that is the","supported route for a paged or remote source.")}const ae="source.where.overThreshold";function W(d,f,b,E){!Array.isArray(d)||!d.length||F(`${ae}:${f}`,`filters.where (${d.join(", ")}) is not applied to the ${f} pushdown source:`,b===null?"the adapter reports no row total, so the size of the matching set is unknown.":`its matching set is ${b.toLocaleString()} rows, at or past the whereRowLimit of ${E.toLocaleString()}.`,"Running the predicate needs every matching row fetched and held here, which is the whole","download a pushdown source exists to avoid, so it is refused and the rows the predicate","would exclude stay on screen.","Give the predicate a { condition } twin so the engine narrows the fetch itself — that is the","route that works at any size — or raise `whereRowLimit` on the source config if you want the","download.")}const B=new Map;function J(d){let f=B.get(d);return f||(f=new Intl.DateTimeFormat("en-US",{timeZone:d,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}),B.set(d,f)),f}function te(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC"}catch{return"UTC"}}function G(d,f){const b=J(f).formatToParts(new Date(d)),E={y:1970,m:1,d:1,h:0,mi:0,s:0};for(const K of b)K.type==="year"?E.y=+K.value:K.type==="month"?E.m=+K.value:K.type==="day"?E.d=+K.value:K.type==="hour"?E.h=+K.value%24:K.type==="minute"?E.mi=+K.value:K.type==="second"&&(E.s=+K.value);return E}function ne(d,f){const b=G(d,f);return Date.UTC(b.y,b.m-1,b.d,b.h,b.mi,b.s)-Math.floor(d/1e3)*1e3}function $(d,f,b,E){const K=Date.UTC(d,f-1,b),V=K-ne(K,E);return K-ne(V,E)}function ee(d,f,b){const E=new Date(Date.UTC(d.y,d.m-1,d.d+f));return $(E.getUTCFullYear(),E.getUTCMonth()+1,E.getUTCDate(),b)}const O=Object.freeze(["today","yesterday","lastNDays","thisWeek","thisMonth","thisQuarter","thisYear","quarterToDate","yearToDate"]);function R(d,f){if(typeof d!="string")return null;const b=d.trim().toLowerCase().replace(/[\s_-]+/g,""),E=/^last(\d*|n)days?$/.exec(b);if(E){const K=E[1]==="n"?"":E[1],V=Number(K||f);return!Number.isFinite(V)||V<=0?null:{kind:"lastNDays",n:Math.floor(V)}}switch(b){case"today":return{kind:"today",n:0};case"yesterday":return{kind:"yesterday",n:0};case"thisweek":return{kind:"thisWeek",n:0};case"thismonth":return{kind:"thisMonth",n:0};case"thisquarter":return{kind:"thisQuarter",n:0};case"thisyear":return{kind:"thisYear",n:0};case"quartertodate":case"qtd":return{kind:"quarterToDate",n:0};case"yeartodate":case"ytd":return{kind:"yearToDate",n:0};default:return null}}function j(d,f={}){const b=R(d,f.n);if(!b)return null;const E=f.tz||te(),K=f.now instanceof Date?f.now.getTime():typeof f.now=="number"?f.now:Date.now(),V=G(K,E),ze=$(V.y,V.m,V.d,E),ut=ee(V,1,E);let De=ze,nt=ut;switch(b.kind){case"today":break;case"yesterday":De=ee(V,-1,E),nt=ze;break;case"lastNDays":nt=f.includeToday?ut:ze,De=ee(V,f.includeToday?-(b.n-1):-b.n,E);break;case"thisWeek":{const a=Number.isFinite(f.weekStartsOn)?Number(f.weekStartsOn):1,I=(new Date(Date.UTC(V.y,V.m-1,V.d)).getUTCDay()-a+7)%7;De=ee(V,-I,E),nt=ee(V,-I+7,E);break}case"thisMonth":De=$(V.y,V.m,1,E),nt=$(V.m===12?V.y+1:V.y,V.m===12?1:V.m+1,1,E);break;case"thisQuarter":case"quarterToDate":{const a=Math.floor((V.m-1)/3)*3+1;De=$(V.y,a,1,E),nt=b.kind==="quarterToDate"?ut:a===10?$(V.y+1,1,1,E):$(V.y,a+3,1,E);break}case"thisYear":case"yearToDate":De=$(V.y,1,1,E),nt=b.kind==="yearToDate"?ut:$(V.y+1,1,1,E);break;default:return null}return{from:new Date(De).toISOString(),to:new Date(nt).toISOString(),bounds:"[)",tz:E,relative:b.kind==="lastNDays"?`last${b.n}Days`:b.kind,n:b.n}}function N(d){if(!d||typeof d!="object")return null;const f=d.value;if(f&&typeof f=="object"&&!Array.isArray(f)&&"relative"in f)return{token:String(f.relative),n:typeof f.n=="number"?f.n:void 0};if(d.op==="relative"&&typeof d.value=="string")return{token:d.value,n:void 0};const b=d.meta;return b&&typeof b.relative=="string"&&d.value===void 0?{token:b.relative,n:typeof b.n=="number"?b.n:void 0}:null}function H(){return`Known tokens: ${O.filter(f=>f!=="lastNDays").join(", ")}. "lastNDays" needs a count: pass "last7Days", or the value object { relative: 'lastNDays', n: 7 }.`}function q(d){const f=N(d);return f?R(f.token,f.n)!==null:!1}function z(d,f={}){const b=N(d);if(!b)return d;const E=j(b.token,{...f,n:b.n});return E?{...d,type:d.type||"date",op:"between",value:[E.from,E.to],bounds:d.bounds||E.bounds,meta:{...d.meta||{},relative:E.relative,tz:E.tz}}:(F(`source.relative.${b.token}`,`unknown relative date token "${b.token}"; sending the condition unresolved.`,H()),d)}function de(d){return!!d&&typeof d=="object"&&Array.isArray(d.conditions)}function qe(d,f){if(d){if(de(d)){for(const b of d.conditions)qe(b,f);return}f(d)}}function Ce(d,f){if(!d)return null;if(!de(d))return f(d);const b=d;let E=!1;const K=[];for(const V of b.conditions){const ze=Ce(V,f);ze!==V&&(E=!0),ze&&K.push(ze)}return!E&&K.length===b.conditions.length?d:K.length?{...b,conditions:K}:null}function $e(d){if(!d)return null;if(!de(d))return d;const f=d,b=[];for(const E of f.conditions){const K=$e(E);K&&b.push(K)}return b.length?{op:f.op,conditions:b}:null}function pe(d){const f=$e(d);return f?de(f)&&f.op==="and"?f:{op:"and",conditions:[f]}:null}function ie(d){const f=(d||[]).filter(Boolean);return f.length?{op:"and",conditions:f}:null}function Ke(d,f={}){const b=Ce(d,E=>z(E,f));return pe(b)}function kt(d){const f=He(d.filters??null);return JSON.stringify([f,d.sort??null,d.quick??"",d.groupBy??null,d.pivotBy??null,g(d.context)])}function He(d){if(!d)return null;if(de(d)){const E=d;return{op:E.op,conditions:E.conditions.map(He)}}const f=d,b=f.meta&&typeof f.meta.relative=="string"?f.meta.relative:N(f)?.token;return{col:f.col,op:f.op,bounds:f.bounds??null,caseSensitive:f.caseSensitive??!1,value:b?`rel:${b}`:f.value??null}}function g(d){if(d==null)return null;try{return JSON.parse(JSON.stringify(d))}catch{return F("source.context.unserialisable","config.context is not JSON-serialisable; cache keys ignore it."),"[unserialisable]"}}}),mt("packages/core/src/source/aggregates.js",function(w,Te){"use strict";Object.defineProperty(w,"STAT_PUSHDOWN",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(w,"pushableAggregates",{enumerable:!0,get:function(){return F}}),Object.defineProperty(w,"fillAggregateSql",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"resolveAggregatesConfig",{enumerable:!0,get:function(){return be}}),Object.defineProperty(w,"routeAggregate",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"resolveAggregatePlan",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(w,"groupKeysPushable",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(w,"pushdownDocRows",{enumerable:!0,get:function(){return ae}});const ye=Object.freeze({sum:{pushable:!0,class:"identical",sql:"sum(%c)"},avg:{pushable:!0,class:"identical",sql:"avg(%c)"},min:{pushable:!0,class:"identical",sql:"min(%c)"},max:{pushable:!0,class:"identical",sql:"max(%c)"},count:{pushable:!0,class:"identical",sql:"count(*)"},countValues:{pushable:!0,class:"identical",sql:"count(%c)",blankAware:!0},range:{pushable:!0,class:"identical",sql:"(max(%c) - min(%c))"},variance:{pushable:!0,class:"identical",sql:"var_samp(%c)"},varianceP:{pushable:!0,class:"identical",sql:"var_pop(%c)"},stddev:{pushable:!0,class:"identical",sql:"stddev_samp(%c)"},stddevP:{pushable:!0,class:"identical",sql:"stddev_pop(%c)"},sumSquares:{pushable:!0,class:"identical",sql:"sum(%c * %c)"},median:{pushable:!0,class:"identical",sql:"median(%c)"},p25:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.25)"},p75:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.75)"},p90:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.9)"},p95:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.95)"},p99:{pushable:!0,class:"identical",sql:"quantile_cont(%c, 0.99)"},iqr:{pushable:!0,class:"identical",sql:"(quantile_cont(%c, 0.75) - quantile_cont(%c, 0.25))"},mad:{pushable:!0,class:"identical",sql:"mad(%c)"},distinct:{pushable:!0,class:"identical",sql:"count(DISTINCT %c)",blankAware:!0},skewness:{pushable:!0,class:"identical",sql:"skewness(%c)"},kurtosis:{pushable:!0,class:"identical",sql:"kurtosis(%c)"},geomean:{pushable:!0,class:"identical",sql:"exp(avg(ln(%c)))"},harmean:{pushable:!0,class:"identical",sql:"(count(%c) / sum(1.0 / %c))"},entropy:{pushable:!0,class:"identical",sql:"entropy(%c)",blankAware:!0},correlation:{pushable:!0,class:"identical",sql:"corr(%w, %c)",twoColumn:!0},hhi:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_transform(map_values(histogram(%c)), lambda v: (v::DOUBLE/count(%c))*(v::DOUBLE/count(%c)))) END"},evenness:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL WHEN count(DISTINCT %c)<2 THEN 1.0 ELSE entropy(%c)/log2(count(DISTINCT %c)) END"},top3Share:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,3))::DOUBLE/count(%c) END"},top10Share:{pushable:!0,class:"identical",blankAware:!0,sql:"CASE WHEN count(%c)=0 THEN NULL ELSE list_sum(list_slice(list_sort(map_values(histogram(%c)),'DESC'),1,10))::DOUBLE/count(%c) END"},gini:{pushable:!0,class:"identical",sql:"CASE WHEN list_min(list(%c) FILTER (WHERE isfinite(%c)))<0 THEN NULL WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL WHEN list_sum(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN 0 ELSE 2.0*list_sum(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v, i: i*v))/(len(list(%c) FILTER (WHERE isfinite(%c)))*list_sum(list(%c) FILTER (WHERE isfinite(%c))))-(len(list(%c) FILTER (WHERE isfinite(%c)))+1.0)/len(list(%c) FILTER (WHERE isfinite(%c))) END"},trimmedMean:{pushable:!0,class:"identical",sql:"CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE list_avg(list_slice(list_sort(list(%c) FILTER (WHERE isfinite(%c))), floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1, len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT)) END"},winsorizedMean:{pushable:!0,class:"identical",sql:"CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))=0 THEN NULL ELSE list_avg(list_transform(list_sort(list(%c) FILTER (WHERE isfinite(%c))), lambda v: least(list_sort(list(%c) FILTER (WHERE isfinite(%c)))[len(list(%c) FILTER (WHERE isfinite(%c)))-floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT], greatest(list_sort(list(%c) FILTER (WHERE isfinite(%c)))[floor(len(list(%c) FILTER (WHERE isfinite(%c)))*0.1)::BIGINT+1], v)))) END"},robustOutliers:{pushable:!0,class:"identical",sql:"(SELECT CASE WHEN len(d.a)=0 THEN NULL WHEN d.mad=0 THEN NULL ELSE len(list_filter(d.a, lambda v: abs(0.6745*(v-d.med)/d.mad)>3.5)) END FROM (SELECT xs AS a, list_median(xs) AS med, list_median(list_transform(xs, lambda w: abs(w-list_median(xs)))) AS mad FROM (SELECT list(%c) FILTER (WHERE isfinite(%c)) AS xs)) d)"},jarqueBera:{pushable:!0,class:"identical",sql:"CASE WHEN len(list(%c) FILTER (WHERE isfinite(%c)))<8 THEN NULL WHEN list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2)))=0 THEN NULL ELSE (len(list(%c) FILTER (WHERE isfinite(%c)))/6.0)*(power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),3)))/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),1.5),2)+power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),4)))/power(list_avg(list_transform(list(%c) FILTER (WHERE isfinite(%c)), lambda v: power(v-list_avg(list(%c) FILTER (WHERE isfinite(%c))),2))),2)-3,2)/4.0) END"},weightedAvg:{pushable:!0,class:"identical",twoColumn:!0,sql:"sum(%c*%w) FILTER (WHERE isfinite(%c) AND isfinite(%w))/nullif(sum(%w) FILTER (WHERE isfinite(%c) AND isfinite(%w)),0)"},mode:{pushable:!0,class:"may-differ",sql:"mode(%c)",note:"DuckDB returns a modal value even for an all-distinct column; the grid returns null. Tie-breaking can also differ, and on a text column an empty string counts as a value. Under pushdown you will see a value."},weightedQuantile:{pushable:!1,class:"fallback",note:"No SQL equivalent for the grid's weighted-quantile midpoint convention; always computed client-side (needs a full-dataset pull for a correct figure over a remote source)."}});function F(){const W=new Set;for(const[B,J]of Object.entries(ye))J.pushable&&W.add(B);return W}function le(W,B,J){let te=W.split("%c").join(B);return J!==void 0&&(te=te.split("%w").join(J)),te}function be(W){const B=W||{},J=B.default==="engine"||B.default==="engine-if-identical"?B.default:"client",te={};if(B.overrides&&typeof B.overrides=="object")for(const[G,ne]of Object.entries(B.overrides))(ne==="engine"||ne==="client")&&(te[G]=ne);return{default:J,overrides:te}}function oe(W,B){const J=ye[W];if(!J||!J.pushable)return"client";const te=B.overrides[W];return te==="engine"||te==="client"?te:B.default==="client"?"client":B.default==="engine-if-identical"?J.class==="identical"?"engine":"client":"engine"}function Pe(W,B){const J=be(B),te=[],G=[];for(const ne of W||[]){const $=ye[ne.fn],ee=oe(ne.fn,J),O={id:ne.id,col:ne.col,fn:ne.fn,class:$?$.class:"fallback"};ne.weight!==void 0&&(O.weight=ne.weight),ne.params!==void 0&&(O.params=ne.params),ee==="engine"?te.push(O):(O.reason=$&&!$.pushable?$.note||"the engine cannot express this stat":"client by config",G.push(O))}return{engine:te,client:G,config:J}}const D=/^[A-Za-z_][A-Za-z0-9_$]*$/;function Y(W,B=[]){return(W||[]).every(te=>{if(typeof te=="string")return D.test(te);if(!te||typeof te!="object")return!1;const G=te;return Array.isArray(B)&&B.includes(G.bucket)&&typeof G.col=="string"&&D.test(G.col)&&typeof G.size=="number"&&Number.isFinite(G.size)&&G.size>0})}function ae(){return Object.entries(ye).map(([W,B])=>({stat:W,class:B.class,sql:B.sql?le(B.sql,"col",B.twoColumn?"weight":void 0):"",note:B.note||(B.class==="identical"?"Pushes to DuckDB with the same result.":"")}))}}),mt("packages/core/src/source/abort.js",function(w,Te){"use strict";Object.defineProperty(w,"SupersededError",{enumerable:!0,get:function(){return ye}}),Object.defineProperty(w,"RequestToken",{enumerable:!0,get:function(){return F}}),Object.defineProperty(w,"AbortScope",{enumerable:!0,get:function(){return le}}),Object.defineProperty(w,"createAbortScope",{enumerable:!0,get:function(){return be}}),Object.defineProperty(w,"isAbortError",{enumerable:!0,get:function(){return oe}});class ye extends Error{constructor(D,Y="superseded"){super(`[lattice] request ${D?`"${D}" `:""}${Y}`),this.name="SupersededError",this.superseded=!0,this.key=D}}class F{#e;constructor(D,Y,ae,W){this.#e=D,this.key=Y,this.controller=ae,this.signal=ae.signal,this.seq=W}get current(){return!this.signal.aborted&&this.#e.tokenFor(this.key)===this}settle(){this.#e.settle(this)}abort(D){this.signal.aborted||this.controller.abort(new ye(this.key,D)),this.#e.settle(this)}}class le{#e=new Map;#t=0;begin(D="",Y="superseded"){const ae=this.#e.get(D);ae&&!ae.signal.aborted&&ae.controller.abort(new ye(D,Y));const W=new F(this,D,new AbortController,++this.#t);return this.#e.set(D,W),W}tokenFor(D){return this.#e.get(D)}pending(D=""){const Y=this.#e.get(D);return!!Y&&!Y.signal.aborted}get size(){return this.#e.size}settle(D){this.#e.get(D.key)===D&&this.#e.delete(D.key)}abort(D="",Y="superseded"){const ae=this.#e.get(D);ae&&ae.abort(Y)}abortAll(D="superseded"){for(const Y of[...this.#e.values()])Y.abort(D);this.#e.clear()}}function be(){return new le}function oe(Pe){if(!Pe||typeof Pe!="object")return!1;const D=Pe;return D.superseded===!0||D.name==="AbortError"||D.name==="SupersededError"}}),mt("packages/core/src/source/pushdown.js",function(w,Te){"use strict";Object.defineProperty(w,"FOREGROUND_WAIT_MS",{enumerable:!0,get:function(){return $}}),Object.defineProperty(w,"NO_CAPABILITIES",{enumerable:!0,get:function(){return O}}),Object.defineProperty(w,"resolveMutate",{enumerable:!0,get:function(){return R}}),Object.defineProperty(w,"capabilitiesOf",{enumerable:!0,get:function(){return H}}),Object.defineProperty(w,"splitFilters",{enumerable:!0,get:function(){return z}}),Object.defineProperty(w,"LEAF_COUNT_ID",{enumerable:!0,get:function(){return de}}),Object.defineProperty(w,"PIVOT_UNSUPPORTED",{enumerable:!0,get:function(){return pe}}),Object.defineProperty(w,"GROUP_UNSUPPORTED",{enumerable:!0,get:function(){return ie}}),Object.defineProperty(w,"UNGROUPED_LEVEL",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(w,"planQuery",{enumerable:!0,get:function(){return He}}),Object.defineProperty(w,"applyResidual",{enumerable:!0,get:function(){return f}}),Object.defineProperty(w,"DEFAULT_WHERE_ROW_LIMIT",{enumerable:!0,get:function(){return V}}),Object.defineProperty(w,"createPushdownSource",{enumerable:!0,get:function(){return nt}});const ye=Te("packages/core/src/internal/util.js"),F=ye.defaultCompare,le=ye.isFunction,be=ye.toArray,oe=ye.warnOnce,Pe=Te("packages/core/src/source/filterwire.js"),D=Pe.isGroup,Y=Pe.warnWherePageRelative,ae=Pe.warnWhereOverThreshold,W=Te("packages/core/src/source/aggregates.js"),B=W.resolveAggregatePlan,J=W.groupKeysPushable,te=W.STAT_PUSHDOWN,ne=Te("packages/core/src/source/abort.js").SupersededError,$=1e3;function ee(a){const y=a&&a.signal;if(!y||!y.aborted)return;const I=y.reason;throw I instanceof Error?I:new ne("","superseded before it was sent")}const O=Object.freeze({filter:!1,operators:Object.freeze([]),sort:!1,quick:!1,range:!1,total:!1,group:!1,pivot:!1,mutate:!1});function R(a){if(!a||typeof a!="object")return!1;const y=a.returning==="row"||a.returning==="key"?a.returning:"none";return{append:a.append===!0,update:a.update===!0,delete:a.delete===!0,returning:y}}function j(a,y){if(!a||typeof y!="string")return;if(!y.includes("."))return a[y];let I=a;for(const _ of y.split(".")){if(I===null||typeof I!="object")return;I=I[_]}return I}function N(a){if(a===!0)return!0;if(!a||typeof a!="object")return!1;const y=a;return y.enabled===!1?!1:y.enabled===!0||le(y.commit)}function H(a){const y={...O,...a||{}};return y.operators=new Set(y.operators||[]),y.mutate=R(y.mutate),y}function q(a,y){return!a||!a.op||!y.operators.size?!1:y.operators.has(a.op)}function z(a,y){if(!a)return{pushed:null,residual:null};if(!y.filter)return{pushed:null,residual:a};if(y.filter==="term"){if(D(a)){const X=a.conditions||[];if(String(a.op)!=="and")return{pushed:null,residual:a};const Q=X.findIndex(u=>!D(u)&&q(u,y));if(Q<0)return{pushed:null,residual:a};const l=X.filter((u,k)=>k!==Q);return{pushed:X[Q],residual:l.length?{op:"and",conditions:l}:null}}return q(a,y)?{pushed:a,residual:null}:{pushed:null,residual:a}}if(!D(a))return q(a,y)?{pushed:a,residual:null}:{pushed:null,residual:a};if(String(a.op)!=="and")return(a.conditions||[]).every(Q=>D(Q)?z(Q,y).residual===null:q(Q,y))?{pushed:a,residual:null}:{pushed:null,residual:a};const I=[],_=[];for(const X of a.conditions||[]){if(D(X)){if(y.filter==="flat"){_.push(X);continue}const Q=z(X,y);Q.pushed&&I.push(Q.pushed),Q.residual&&_.push(Q.residual);continue}(q(X,y)?I:_).push(X)}const P=X=>X.length===0?null:X.length===1?X[0]:{op:"and",conditions:X};return{pushed:P(I),residual:P(_)}}const de="__lattice_leaves";function qe(a){return a.aggregates?a.aggregates instanceof Set?a.aggregates:new Set(be(a.aggregates)):new Set}function Ce(a){const y=qe(a);return y.size?y.has("count")?a.filter!=="tree"||!a.operators||!a.operators.has("eq")?"the adapter does not declare the `group` capability, and cannot narrow a group's rows by its key (that needs a `tree` filter with the `eq` operator)":"":"the adapter does not declare the `group` capability, and its declared aggregates have no `count` to give each group its row count":"the adapter does not declare the `group` capability"}function $e(a,y,I,_,P,X,Q){const l=Array.isArray(a.groupBy)?a.groupBy:[],u=Array.isArray(a.groupPath)?a.groupPath:[],k=Array.isArray(a.groupValues)?a.groupValues:null;if(!y.group){const M=Ce(y);if(M)return M}return J(l)?I.residual?"the filter did not fully push, so the engine would group a superset of the matching rows":_?P?X?"a host `where` predicate can only run in the browser, over rows the engine grouped":Q?"fullDataset holds the whole matching set, so the grid groups it itself":!k||k.length!==u.length?"the request carries no typed `groupValues` for its group path, and the string `groupPath` cannot be compared against a typed column":"":"a quick search did not push, so the engine would group unsearched rows":"the sort did not push, so the engine would order the groups differently":"a grouping key is not a plain column the engine can name in a GROUP BY"}const pe="pushdown:pivot-unsupported",ie="pushdown:group-unsupported",Ke=Symbol("lattice.remote.ungroupedLevel");function kt(a,y,I,_,P,X){const Q=Array.isArray(a.pivotBy)?a.pivotBy:[],l=Array.isArray(a.groupBy)?a.groupBy:[],u=Array.isArray(a.groupPath)?a.groupPath:[],k=Array.isArray(a.groupValues)?a.groupValues:null;return y.pivot?J(Q)?l.length&&!J(l)?"a grouping key is not a plain column the engine can name in a GROUP BY":I.residual?"the filter did not fully push, so the engine would pivot a superset of the matching rows":_?P?X?"a host `where` predicate can only run in the browser, over rows the engine pivoted":!k||k.length!==u.length?"the request carries no typed `groupValues` for its group path, and the string `groupPath` cannot be compared against a typed column":"":"a quick search did not push, so the engine would pivot unsearched rows":"the sort did not push, so the engine would order the rows differently":"a pivot column is not a plain column the engine can name in a GROUP BY":"the adapter does not declare the `pivot` capability"}function He(a,y,I=!1){const _=z(a.filters||null,y),P=[];_.residual&&P.push("filter");const X=a.sort||[],Q=X.length===0||y.sort==="multi"&&X.length>=1||y.sort==="single"&&X.length===1;!Q&&X.length&&P.push("sort");const l=a.quick?String(a.quick):"",u=!l||!!y.quick;u||P.push("quick");const k=a.where&&a.where.active?a.where:null;k&&P.push("where");const M={filters:_.residual,sort:Q?null:X,quick:u?"":l,where:k},Re=!!I,se=Array.isArray(a.groupBy)&&a.groupBy.length>0,ke=se?$e(a,y,_,Q,u,k,Re):"",ve=a.pivotMode!==!1&&Array.isArray(a.pivotBy)&&a.pivotBy.length>0,Ve=ve?kt(a,y,_,Q,u,k):"",Ne=ve&&Ve==="";ve&&!Ne&&P.push("pivot");const _e=ve?Ne&&se:se&&ke==="";se&&!ve&&!_e&&P.push("group");const Me=(_e||Ne)&&Array.isArray(a.groupValues)?a.groupValues.length:0,yt=_e||ve?!1:Re||!!(M.filters||M.sort||M.quick||M.where)||!y.range;return{pushed:{...a,filters:_.pushed,sort:Q?X:[],quick:u?l:"",range:yt?null:a.range},residual:M,needsAll:yt,unpushed:P,full:Re,grouped:_e,groupLevel:Me,groupReason:ve?"":ke,pivoted:Ne,pivotReason:Ve}}function g(a){const y=Array.isArray(a.totals)?a.totals:[],I=a.totalFns&&typeof a.totalFns=="object"?a.totalFns:{},_=[],P=[];for(const X of y){const Q=String(X),l=typeof I[Q]=="string"?I[Q]:null,u=l?te[l]:null;l?!u||!u.pushable||!u.sql?P.push({id:Q,fn:l,class:u?u.class:"fallback",reason:u&&u.note?u.note:`the pushdown map cannot express "${l}"`}):u.twoColumn?P.push({id:Q,fn:l,class:u.class,reason:`"${l}" reduces two columns, and a grouped request carries no weight column`}):_.push({id:Q,col:Q,fn:l,class:u.class}):P.push({id:Q,fn:null,class:"fallback",reason:"the column totals with a host function, so there is no named statistic to push"})}return{engine:_,client:P}}const d=Object.freeze({items:a=>a==null?[]:Array.isArray(a)?a:[a]});function f(a,y,I){if(!y)return a;let _=a;if(y.filters&&le(I.evaluateFilters)){const P=_,X={count:_.length,handle:u=>({id:u,get:k=>j(P[k],u)}),itemwise:u=>P.some(k=>Array.isArray(j(k,u)))?d:null},Q=I.evaluateFilters(y.filters,X),l=[];for(let u=0;u<_.length;u++)Q[u]&&l.push(_[u]);_=l}if(y.where&&y.where.active&&(y.whole||Y(y.where.names,"pushdown"),_=_.filter(P=>y.where.passes(P))),y.quick){const P=y.quick.toLowerCase();_=_.filter(X=>{if(!X||typeof X!="object")return!1;for(const Q of Object.values(X))if(Q!=null&&String(Q).toLowerCase().includes(P))return!0;return!1})}if(y.sort&&y.sort.length&&le(I.sortMulti)){const P=[...new Set(y.sort.map(u=>u.col))],X=_,Q=P.map(u=>({id:u,get:k=>j(X[k],u)})),l=I.sortMulti(Q,y.sort.map(u=>({col:u.col,dir:u.dir})),Uint32Array.from({length:_.length},(u,k)=>k),{});_=Array.from(l,u=>X[u])}return _}function b(a){return JSON.stringify({filters:a.filters||null,sort:a.sort||[],quick:a.quick||"",groupBy:a.groupBy||[],groupPath:a.groupPath||[],context:a.context??null})}function E(a){if(!a||typeof a!="object")return 16;let y="";try{y=JSON.stringify(a)}catch{return 200}return y.length*2+64}function K(a){const y=a||{};return{enabled:!!y.enabled,maxRows:Number.isFinite(y.maxRows)?y.maxRows:1e6,maxBytesEstimate:Number.isFinite(y.maxBytesEstimate)?y.maxBytesEstimate:512*1024*1024}}const V=5e4;function ze(a){return Number.isFinite(a)&&a>=0?a:V}function ut(a){return!!a&&le(a.then)}async function De(a){if(!a||a.total!==void 0||!ut(a.pendingTotal))return a;const y=await a.pendingTotal,{pendingTotal:I,..._}=a;return typeof y=="number"?{..._,total:y}:_}function nt(a={}){const y=a.adapter;if(!y||!le(y.execute))return oe("source.pushdown.adapter","createPushdownSource needs an `adapter` with an `execute(query)` function."),{...a,mode:"remote",fetch:async()=>({rows:[],total:0})};const I=H(y.capabilities),_=y.capabilities&&Object.getOwnPropertyDescriptor(y.capabilities,"operators");_&&le(_.get)&&Object.defineProperty(I,"operators",{enumerable:!0,configurable:!0,get:()=>new Set(y.capabilities.operators||[]),set:()=>{}});const P=y.name||"adapter";let X=null;const Q=()=>le(y.ready)?(X||(X=Promise.resolve(y.ready()).then(()=>{Object.assign(I,H(y.capabilities))},x=>{throw X=null,x})),X):null,l=K(a.fullDataset),u=!!a.allowPartialResults,k=ze(a.whereRowLimit);let M=null;const Re=a.aggregates;let se=null,ke=null,ve=null,Ve=null,Ne=null,_e,Me=null,yt=0,bt=null;const dt=()=>!l.enabled||!se?null:(bt!==se.key&&(yt++,bt=se.key),{rows:se.rows,version:yt}),Ft=async x=>{const C=x.where&&x.where.active?x.where:null;if(!C)return{request:x,probe:null};const{where:U,...re}=x,T=He(re,I,l.enabled);if(T.needsAll)return{request:x,probe:null};const we=b(T.pushed);let fe=null;return(!M||M.key!==we)&&(I.total?(ee(x),fe=await De(await y.execute(T.pushed,x)),M={key:we,size:fe&&typeof fe.total=="number"?fe.total:null}):M={key:we,size:null}),M.size!==null&&M.size<k?{request:x,probe:null}:(ae(C.names,P,M.size,k),{request:re,probe:fe})},xt=async(x,C)=>{Me=null;const U=g(x.pushed);ve={engine:U.engine,client:U.client,groupBy:x.pushed.groupBy},U.client.length&&oe(`source.pushdown.group.totals.${P}.${U.client.map(we=>we.id).join(".")}`,`the ${P} adapter cannot compute the group subtotal for ${U.client.map(we=>`"${we.id}" (${we.reason})`).join(", ")}, so those group rows carry no value for that column. A figure computed over anything other than the group would be wrong, so none is shown; \`lastPlan().aggregates.client\` names them.`);const re=await y.executeGroupLevel(x.pushed,U.engine,C)||{};let T=re.rows||[];return!I.range&&C.range&&(T=T.slice(C.range.start,C.range.end)),ct(re),re.total===void 0?{rows:T}:{rows:T,total:re.total}},pt=new Map,mn=64,Pt=async(x,C)=>{Me=null;const U=x.pushed,re=U.groupBy,T=Array.isArray(U.groupValues)?U.groupValues:[],we=T.length,fe=[...U.filters?[U.filters]:[],...re.slice(0,we).map((Z,Qe)=>({col:Z,op:"eq",value:T[Qe]===void 0?null:T[Qe],caseSensitive:!0}))],We=fe.length===0?null:fe.length===1?fe[0]:{op:"and",conditions:fe},Fe=C.range?C.range.start:0;if(we>=re.length){const Z={...U,filters:We,groupBy:[],groupPath:[],groupValues:[],totals:[],totalFns:{}},Qe=await De(await y.execute(Z,C))||{};let it=Qe.rows||[];return!I.range&&C.range&&(it=it.slice(C.range.start,C.range.end)),typeof Qe.total=="number"?{rows:it,total:Qe.total}:{rows:it}}const ue=re[we],et=g(U),ft=qe(I),Ee=et.engine.filter(Z=>ft.has(Z.fn)),Ge=[...et.engine.filter(Z=>!ft.has(Z.fn)).map(Z=>({id:Z.id,fn:Z.fn,class:Z.class,reason:`the ${P} adapter does not compute "${Z.fn}"`})),...et.client];ve={engine:Ee,client:Ge,groupBy:re},Ge.length&&oe(`source.pushdown.group.totals.${P}.${Ge.map(Z=>Z.id).join(".")}`,`the ${P} adapter cannot compute the group subtotal for ${Ge.map(Z=>`"${Z.id}" (${Z.reason})`).join(", ")}, so those group rows carry no value for that column. A figure computed over anything other than the group would be wrong, so none is shown; \`lastPlan().aggregates.client\` names them.`);const me=[...Ee.map(Z=>({id:Z.id,col:Z.col,fn:Z.fn})),{id:de,col:ue,fn:"count"}],xe={...U,filters:We,range:null},je=JSON.stringify([b(xe),T,ue,me]);let Be=Fe>0?pt.get(je):void 0;if(!Be){for(Be=Promise.resolve(y.executeGroupedAggregates(xe,[ue],me)),pt.delete(je),pt.set(je,Be);pt.size>mn;)pt.delete(pt.keys().next().value);Be.catch(()=>{pt.get(je)===Be&&pt.delete(je)})}const ht=await Be||[];ee(C);const Le=Z=>{const Qe={};for(const it of Ee)Qe[it.id]=Z?Z[it.id]:void 0;return Qe},Oe=(U.sort||[]).find(Z=>Z&&Z.col===ue),St=Oe&&Oe.dir==="desc"?-1:1,Et=ht.filter(Z=>Z&&Z.level===1).map(Z=>({[ue]:Z.keys[0]===void 0?null:Z.keys[0],leafCount:Number(Z.values&&Z.values[de])||0,totals:Le(Z.values)})).sort((Z,Qe)=>St*F(Z[ue],Qe[ue]));if(we===0){const Z=ht.find(it=>it&&it.level===0),Qe=Z?Number(Z.values&&Z.values[de]):NaN;ct({matchCount:Number.isFinite(Qe)?Qe:Et.reduce((it,wn)=>it+wn.leafCount,0),...Z?{grand:Le(Z.values)}:{}})}const bn=C.range?C.range.end:Et.length;return{rows:Et.slice(Fe,bn),total:Et.length}},ct=x=>{typeof x.matchCount=="number"&&(Ve=x.matchCount,Ne=x.grand?{totals:x.grand,leafCount:x.matchCount}:null,_e===void 0&&le(y.unfilteredCount)&&(_e=null,Promise.resolve(y.unfilteredCount()).then(C=>{_e=typeof C=="number"?C:null}).catch(C=>{oe(`source.pushdown.group.unfiltered.${P}`,`the ${P} adapter could not count the unfiltered set (${C&&C.message?C.message:C}), so "N of M" falls back to the display count for its denominator.`)})))},vt=async(x,C)=>{Me=null;const U=g(x.pushed);ve={engine:U.engine,client:U.client,groupBy:x.pushed.groupBy,pivotBy:x.pushed.pivotBy},U.client.length&&oe(`source.pushdown.pivot.totals.${P}.${U.client.map(We=>We.id).join(".")}`,`the ${P} adapter cannot compute the pivot cells for ${U.client.map(We=>`"${We.id}" (${We.reason})`).join(", ")}, so those cells are empty. A figure computed over anything other than the cell would be wrong, so none is shown; \`lastPlan().aggregates.client\` names them.`);const re=await y.executePivotLevel(x.pushed,U.engine,C)||{};let T=re.rows||[];!I.range&&C.range&&(T=T.slice(C.range.start,C.range.end)),ct(re);const we=re.pivot&&typeof re.pivot=="object"?re.pivot:{},fe={cells:Array.isArray(we.cells)?we.cells:[],...Array.isArray(we.axis)?{axis:we.axis}:{}};return re.total===void 0?{rows:T,pivot:fe}:{rows:T,total:re.total,pivot:fe}},$t=x=>{oe(`source.pushdown.pivot.${P}.${x}`,`pushdown:pivot-unsupported: the ${P} adapter cannot pivot this query because ${x}, so no rows are fetched rather than every leaf row being pulled into the browser to pivot there. \`lastPlan().pivotReason\` says the same.`);const C=new Error(`[lattice] ${pe}: the ${P} adapter cannot pivot this query because ${x}, so no rows are fetched rather than every leaf row being pulled into the browser to pivot there. \`lastPlan().pivotReason\` says the same.`);throw C.code=pe,C.reason=x,C},yn=(x,C)=>{const U={key:C,state:"pending",value:null};return Me=U,x.then(re=>(Me===U&&(Me={key:C,state:"settled",value:typeof re=="number"?re:null}),re),re=>{throw Me===U&&(Me={key:C,state:"failed",value:null}),re})};let Xe=0,Ye=[];const rt=()=>Xe===0?null:new Promise(x=>{const C=setTimeout(x,$);Ye.push(()=>{clearTimeout(C),x()})});let Ue;const Rt=async x=>{const C=Q();C&&await C;const re=x&&x.pivotMode!==!1&&Array.isArray(x.pivotBy)&&x.pivotBy.length>0?{request:x,probe:null}:await Ft(x);ee(x);let T=He(re.request,I,l.enabled);if(I.group&&T.grouped&&!T.pivoted&&!le(y.executeGroupLevel)&&(oe(`source.pushdown.group.method.${P}`,`the ${P} adapter declares the \`group\` capability but has no \`executeGroupLevel(query, aggregates, request)\`, so grouping is not pushed and the grid stays ungrouped unless it holds the whole matching set. Implement the method or drop the capability.`),T=He(re.request,{...I,group:!1,aggregates:null},l.enabled)),T.pivoted&&!le(y.executePivotLevel)&&(T=He(re.request,{...I,pivot:!1},l.enabled),T.pivotReason="the adapter declares the `pivot` capability but has no `executePivotLevel(query, aggregates, request)`"),T.grouped&&!T.pivoted&&!I.group&&!le(y.executeGroupedAggregates)&&(oe(`source.pushdown.group.aggregates.method.${P}`,`the ${P} adapter declares \`aggregates\` but has no \`executeGroupedAggregates(query, groupBy, aggregates)\`, so the grouped view cannot be built from grouped aggregates and the grid stays ungrouped unless it holds the whole matching set. Implement the method, or declare \`group\` and implement \`executeGroupLevel\`.`),T=He(re.request,{...I,aggregates:null},l.enabled)),ke=T,T.pivoted)return vt(T,x);if(T.pivotReason&&$t(T.pivotReason),T.grouped)return I.group?xt(T,x):Pt(T,x);const fe=!!T.groupReason&&!T.full;fe?oe(`source.pushdown.group-unsupported.${P}.${T.groupReason}`,`pushdown:group-unsupported: the ${P} adapter was not asked to group this query because ${T.groupReason}, so the grid stays ungrouped rather than building group rows, counts and subtotals from a window of leaf rows. \`lastPlan().groupReason\` says the same.`):T.groupReason&&oe(`source.pushdown.group.${P}.${T.groupReason}`,`the ${P} adapter was not asked to group this query because ${T.groupReason}. The engine returns rows and the grouping is the grid's to do, which needs every matching row in the browser — correct where the grid holds them, and wrong-looking where it holds a window. \`lastPlan().unpushed\` names it.`);const We=me=>fe?{...me,[Ke]:!0}:me;if(!T.needsAll){const me=re.probe||await y.execute(T.pushed,x),xe=me.rows||[];return ut(me.pendingTotal)&&me.total===void 0?We({rows:xe,pendingTotal:yn(me.pendingTotal,b(T.pushed))}):(Me=null,!I.total&&me.total===void 0?We({rows:xe}):We({rows:xe,total:me.total??xe.length}))}T.unpushed.length&&oe(`source.pushdown.residual.${P}.${T.unpushed.join(".")}`,`the ${P} adapter cannot push ${T.unpushed.join(" or ")}, so every matching row is fetched and the rest is applied in the browser. Correct, and slower than it needs to be: widening the adapter is the fix.`);const Fe=b(T.pushed);if(!se||se.key!==Fe){const me=await De(await y.execute(T.pushed,x));Me=null;const xe=me.rows||[];if(T.full){const je=typeof me.total=="number"?Math.max(me.total,xe.length):xe.length;if(je>l.maxRows)throw new Error(`[lattice] fullDataset refused: the ${P} adapter's matching set is ${je.toLocaleString()} rows, past the configured maxRows of ${l.maxRows.toLocaleString()}. The whole set cannot be held client-side, so it is refused rather than truncated — a fraction shown as the whole would make every total and statistic silently wrong. Narrow the filter or raise maxRows.`);const Be=xe.length*E(xe[0]);if(Be>l.maxBytesEstimate)throw new Error(`[lattice] fullDataset refused: the ${P} adapter's matching set is an estimated ${Math.round(Be/(1024*1024)).toLocaleString()} MB across ${xe.length.toLocaleString()} rows, past the configured maxBytesEstimate of ${Math.round(l.maxBytesEstimate/(1024*1024)).toLocaleString()} MB. The whole set cannot be held client-side, so it is refused rather than truncated. Narrow the filter or raise maxBytesEstimate.`)}if(typeof me.total=="number"&&xe.length<me.total){const je=!!(T.residual.filters||T.residual.quick||T.residual.sort&&T.residual.sort.length);if(je&&!u)throw new Error(`[lattice] the ${P} adapter returned ${xe.length} of ${me.total} matching rows when asked for the whole result, and the query has residual ${T.unpushed.join(" and ")||"work"} to finish in the browser. Filtering or sorting a fraction of the result would return wrong rows, so the result is refused. Fix the adapter to follow the engine's own paging before returning, hold the data in memory, or set \`allowPartialResults: true\` on the source config to accept this knowingly.`);je?oe(`source.pushdown.partial.residual.${P}`,`the ${P} adapter returned ${xe.length} of ${me.total} matching rows when asked for the whole result, and residual work will run over that fraction. allowPartialResults is set, so the result is used as-is — it may be wrong. The adapter must follow the engine's own paging to be correct.`):oe(`source.pushdown.partial.${P}`,`the ${P} adapter returned ${xe.length} of ${me.total} matching rows when asked for the whole result. The adapter must follow the engine's own paging before returning.`)}se={key:Fe,rows:xe,total:typeof me.total=="number"?me.total:null}}let ue=T;if(T.residual.where){const me=se.total??se.rows.length;if(me>=k){ae(T.residual.where.names,P,me,k);const{where:xe,...je}=re.request;ue=He(je,I,l.enabled),ke=ue}}const et=se.total!==null&&se.rows.length>=se.total,ft=f(se.rows,{...ue.residual,whole:et},a.compute||{}),Ee=x.range?x.range.start:0,Ge=x.range?x.range.end:ft.length;return We({rows:ft.slice(Ee,Ge),total:ft.length})},Dt=async(x,C,U)=>{const T=U&&U.waitForPage&&Ue&&le(Ue.pageForegroundIdle)?Ue.pageForegroundIdle():rt();T&&await T;const we=Q();we&&await we;const fe=He(x,I,l.enabled);ke=fe;const We=B(C,Re),Fe=Array.isArray(x.groupBy)?x.groupBy:[],ue=Fe.length>0,et=!fe.residual.filters&&!fe.residual.quick,ft=!ue||J(Fe,I.buckets);let Ee=We.engine,Ge=We.client;if(I.aggregates&&Ee.length){const Be=I.aggregates instanceof Set?I.aggregates:new Set(be(I.aggregates)),ht=Ee.filter(Le=>!Be.has(Le.fn));ht.length&&(Ee=Ee.filter(Le=>Be.has(Le.fn)),Ge=[...ht.map(Le=>({...Le,reason:`the ${P} adapter does not compute "${Le.fn}"`})),...Ge])}const me=Be=>{Ge=[...Ee.map(ht=>({...ht,reason:Be})),...Ge],Ee=[]};Ee.length&&!et?me(fe.residual.quick&&!fe.residual.filters?"a quick search the adapter cannot push forces all-client (no mixed provenance)":"residual filter forces all-client (no mixed provenance)"):Ee.length&&!ft&&me("a grouping key the engine cannot form forces all-client (no mixed provenance)");let xe={},je;return Ee.length&&(le(ue?y.executeGroupedAggregates:y.executeAggregates)?ue?je=await y.executeGroupedAggregates(fe.pushed,Fe,Ee)||[]:xe=await y.executeAggregates(fe.pushed,Ee)||{}:(oe(`source.pushdown.aggregates.${P}${ue?".grouped":""}`,`the ${P} adapter cannot compute ${ue?"grouped ":""}aggregates, so every requested statistic is computed client-side. Correct, and slower than it needs to be.`),me(`adapter cannot compute ${ue?"grouped ":""}aggregates`))),ve={engine:Ee,client:Ge,...ue?{groupBy:Fe}:{}},{values:xe,engine:Ee,client:Ge,...je!==void 0?{groups:je}:{}}},wt=async x=>{Xe++;try{return await Rt(x)}finally{if(Xe--,Xe===0&&Ye.length){const C=Ye;Ye=[];for(const U of C)U()}}},ot=N(a.edit),Tt=a.edit&&typeof a.edit=="object"&&le(a.edit.commit);let It=a.edit;if(ot&&!Tt)if(I.mutate&&I.mutate.update){const x=C=>{if(!I.mutate||!I.mutate.update)throw new Error(`[lattice] the ${P} adapter cannot update rows (mutate.update is not declared), so this edit cannot be persisted. The cell is reverted rather than left looking saved.`);const U={kind:"update",key:String(C.key),patch:{[C.colId]:C.value}};return y.mutate(U,C.request||{})};It={...a.edit===!0?{}:a.edit,commit:x}}else oe(`source.pushdown.readonly.${P}`,`edit is enabled but the ${P} adapter declares mutate: ${I.mutate?"without update":"false"} (read-only by declaration), so no commit is synthesised and the grid stays read-only. Declare \`mutate: { update: true }\` on the adapter to allow cell edits.`);const ce=ot&&I.mutate&&(I.mutate.append||I.mutate.delete)?{append:I.mutate.append===!0,remove:I.mutate.delete===!0,returning:I.mutate.returning,mutate:(x,C)=>y.mutate(x,C||{})}:null,Se=async x=>{const C=Q();C&&await C;const{range:U,signal:re,export:T,...we}=x||{},fe={...we,groupBy:[],groupPath:[],groupValues:[],pivotBy:[],pivotMode:!1,totals:[]};return{plan:He(fe,I,l.enabled),signal:re}};async function*Ut(x,C={}){const{plan:U,signal:re}=await Se(x),T=Math.max(1,Math.floor(Number(C.pageSize))||5e3),we={signal:re,stream:!0};if(!U.needsAll)for(let Fe=0;;Fe+=T){ee(we);const ue=await y.execute({...U.pushed,range:{start:Fe,end:Fe+T}},we);ue&&ut(ue.pendingTotal)&&ue.pendingTotal.then(null,()=>{});const et=ue&&ue.rows||[];if(et.length&&(yield et),et.length<T)return}ee(we);const fe=await De(await y.execute({...U.pushed,range:void 0},we)),We=f(fe&&fe.rows||[],{...U.residual,whole:!0},a.compute||{});for(let Fe=0;Fe<We.length;Fe+=T)yield We.slice(Fe,Fe+T)}return Ue={...a,edit:It,rowMutate:ce,mode:"remote",fetch:wt,foregroundIdle:rt,aggregate:Dt,countMatching:async x=>{const{plan:C,signal:U}=await Se(x);if(!C.needsAll&&I.total){ee({signal:U});const T=await De(await y.execute({...C.pushed,range:{start:0,end:0}},{signal:U}));if(T&&typeof T.total=="number")return T.total}let re=0;for await(const T of Ut(x))re+=T.length;return re},streamMatching:Ut,lastPlan:()=>ke?{...ke,...ve?{aggregates:ve}:{},...Me?{total:{deferred:!0,state:Me.state,value:Me.value}}:{}}:null,fullFrame:dt,counts:()=>({match:Ve,total:_e??null,pending:!!Me&&Me.state==="pending"}),grandTotals:()=>Ne},Ue}}),mt("packages/core/src/model/rowkey.js",function(w,Te){"use strict";Object.defineProperty(w,"KEY_DEPENDENT_FEATURES",{enumerable:!0,get:function(){return Pe}}),Object.defineProperty(w,"compositeKey",{enumerable:!0,get:function(){return ae}}),Object.defineProperty(w,"createRowKey",{enumerable:!0,get:function(){return W}}),Object.defineProperty(w,"warnMissingKeys",{enumerable:!0,get:function(){return te}}),Object.defineProperty(w,"groupPathKey",{enumerable:!0,get:function(){return G}}),Object.defineProperty(w,"splitPathKey",{enumerable:!0,get:function(){return ne}});const ye=Te("packages/core/src/internal/util.js"),F=ye.warnOnce,le=ye.pathGetter,be=ye.isFunction,oe=ye.isBlank,Pe=["changes (rows.apply / rows.queue)","streaming dedupe","selection persistence","remote reload","cell comments"],D="";function Y($){if($===null)return"\0n";if($===void 0)return"\0u";const ee=typeof $;if(ee==="string")return $;if(ee==="number"||ee==="bigint"||ee==="boolean")return String($);if($ instanceof Date)return`\0d${$.getTime()}`;try{return`\0o${JSON.stringify($)}`}catch{return"\0o?"}}function ae($){if($.length===1)return Y($[0]);let ee="";for(let O=0;O<$.length;O++)O&&(ee+=D),ee+=Y($[O]);return ee}function W($,ee={}){const O=ee.warn!==!1;if(be($)){const R=$;return{stable:!0,fields:[],disabled:[],key(j,N){try{const H=R(j);return Array.isArray(H)?ae(H):Y(H)}catch(H){return F("rowKey.throw","rowKey function threw; falling back to index identity for the affected rows.",H),`#${N??-1}`}},keyEmpty(j){try{const N=R(j);return Array.isArray(N)?N.length===0||N.some(oe):oe(N)}catch{return!1}},missingFields(){return[]}}}if(Array.isArray($)&&$.length>0){const R=$.filter(H=>typeof H=="string"),j=R.map(H=>le(H)),N=j.length;return{stable:!0,fields:R,disabled:[],key(H){const q=new Array(N);for(let z=0;z<N;z++)q[z]=j[z](H);return ae(q)},keyEmpty(H){for(let q=0;q<N;q++)if(oe(j[q](H)))return!0;return!1},missingFields(H){const q=[];for(let z=0;z<N;z++)oe(j[z](H))&&q.push(R[z]);return q}}}if(typeof $=="string"&&$.length>0){const R=le($);return{stable:!0,fields:[$],disabled:[],key(j){return Y(R(j))},keyEmpty(j){return oe(R(j))},missingFields(j){return oe(R(j))?[$]:[]}}}return O&&F("rowKey.missing",`no rowKey configured, so rows are identified by object identity. This disables: ${Pe.join(", ")}. Set rowKey to a field name, an array of field names, or a function.`),{stable:!1,fields:[],disabled:Pe.slice(),key(R,j){if(R===null||typeof R!="object")return`#${j??0}:${String(R)}`;let N=B.get(R);return N===void 0&&(N=`#${J++}`,B.set(R,N)),N}}}const B=new WeakMap;let J=0;function te($,ee){if(!$||$.stable===!1||!be($.keyEmpty)||!Array.isArray(ee)||ee.length===0)return;let O=0,R=null,j;for(let z=0;z<ee.length;z++){const de=ee[z];$.keyEmpty(de)&&(O++,R===null&&(R=be($.missingFields)?$.missingFields(de):[],j=de))}if(O===0)return;const N=$.fields.length?$.fields.join(","):"(function)",H=R&&R.length?R.join(", "):$.fields.length?$.fields.join(", "):"the rowKey function",q=j!==null&&typeof j=="object"?Object.keys(j).join(", ")||"(no fields)":String(j);F(`rowKey.emptyValue:${N}`,`rowKey ${H} is missing on ${O} of ${ee.length} rows; the first such row has: ${q}. Rows without a key value collapse onto one key, so selection, edits and rows.apply updates land on whichever row now shares it. Set rowKey to a field present on every row, or fix the source data.`)}function G($){return ae($)}function ne($){return $.split(D)}}),mt("packages/modules/data-router/devtools.js",function(w,Te){"use strict";Object.defineProperty(w,"mountRouterDevtools",{enumerable:!0,get:function(){return Y}}),Object.defineProperty(w,"default",{enumerable:!0,get:function(){return ae}});const F=Te("packages/core/src/internal/util.js").warnOnce,le="lat-router-devtools";function be(W,B,J){const te=W.createElement(B);return te.textContent=J==null?"—":String(J),te}function oe(W){return Number.isFinite(W)?`${Math.round(W*10)/10}/s`:"—"}function Pe(W,B,J,te){const G=W.createElement("section");G.className=`${le}-section`;const ne=W.createElement("h4");ne.textContent=B,G.appendChild(ne);const $=W.createElement("table"),ee=W.createElement("tr");for(const O of J)ee.appendChild(be(W,"th",O));$.appendChild(ee);for(const O of te){const R=W.createElement("tr");for(const j of O)R.appendChild(be(W,"td",j));$.appendChild(R)}return G.appendChild($),G}function D(W,B,J){B.textContent="";const te=Pe(W,"Router",["metric","value"],[["throughput",oe(J.throughput)],["unrouted",J.unrouted],["dropped (duplicate)",J.dropped],["buffer depth",J.buffered],["lag (deltas behind)",J.lag]]);B.appendChild(te),B.appendChild(Pe(W,"Routes",["#","label","kind","rows","shown","rows/sec"],J.routes.map(G=>[G.index,G.label,G.kind,G.rows,G.shown,oe(G.throughput)]))),J.sources.length&&B.appendChild(Pe(W,"Sources",["id","rows","ingested","rows/sec"],J.sources.map(G=>[G.id,G.rows,G.ingested,oe(G.throughput)])))}function Y(W,B,J={}){const te=B&&B.ownerDocument||(typeof document<"u"?document:null);if(!W||typeof W.metrics!="function"||typeof W.on!="function"||!B||!te)return F("data-router:devtools-target","router.mountDevtools(el) needs a router with metrics()/on() and a DOM element to render into; the panel was not mounted."),{destroy(){},refresh(){}};const G=te.createElement("div");G.className=le,B.appendChild(G);const ne=()=>D(te,G,W.metrics());ne();const $=W.on("metrics",()=>ne());return{refresh:ne,destroy(){$(),G.parentNode&&G.parentNode.removeChild(G)}}}const ae=Y}),mt("packages/core/src/format/date.js",function(w,Te){"use strict";Object.defineProperty(w,"scanPattern",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"toDate",{enumerable:!0,get:function(){return D}}),Object.defineProperty(w,"compilePattern",{enumerable:!0,get:function(){return W}}),Object.defineProperty(w,"compileDate",{enumerable:!0,get:function(){return J}}),Object.defineProperty(w,"toIsoDate",{enumerable:!0,get:function(){return te}}),Object.defineProperty(w,"toIsoDateTime",{enumerable:!0,get:function(){return G}}),Object.defineProperty(w,"compareIso",{enumerable:!0,get:function(){return ee}});const ye=Te("packages/core/src/internal/util.js"),F=ye.isNil,le=ye.warnOnce,be=["yyyy","yy","MMMM","MMM","MM","M","dd","d","EEEE","EEE","HH","H","hh","h","mm","m","ss","s","SSS","a"];function oe(O){const R=[];let j=0,N="";const H=()=>{N&&(R.push({token:null,text:N}),N="")};for(;j<O.length;){const q=O[j];if(q==="'"){if(O[j+1]==="'"){N+="'",j+=2;continue}const de=O.indexOf("'",j+1);if(de===-1){N+=O.slice(j+1),j=O.length;continue}N+=O.slice(j+1,de),j=de+1;continue}const z=be.find(de=>O.startsWith(de,j));if(z){H(),R.push({token:z,text:z}),j+=z.length;continue}/[A-Za-z]/.test(q)&&le(`date.pattern.token:${q}`,`the date pattern "${O}" contains '${q}', which is not a supported token, so it is rendered as text. Quote it as a literal to silence this. Supported: ${be.join(" ")}.`),N+=q,j+=1}return H(),R}const Pe=/^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2}))?(?:\.\d+)?)?$/;function D(O){if(F(O)||O==="")return null;if(O instanceof Date)return Number.isNaN(O.getTime())?null:O;if(typeof O=="number")return Number.isNaN(O)?null:new Date(O);if(typeof O=="string"){const R=Pe.exec(O.trim());if(R){const[,N,H,q,z="0",de="0",qe="0"]=R;return new Date(+N,+H-1,+q,+z,+de,+qe)}const j=new Date(O);return Number.isNaN(j.getTime())?null:j}return null}function Y(O,R){return String(O).padStart(R,"0")}function ae(O){if(!O)return N=>({year:N.getFullYear(),month:N.getMonth()+1,day:N.getDate(),hour:N.getHours(),minute:N.getMinutes(),second:N.getSeconds(),ms:N.getMilliseconds(),weekday:N.getDay()});const R=new Intl.DateTimeFormat("en-US",{timeZone:O,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,weekday:"short"}),j={Sun:0,Mon:1,Tue:2,Wed:3,Thu:4,Fri:5,Sat:6};return N=>{const H={year:0,month:1,day:1,hour:0,minute:0,second:0,ms:N.getMilliseconds(),weekday:0};for(const q of R.formatToParts(N))switch(q.type){case"year":H.year=Number(q.value);break;case"month":H.month=Number(q.value);break;case"day":H.day=Number(q.value);break;case"hour":H.hour=Number(q.value)%24;break;case"minute":H.minute=Number(q.value);break;case"second":H.second=Number(q.value);break;case"weekday":H.weekday=j[q.value]??0;break;default:break}return H}}function W(O,R,j){const N=oe(O),H=ae(j),q=new Set(N.filter($e=>$e.token).map($e=>$e.token)),z=q.has("MMM")?new Intl.DateTimeFormat(R,{month:"short",timeZone:j}):null,de=q.has("MMMM")?new Intl.DateTimeFormat(R,{month:"long",timeZone:j}):null,qe=q.has("EEE")?new Intl.DateTimeFormat(R,{weekday:"short",timeZone:j}):null,Ce=q.has("EEEE")?new Intl.DateTimeFormat(R,{weekday:"long",timeZone:j}):null;return $e=>{const pe=H($e);let ie="";for(const Ke of N){if(!Ke.token){ie+=Ke.text;continue}switch(Ke.token){case"yyyy":ie+=Y(pe.year,4);break;case"yy":ie+=Y(pe.year%100,2);break;case"MMMM":ie+=de.format($e);break;case"MMM":ie+=z.format($e);break;case"MM":ie+=Y(pe.month,2);break;case"M":ie+=String(pe.month);break;case"dd":ie+=Y(pe.day,2);break;case"d":ie+=String(pe.day);break;case"EEEE":ie+=Ce.format($e);break;case"EEE":ie+=qe.format($e);break;case"HH":ie+=Y(pe.hour,2);break;case"H":ie+=String(pe.hour);break;case"hh":ie+=Y(pe.hour%12===0?12:pe.hour%12,2);break;case"h":ie+=String(pe.hour%12===0?12:pe.hour%12);break;case"mm":ie+=Y(pe.minute,2);break;case"m":ie+=String(pe.minute);break;case"ss":ie+=Y(pe.second,2);break;case"s":ie+=String(pe.second);break;case"SSS":ie+=Y(pe.ms,3);break;case"a":ie+=pe.hour<12?"AM":"PM";break;default:ie+=Ke.text;break}}return ie}}const B=[["year",365*24*36e5],["month",720*36e5],["week",168*36e5],["day",24*36e5],["hour",36e5],["minute",6e4],["second",1e3]];function J(O,R){const j=O||{},N=j.locale||R||void 0,H=j.nullDisplay??"",q=j.timeZone;let z;if(j.pattern)z=W(j.pattern,N,q);else if(j.dateStyle||j.timeStyle){const pe={timeZone:q};j.dateStyle&&(pe.dateStyle=j.dateStyle),j.timeStyle&&(pe.timeStyle=j.timeStyle);const ie=new Intl.DateTimeFormat(N,pe);z=Ke=>ie.format(Ke)}else{const pe=new Intl.DateTimeFormat(N,{dateStyle:"medium",timeZone:q});z=ie=>pe.format(ie)}const de=j.relative?new Intl.RelativeTimeFormat(N,{numeric:"auto"}):null,Ce=(typeof j.relative=="object"&&j.relative?j.relative.threshold??7:7)*24*36e5,$e=(pe,ie)=>{const Ke=D(pe);if(!Ke)return H;if(de){const kt=ie&&typeof ie.now=="number"?ie.now:Date.now(),He=Ke.getTime()-kt;if(Math.abs(He)<Ce){for(const[g,d]of B)if(Math.abs(He)>=d||g==="second")return de.format(Math.round(He/d),g)}}return z(Ke)};return $e.spec=j,$e}function te(O){if(F(O)||O==="")return null;if(typeof O=="string"){const N=/^(\d{4}-\d{2}-\d{2})/.exec(O.trim());if(N)return N[1];const H=D(O);return H?te(H):null}const R=D(O);if(!R)return null;const j=N=>String(N).padStart(2,"0");return`${R.getFullYear()}-${j(R.getMonth()+1)}-${j(R.getDate())}`}function G(O,R){if(F(O)||O==="")return null;if(typeof O=="string"){const N=O.trim();if(ne.test(N)){const z=D(N);return z?$(z,R):null}const H=/^(\d{4}-\d{2}-\d{2})[T ](\d{2}):(\d{2})(?::(\d{2}))?/.exec(N);if(H){const[,z,de,qe,Ce]=H;return`${z}T${de}:${qe}${Ce&&Ce!=="00"?`:${Ce}`:""}`}if(/^\d{4}-\d{2}-\d{2}$/.test(N))return`${N}T00:00`;const q=D(N);return q?G(q):null}const j=D(O);return j?$(j,R):null}const ne=/(?:Z|[+-]\d{2}:?\d{2})$/i;function $(O,R){const j=z=>String(z).padStart(2,"0");if(R)try{const z=new Intl.DateTimeFormat("en-CA",{timeZone:R,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1}).formatToParts(O).reduce((Ce,$e)=>($e.type!=="literal"&&(Ce[$e.type]=$e.value),Ce),{}),de=z.hour==="24"?"00":z.hour,qe=Number(z.second);return`${z.year}-${z.month}-${z.day}T${de}:${z.minute}`+(qe?`:${z.second}`:"")}catch{}const N=`${O.getFullYear()}-${j(O.getMonth()+1)}-${j(O.getDate())}`,H=O.getSeconds(),q=`${j(O.getHours())}:${j(O.getMinutes())}${H?`:${j(H)}`:""}`;return`${N}T${q}`}function ee(O,R){const j=F(O)||O===""?null:String(O),N=F(R)||R===""?null:String(R);return j===null?N===null?0:1:N===null||j<N?-1:j>N?1:0}}),mt("packages/core/src/format/boolean.js",function(w,Te){"use strict";Object.defineProperty(w,"toTriState",{enumerable:!0,get:function(){return oe}}),Object.defineProperty(w,"compileBoolean",{enumerable:!0,get:function(){return Pe}});const F=Te("packages/core/src/internal/util.js").isNil,le={true:"☑",false:"☐",null:""},be={true:"◉",false:"◯",null:""};function oe(D){if(F(D)||D==="")return null;if(typeof D=="boolean")return D;if(typeof D=="number")return D!==0;const Y=String(D).trim().toLowerCase();return Y==="true"||Y==="yes"||Y==="y"||Y==="1"?!0:Y==="false"||Y==="no"||Y==="n"||Y==="0"?!1:null}function Pe(D,Y){const ae=D||{},W=ae.display||"text",B=ae.trueLabel??"Yes",J=ae.falseLabel??"No",te=ae.nullLabel??"";let G=B,ne=J;const $=te;W==="checkbox"?(G=le.true,ne=le.false):W==="switch"?(G=be.true,ne=be.false):W==="icon"&&(G=ae.trueIcon??B,ne=ae.falseIcon??J);const ee=O=>{const R=oe(O);return R===null?$:R?G:ne};return ee.display=W,ee.labels={true:B,false:J,null:te},ee.locale=Y,ee.spec=ae,ee}}),mt("packages/modules/data-router/index.js",function(w,Te){"use strict";Object.defineProperty(w,"createDataRouter",{enumerable:!0,get:function(){return Ke}}),Object.defineProperty(w,"default",{enumerable:!0,get:function(){return He}});const F=Te("packages/core/src/internal/util.js").warnOnce,le=Te("packages/core/src/source/pushdown.js"),be=le.planQuery,oe=le.capabilitiesOf,D=Te("packages/core/src/model/rowkey.js").compositeKey,ae=Te("packages/modules/data-router/devtools.js").mountRouterDevtools,W=Te("packages/core/src/format/date.js"),B=W.toIsoDate,J=W.scanPattern,G=Te("packages/core/src/format/boolean.js").toTriState;function ne(g,d){return typeof g=="function"?g:typeof g=="string"?f=>f[g]:d}function $(g,d){if(!g||typeof g!="object"||typeof d!="string")return;if(!d.includes("."))return g[d];let f=g;for(const b of d.split(".")){if(!f||typeof f!="object")return;f=f[b]}return f}function ee(g,d){const f=d.split(".");if(f.length===1){delete g[d];return}let b=g;for(let E=0;E<f.length-1;E+=1)if(b=b[f[E]],!b||typeof b!="object")return;delete b[f[f.length-1]]}function O(g){return Array.isArray(g)?"array":g===null?"null":typeof g}function R(g,d){if(g===void 0||typeof g=="string"&&g.length>0)return g;if(typeof g=="function")return f=>{const b=g(f);if(typeof b=="string"||typeof b=="number"&&Number.isFinite(b))return b;throw new Error(`lattice-data-router: rowKey function must return a string or number; got ${O(b)}.`)};throw new Error(`lattice-data-router: rowKey must be a property name or a function; composite keys are not supported on ${d}.`)}function j(g){if(typeof g=="function")return g;if(g&&typeof g=="object"&&typeof g.key=="string"){const d=g.dir==="desc"?-1:1,{key:f}=g;return(b,E)=>{const K=b?b[f]:void 0,V=E?E[f]:void 0;return K<V?-1*d:K>V?1*d:0}}return null}function N(g){if(!g||typeof g!="object")return null;let d=0;Number.isFinite(g.minInterval)&&g.minInterval>0?d=Number(g.minInterval):Number.isFinite(g.maxHz)&&g.maxHz>0&&(d=1e3/Number(g.maxHz));const f=Number.isFinite(g.sample)&&g.sample>1?Math.floor(Number(g.sample)):1,b=Number.isFinite(g.maxLag)&&g.maxLag>=0?Math.floor(Number(g.maxLag)):null;return d===0&&f===1&&b===null?null:{minInterval:d,sample:f,maxLag:b}}let H=0;function q(){return H+=1,`r${H}`}function z(g){const f=(Array.isArray(g)?g:[g]).map(b=>({name:typeof b=="string"?b:null,get:ne(b,()=>{})}));return b=>{const E={},K=[];for(const V of f){const ze=V.get(b);K.push(ze),V.name&&(E[V.name]=ze)}return{key:D(K),fields:E}}}function de(g,d){if(typeof g=="function")return g(d);if(g&&typeof g=="object"){const{op:f,field:b}=g;if(f==="count")return d.length;const E=b!=null?d.map(K=>Number(K[b])).filter(K=>Number.isFinite(K)):[];if(f==="sum")return E.reduce((K,V)=>K+V,0);if(f==="avg")return E.length?E.reduce((K,V)=>K+V,0)/E.length:0;if(f==="min")return E.length?Math.min(...E):void 0;if(f==="max")return E.length?Math.max(...E):void 0}}function qe(g){return g&&typeof g=="object"&&typeof g.from=="string"&&typeof g.to=="string"?{from:g.to,to:g.from}:(F("data-router:mutual-fn","relate({ mutual: true }) with a function relation cannot be inverted; the same predicate is applied in both directions. Use a { from, to } key map for a mutual edge."),g)}function Ce(g,d){return g?d?{op:"and",conditions:[g,d]}:g:d||null}const $e=Object.freeze(["eq","ne","lt","lte","gt","gte","between","notBetween","in","notIn","contains","notContains","startsWith","endsWith","blank","notBlank"]);function pe(g,d){const f=d?d[g.col]:void 0,b=g.value,E=K=>g.caseSensitive?String(K):String(K).toLowerCase();switch(g.op){case"eq":return f===b;case"ne":return f!==b;case"lt":return f<b;case"lte":return f<=b;case"gt":return f>b;case"gte":return f>=b;case"between":return Array.isArray(b)&&f>=b[0]&&f<=b[1];case"notBetween":return!(Array.isArray(b)&&f>=b[0]&&f<=b[1]);case"in":return Array.isArray(b)&&b.includes(f);case"notIn":return!(Array.isArray(b)&&b.includes(f));case"contains":return f!=null&&E(f).includes(E(b));case"notContains":return f==null||!E(f).includes(E(b));case"startsWith":return f!=null&&E(f).startsWith(E(b));case"endsWith":return f!=null&&E(f).endsWith(E(b));case"blank":return f==null||f==="";case"notBlank":return!(f==null||f==="");default:throw new Error(`[lattice] query() cannot evaluate the residual filter operator "${String(g.op)}" on column "${String(g.col)}" client-side, so the query is refused rather than returning rows the filter excludes. Push it down to an adapter that implements it, or use an operator this router evaluates: ${$e.join(", ")}.`)}}function ie(g,d){return g?Array.isArray(g.conditions)?g.op==="or"?g.conditions.some(f=>ie(f,d)):g.op==="not"?!g.conditions.every(f=>ie(f,d)):g.conditions.every(f=>ie(f,d)):pe(g,d):!0}function Ke(g={}){const d=ne(g.key,()=>{}),f=ne(R(g.rowKey,"routes"),e=>e.rowKey),b=typeof g.key=="string"?g.key:null,E=!!g.overlap,K=typeof g.onUnrouted=="function"?g.onUnrouted:null,V=Number.isFinite(g.selectionDebounce)?Number(g.selectionDebounce):16,ze=typeof g.onWrite=="function"?g.onWrite:null,ut=typeof g.onConflict=="function"?g.onConflict:null,De=g.seq!=null?ne(g.seq,()=>{}):null,nt=De?g.dedupe!==!1:!1,a=f;let y=null;typeof g.batch=="number"?y=g.batch:g.batch&&Number.isFinite(g.batch.intervalMs)&&(y=Number(g.batch.intervalMs));const I=y!==null||!!g.coalesce,_=new Map;let P,X=0;const Q=[];let l=null;const u=g.time!=null?ne(g.time,()=>{}):null,k=typeof g.now=="function"?g.now:Date.now,M=1e4;let Re=!1,se=null,ke=null,ve="time",Ve=new Map;const Ne=[];let _e=0,Me,yt,bt=!1,dt=null,Ft=[],xt=0,pt=0,mn="time",Pt=!1,ct=null,vt=null;const $t=e=>{if(e&&Number.isFinite(e.seq))return e.seq;if(De&&e&&e.row){const n=De(e.row);return Number.isFinite(n)?n:void 0}},yn=e=>{if(e&&Number.isFinite(e.t))return e.t;if(u&&e&&e.row){const n=u(e.row);if(Number.isFinite(n))return n}return k()},Xe=[];let Ye=null;const rt=[],Ue=[],Rt=new Map,Dt=new Set;let wt=null,ot=0;const Tt=new Map,It=new Set,ce=typeof g.rowKey=="string"?g.rowKey:"rowKey",Se=new Map;let Ut=0;const Xt=new Set,x=[],C=new Map,U=(e,n)=>{C.set(e,(C.get(e)||0)+n)};let re=0;const T=new Map,we=new Map;let fe=null;const We=Number.isFinite(g.metricsInterval)?Number(g.metricsInterval):1e3;let Fe=0,ue=null,et="lattice-router",ft=250,Ee=null,Ge=null,me=!1,xe=!1,je=null,Be=!1,ht=null;const Le=[],Oe=()=>Ye?[...Xe,Ye]:Xe,St=e=>Oe().find(n=>n.grid===e)||null,Et=e=>{const n=[];for(const t of Xe)if(t.match(e)&&(n.push(t),!E))break;return n.length?n:Ye?[Ye]:[]},bn=e=>e.hasPartValue?e.partValue:e.label!=null?e.label:e.grid,Z=e=>{for(const n of Oe())if(n.grid===e)return n;for(const n of Oe())if(n.hasPartValue&&n.partValue===e||n.label!=null&&n.label===e)return n;return null},Qe=(e,n)=>{if(n.add.length||n.update.length||n.remove.length){const t=e.sink(n);it(e,t)}return{added:n.add.length,updated:n.update.length,removed:n.remove.length}},it=(e,n)=>{const t=n?.rejected;if(!Array.isArray(t)||!t.length)return;const r=t.filter(i=>i&&i.operation==="remove");if(!r.length)return;const o=e.label||`route ${e.routeId}`;F(`data-router:remove-rejected:${e.routeId}`,`route "${o}" asked its target to remove ${r.length} row(s) the target does not have (for example ${JSON.stringify(String(r[0].id))}). The rows are still on screen. This is a key mismatch: the key the route derives for a row is not the key the grid derives for it. Check that the route's \`rowKey\` names the same value as the grid's.`)},wn=(e,n)=>{for(const t of rt)if(t.to===e.grid&&t.predicate&&!t.predicate(n))return!1;if(e.graphPreds){for(const t of e.graphPreds)if(!t(n))return!1}return!0},jt=e=>{const n=qt(),t=[];for(const h of e.partition.values()){if(e.filter&&!e.filter(h)){if(he){const m=String(h[ce]);at(m,{kind:"filter",passed:!1}),st(m,"filter-rejected","the route's filter rejected this row.")}continue}if(!wn(e,h)){if(he){const m=String(h[ce]);at(m,{kind:"filter",passed:!1}),st(m,"filter-rejected","a cross-grid link/graph predicate rejected this row.")}continue}he&&at(String(h[ce]),{kind:"filter",passed:!0}),t.push(h)}if(e.explain.filterIn=e.partition.size,e.explain.filterOut=t.length,Xt.size){const h=new Map;for(const L of t)for(const S of Object.keys(L))Xt.has(S)&&L[S]!==void 0&&!h.has(S)&&h.set(S,!0);const m=e.spreadFields||(e.spreadFields=new Map),v=[],A=[];for(const L of h.keys())m.has(L)||v.push(L);for(const L of m.keys())h.has(L)||A.push(L);v.length||A.length?(e.spreadFields=h,cr("fields:changed",{route:bn(e),added:v,removed:A})):e.spreadFields=h}let r;const o=he&&!e.rollup?new Map:null;if(e.rollup){const h=new Map;for(const v of t){const{key:A,fields:L}=e.rollup.group(v);let S=h.get(A);S||(S={key:A,fields:L,rows:[]},h.set(A,S)),S.rows.push(v)}if(he)for(const v of h.values())for(const A of v.rows)at(String(A[ce]),{kind:"rollup",groupKey:v.key,memberCount:v.rows.length});let m=[];for(const v of h.values()){const A={...v.fields};for(const[L,S]of e.rollup.specs)A[L]=de(S,v.rows);m.push({gkey:v.key,row:A})}e.explain.rollupIn=t.length,e.explain.rollupGroups=h.size,e.explain.rollupOut=m.length,e.sort&&(e.explain.sortCount=m.length,m.sort((v,A)=>e.sort(v.row,A.row))),e.explain.transformIn=m.length,e.transform&&(m=m.map(v=>({gkey:v.gkey,row:e.transform(v.row)}))),e.explain.transformOut=m.length,r=new Map(m.map(v=>[v.gkey,v.row]))}else{let h=t;if(e.sort&&(e.explain.sortCount=h.length,h=h.slice().sort(e.sort),he))for(const m of h)at(String(m[ce]),{kind:"sort",passed:!0});e.explain.transformIn=h.length,e.explain.transformOut=h.length,r=new Map;for(const m of h){const v=D([e.keyOf(m)]);he&&(e.transform&&at(String(m[ce]),{kind:"transform",passed:!0}),o.set(v,String(m[ce]))),r.set(v,e.transform?e.transform(m):m)}}const i=[],s=[],c=[];for(const[h,m]of r)e.keys.has(h)?kt(e.keys.get(h),m)||(s.push(m),he&&o&&gr(o.get(h),e,"update")):(i.push(m),he&&o&&gr(o.get(h),e,"add"));for(const h of e.keys.keys())r.has(h)||c.push(h);e.keys=r;const p=Qe(e,{add:i,update:s,remove:c});return e.explain.writeAdd=p.added,e.explain.writeUpdate=p.updated,e.explain.writeRemove=p.removed,e.explain.timingMs+=qt()-n,p},en=e=>{e.bpTimer&&(clearTimeout(e.bpTimer),e.bpTimer=null),jt(e),e.bpPending=0,e.bpLastFlush=k()},br=(e,n)=>{if(e.bpTimer)return;const t=e.bp.minInterval>0?Math.max(e.bp.minInterval-(n-e.bpLastFlush),0):0;e.bpTimer=setTimeout(()=>{e.bpTimer=null,At();try{en(e)}finally{Nt()}},t),e.bpTimer&&typeof e.bpTimer.unref=="function"&&e.bpTimer.unref()},wr=(e,n,t)=>{if(!e.bp){jt(e);return}e.bpPending+=n,e.bpCoalesced+=n;const r=e.bp;if(r.maxLag!=null&&e.bpPending<=r.maxLag&&!e.bpTimer){en(e);return}const o=k(),i=o-e.bpLastFlush>=r.minInterval,s=e.bpPending>=r.sample;if(i&&s){en(e);return}if(he&&t)for(const c of t)st(String(c[ce]),"not-yet-flushed","this route is backpressured; the write is deferred to a trailing flush.");br(e,o)},kr=e=>{e.bpTimer&&(clearTimeout(e.bpTimer),e.bpTimer=null),e.bpPending=0,e.bpLastFlush=k()},kn=(e,n)=>{if(typeof e=="function"){const t=e(n);return typeof t=="function"?t:null}if(e&&typeof e=="object"){const t=e.from,r=e.to,o=new Set(n.map(i=>i&&i[t]));return i=>o.has(i&&i[r])}return null},vn=e=>{const n=St(e),t=e&&e.selection,r=t&&typeof t.keys=="function"?t.keys():[];return!r.length||!n?[]:r.map(o=>n.partition.get(String(o))).filter(o=>o!==void 0)},vr=e=>{const n=e&&e.selection;if(!n||typeof n.predicate!="function")return null;const t=n.predicate();if(!t||t.all!==!0)return null;const r=typeof n.count=="function"?n.count():Promise.resolve(null);return{predicate:t,count:r}},Ht=e=>{const n=vr(e.from);if(n){if(typeof e.relation=="function"&&e.relation.length>=2){const r=e.relation(vn(e.from),n);e.predicate=typeof r=="function"?r:null}else F("data-router:link-predicate-unsupported","link()/relate() source grid has every row matching a filter selected on a source that holds only the rows it has loaded. The relation does not declare it accepts a predicate selection — a function taking (selected, { predicate, count }) as its second parameter — so the link cannot build a target-row predicate from a truncated key list and imposes no constraint."),e.predicate=null;return}const t=vn(e.from);e.predicate=t.length?kn(e.relation,t):null},Gt=()=>{const e=new Set;for(const n of Ue)e.add(n.from),e.add(n.to);return e},Mt=()=>{for(const i of Oe())i.graphPreds=null;if(!Ue.length)return;const e=Gt(),n=new Map;for(const i of e){const s=vn(i);s.length&&n.set(i,s)}const t=new Map(n);let r=!0,o=(e.size+1)*2;for(;r&&o-- >0;){r=!1;for(const i of e){if(n.has(i))continue;const s=Ue.filter(v=>v.to===i&&t.has(v.from));if(!s.length)continue;const c=St(i);if(!c)continue;const p=s.map(v=>kn(v.rel,t.get(v.from))).filter(Boolean),h=[];for(const v of c.partition.values())p.every(A=>A(v))&&h.push(v);const m=t.get(i);if(!m||m.length!==h.length)t.set(i,h),r=!0;else{const v=new Set(m);h.some(A=>!v.has(A))&&(t.set(i,h),r=!0)}}}for(const i of Ue){if(!t.has(i.from))continue;const s=kn(i.rel,t.get(i.from));if(!s)continue;const c=St(i.to);c&&(c.graphPreds||(c.graphPreds=[])).push(s)}},zn=e=>{const n=Rt.get(e);if(n){n.count+=1;return}const t=e&&typeof e.on=="function"?e.on("selection:changed",()=>Sr(e)):()=>{};Rt.set(e,{off:t,count:1})},Sn=()=>{wt&&(clearTimeout(wt),wt=null);const e=Dt;if(!e.size)return;const n=new Set;for(const t of rt)e.has(t.from)&&(Ht(t),n.add(t.to));if(Dt.clear(),Ue.length){Mt();for(const t of Gt())n.add(t)}for(const t of n){const r=St(t);r&&jt(r)}},Sr=e=>{if(Dt.add(e),V<=0){Sn();return}wt||(wt=setTimeout(Sn,V))},Un=e=>{const n=Rt.get(e);n&&(n.count-=1,n.count<=0&&(n.off(),Rt.delete(e)))},Er=e=>typeof e=="function"?n=>e(n):e&&e.rows&&typeof e.rows.apply=="function"?n=>e.rows.apply(n):(F("data-router:bad-target","attach/subscribe target has no rows.apply and is not a function; its slice goes nowhere. Pass a grid or a handler(change) function."),()=>{}),En=(e,n,t)=>({grid:e,routeId:q(),sink:Er(e),match:n,keyOf:ne(R(t.rowKey,"routes"),f),partition:new Map,keys:new Map,transform:typeof t.transform=="function"?t.transform:null,filter:typeof t.filter=="function"?t.filter:null,sort:j(t.sort),rollup:t.rollup&&t.rollup.groupBy!=null?{group:z(t.rollup.groupBy),specs:Object.entries(t.rollup.aggregate||{})}:null,where:t.where&&typeof t.where=="object"?t.where:null,graphPreds:null,onWrite:typeof t.onWrite=="function"?t.onWrite:null,onConflict:typeof t.onConflict=="function"?t.onConflict:null,writable:t.writable===!0,readonly:!!(t.rollup&&t.rollup.groupBy!=null||typeof t.transform=="function"),label:typeof t.label=="string"?t.label:null,metricRows:0,bp:N(t.backpressure),bpPending:0,bpTimer:null,bpLastFlush:-1/0,bpCoalesced:0,explain:hr()}),Gn=e=>{if(!E){for(const n of Xe)if(n.hasPartValue&&n.partValue===e){F(`data-router:overlap:${String(e)}`,`Data Router: value ${JSON.stringify(e)} already routes to another viewer; with overlap:false only the first receives rows. Pass createDataRouter({ overlap: true }) to fan one value to several viewers.`);return}}},Vn=(e,n)=>`${String(e)}${String(n)}`,jr=e=>{const n=e&&e.row;if(!n)return null;const t=n.data&&typeof n.data=="object"?n.data:n;return t?{...t}:null},tn=(e,n)=>{const t=e.grid;if(!t||!t.edit||typeof t.edit.setCells!="function")return;const r=Vn(n.key,n.colId);It.add(r);try{t.edit.setCells([{key:n.key,colId:n.colId,value:n.before}],"cell")}finally{It.delete(r)}U("writeReverted",1)},_n=e=>{e&&tt.apply([{op:"upsert",row:e}])},Jn=(e,n,t)=>{const r=t&&typeof t=="object"?t:null,o=r&&r.conflict!==void 0?r.conflict:null;if(o){const i=e.onConflict||ut;if(i)try{i(n,{serverRow:o})}catch{}U("writeConflicted",1),_n(r&&r.row?r.row:n.row);return}if(t===!1||r&&r.ok===!1){U("writeRejected",1),tn(e,n);return}U("writeAccepted",1),_n(r&&r.row?r.row:n.row)},Or=e=>{const n=String(e);for(const t of Se.values())if(t.live.has(n))return t.handle;return null},Pr=(e,n)=>{if(!n||n.key===void 0||n.colId===void 0||It.has(Vn(n.key,n.colId)))return;const t=jr(n),r={key:String(n.key),colId:String(n.colId),value:n.value,before:n.oldValue,row:t};if(U("writeRouted",1),e.readonly){F("data-router:readonly-write","an edit on a derived (rollup/transform) route is read-only and was reverted; a derived row cannot be inverted to a source row. Make the source route writable instead."),tn(e,r);return}const o=e.onWrite||ze;if(!o){F("data-router:no-onwrite","a route attached with { writable: true } has no onWrite handler (per-route or router-global); the edit was left in place but not persisted. Pass onWrite to route the write.");return}let i;try{i=o(r,{route:e.grid,source:Or(r.key)})}catch{tn(e,r),U("writeRejected",1);return}i&&typeof i.then=="function"?i.then(s=>Jn(e,r,s),()=>{tn(e,r),U("writeRejected",1)}):Jn(e,r,i)},Rr=e=>{const n=e.grid;if(!n||typeof n.on!="function"||!n.edit||typeof n.edit.setCells!="function"){F("data-router:writable-target","attach({ writable: true }) needs a grid exposing grid.on and grid.edit.setCells; write-back is off for this route.");return}if(Tt.has(n))return;const t=n.on("cell:changed",r=>Pr(e,r));Tt.set(n,typeof t=="function"?t:()=>{})},Tr=e=>{const n=[];for(const t of e.partition.values())e.filter&&!e.filter(t)||n.push(t);return e.explain&&(e.explain.filterIn=e.partition.size,e.explain.filterOut=n.length),n},nn=e=>{const n=Tr(e);if(e.kind==="monitor"){let r;try{r=e.evaluate(n)}catch{r=void 0}e.handler(r,n);return}let t;try{t=e.condition(n)}catch{t=!1}if(t){if(!e.armed)return;e.debounceMs>0?(e.pending={signal:t,rows:n},e.timer||(e.timer=setTimeout(()=>{e.timer=null;const r=e.pending;e.pending=null,r&&(e.armed=!1,e.handler(r.signal,r.rows))},e.debounceMs))):(e.armed=!1,e.handler(t,n))}else e.armed=!0,e.timer&&(clearTimeout(e.timer),e.timer=null),e.pending=null},jn=(e,n)=>{e.partition=new Map;for(const t of n)e.match(t)&&e.partition.set(String(e.keyOf(t)),t);e.explain&&(e.explain.whenRouted=e.partition.size)},Ar=(e,n)=>{for(const t of n){const r=t&&t.row;if(!r)continue;const o=String(e.keyOf(r));if(t.op==="delete"){e.partition.delete(o);continue}e.match(r)?(e.partition.set(o,r),e.explain&&(e.explain.whenRouted+=1)):e.partition.delete(o)}},Vt=()=>{const e=new Map;for(const n of Oe())for(const t of n.partition.values())e.set(String(a(t)),t);return[...e.values()]},Yn=()=>{Ve=new Map;for(const e of Oe())for(const n of e.partition.values())Ve.set(String(a(n)),n);Ne.length=0,_e=0,Me=P,yt=void 0},Qn=()=>{const e=Ne.shift();e&&(e.op==="del"?Ve.delete(e.key):Ve.set(e.key,e.row),Me=e.seq,yt=e.t)},Nr=()=>{if(se!=null)for(;Ne.length>se;)Qn();if(ke!=null&&Ne.length){const e=Ne[Ne.length-1].t;for(;Ne.length>1&&e-Ne[0].t>ke;)Qn()}},Fr=e=>{!e||!e.row||Ne.push({pos:_e++,seq:$t(e),t:yn(e),op:e.op==="delete"?"del":"set",key:String(a(e.row)),row:e.row})},On=(e,n)=>n==="seq"?e.seq:e.t,rn=(e,n)=>{const t=new Map(Ve);for(const r of Ne){const o=On(r,n);if(e!==void 0&&o!==void 0&&o>e)break;r.op==="del"?t.delete(r.key):t.set(r.key,r.row)}return t},on=e=>{const n=new Map(Oe().map(t=>[t,[]]));for(const t of e)for(const r of Et(t))n.get(r).push(t);for(const t of Oe())t.partition=new Map(n.get(t).map(r=>[String(t.keyOf(r)),r]));for(const t of rt)Ht(t);Mt();for(const t of Oe())jt(t)},Pn=e=>Re?!0:(F("data-router:no-buffer",`${e}() needs a buffered window; call router.buffer({ window, max }) first to record one.`),!1),sn=()=>{if(ct&&(clearTimeout(ct),ct=null),Pt=!1,Ft=[],xt=0,vt){const e=vt;vt=null,e()}},xr=()=>{if(Ft=[],xt=0,vt){const e=vt;vt=null,e()}},$r=()=>{ct=null;const e=Ft[xt++];e.op==="del"?dt.delete(e.key):dt.set(e.key,e.row),on([...dt.values()]),Fe=e.pos+1,Rn()};function Rn(){if(!Pt){if(xt>=Ft.length){xr();return}ct=setTimeout($r,pt)}}function ln(e){if(je)try{je.postMessage(e)}catch{}}function Zn(){return{t:"snapshot",rows:Vt(),seq:P,checkpoint:Object.fromEntries(_)}}function Dr(e){const n=e&&e.data;if(!(!n||typeof n!="object")){if(n.t==="hello"){Vt().length&&ln(Zn());return}Be=!0;try{n.t==="delta"?tt.apply(n.deltas||[]):n.t==="snapshot"&&(tt.load(n.rows||[]),n.checkpoint&&tt.seenThrough(n.checkpoint))}finally{Be=!1}}}function Ir(e,n){e.partition=new Map(n.map(t=>[String(e.keyOf(t)),t]))}function Mr(e,n){const t=n.filter(o=>!o.isDefault),r=n.find(o=>o.isDefault)||null;for(const o of n)o.partition=new Map;for(const o of e){const i=[];for(const c of t)if(c.match(o)&&(i.push(c),!E))break;const s=i.length?i:r?[r]:[];if(!s.length){ot+=1,K&&K(o);continue}for(const c of s)c.partition.set(String(c.keyOf(o)),o)}}const Lr=(e,n)=>{if(typeof n=="function")return r=>n(r);let t=null;return n===!0?t=String(e):typeof n=="string"&&(t=n),t==null?null:(r,o=ce)=>`${t}:${r[o]}`},Xn=(e,n)=>{const t={...e.map?e.map(n):n},r=he&&e.fields?[]:null;if(e.fields&&Gr(e,t,r),e.ns){const o=Cr(e,t),i=e.ns(t,o||ce);o&&(t[o]=i),t[ce]=i}if(he){const o=n?.[ce],i=String(t[ce]),s=Qt(e.id,o,i);r&&r.length&&s.steps.push({kind:"fields",changes:r}),s.lastRow=t,t[ce]==null&&st(i,"coerced-invalid-key",`source "${e.id}": the row's key resolved to ${String(t[ce])}, so it cannot be routed.`)}return t},Cr=(e,n)=>{if(typeof g.rowKey!="function")return null;if(e.keyProp!==void 0)return e.keyProp;const t=new Set;try{g.rowKey(new Proxy(n,{get(r,o,i){return typeof o=="string"&&t.add(o),Reflect.get(r,o,i)}}))}catch{}return e.keyProp=t.size===1?[...t][0]:null,e.keyProp===null&&F(`data-router:function-key-namespace:${e.id}`,`addSource("${e.id}") sets \`key\` but the rowKey function does not read exactly one row property, so its ids cannot be namespaced and rows from different feeds sharing an id will replace one another. Use a property-name rowKey, or give each feed ids that are already distinct.`),e.keyProp},er=(e,n)=>{const t=[];for(const r of n||[]){if(!r||!r.row)continue;const o=Xn(e,r.row),i=String(o[ce]);r.op==="delete"?(e.live.delete(i),e.explain.rowsRemoved+=1):(e.live.set(i,o),e.explain.rowsApplied+=1),t.push({...r,row:o})}return e.ingested+=t.length,U(`source:${e.id}`,t.length),t},tr=e=>({get id(){return e.id},get size(){return e.live.size},load(n){At();try{const t=(n||[]).map(i=>Xn(e,i)),r=new Map(t.map(i=>[String(i[ce]),i])),o=[];for(const[i,s]of e.live)r.has(i)||o.push({op:"delete",row:s});for(const i of t)o.push({op:"upsert",row:i});return e.live=r,e.ingested+=t.length,U(`source:${e.id}`,t.length),e.explain.rowsLoaded+=t.length,e.explain.rowsRemoved+=o.length-t.length,_t(e,o,i=>tt.apply(i)),this}finally{Nt()}},apply(n){At();try{return _t(e,er(e,n),t=>tt.apply(t)),this}finally{Nt()}},push(n){At();try{return _t(e,er(e,Array.isArray(n)?n:[n]),t=>tt.push(t)),this}finally{Nt()}},remove(){At();try{const n=[];for(const t of e.live.values())n.push({op:"delete",row:t});return e.explain.rowsRemoved+=n.length,e.live.clear(),Se.delete(e.id),n.length&&tt.apply(n),tt}finally{Nt()}}}),an=new Set(["text","number","integer","boolean","date","json"]),nr=(e,n=".")=>{if(typeof e=="number")return Number.isFinite(e)?e:null;if(typeof e!="string")return null;let t=e.trim();if(t===""||/\d\s*[*/^]\s*[\d.(]/.test(t)||(t=t.replace(/[\s\u00a0\u202f\u2009']/g,""),n===","?t=t.split(".").join("").replace(",","."):t=t.split(",").join(""),t=t.replace(/[^0-9eE+\-.]/g,""),t===""||t==="-"||t==="+"||t==="."||t==="-."||t==="+."))return null;const r=Number(t);return Number.isFinite(r)?r:null},Wr=e=>{if(typeof e=="string")return JSON.stringify(e);if(typeof e=="number"||typeof e=="boolean"||e==null)return String(e);try{return JSON.stringify(e)}catch{return String(e)}},Br=(e,n,t)=>{F(`router:coerce-failed:${e.id}:${n.name}`,`source "${e.id}" field "${n.name}": could not coerce ${Wr(t)} to ${n.type}; the value is stored as null.`)},Kr=(e,n)=>{if(typeof n=="string")return an.has(n)?{name:e,type:n,format:null,decimal:null,trueSet:null,falseSet:null,nulls:null}:(F("data-router:field-type",`addSource field "${e}" names an unknown type "${n}" (expected ${[...an].join(", ")}); the field passes through uncoerced.`),null);if(n&&typeof n=="object"&&!Array.isArray(n)){const t=n.type==null?null:String(n.type);return t!=null&&!an.has(t)?(F("data-router:field-type",`addSource field "${e}" names an unknown type "${t}" (expected ${[...an].join(", ")}); the field passes through uncoerced.`),null):{name:e,type:t,format:typeof n.format=="string"?n.format:null,decimal:n.decimal===","||n.decimal==="."?n.decimal:null,trueSet:Array.isArray(n.true)&&n.true.length?new Set(n.true.map(String)):null,falseSet:Array.isArray(n.false)&&n.false.length?new Set(n.false.map(String)):null,nulls:Array.isArray(n.nulls)&&n.nulls.length?new Set(n.nulls.map(String)):null}}return F("data-router:field-spec",`addSource field "${e}" has an unusable fields declaration (a type string or an options object); the field passes through uncoerced.`),null},Hr=e=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const n=[];for(const[t,r]of Object.entries(e)){const o=Kr(t,r);o&&n.push(o)}return n.length?n:null},qr=(e,n)=>{if(e==null)return null;const t=String(e).trim();if(t==="")return null;const r={yyyy:"(\\d{4})",yy:"(\\d{2})",MM:"(\\d{1,2})",M:"(\\d{1,2})",dd:"(\\d{1,2})",d:"(\\d{1,2})",HH:"(\\d{1,2})",mm:"(\\d{1,2})",ss:"(\\d{1,2})"},o=m=>m.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");let i="^";const s=[];for(const m of J(n))if(m.token&&r[m.token])i+=r[m.token],s.push(m.token);else{if(m.token)return null;i+=o(m.text)}i+="$";const c=new RegExp(i).exec(t);if(!c)return null;const p={year:0,month:1,day:1,hour:0,minute:0,second:0};for(let m=0;m<s.length;m+=1){const v=Number(c[m+1]);if(Number.isNaN(v))return null;const A=s[m];A==="yyyy"?p.year=v:A==="yy"?p.year=2e3+v:A==="MM"||A==="M"?p.month=v:A==="dd"||A==="d"?p.day=v:A==="HH"?p.hour=v:A==="mm"?p.minute=v:A==="ss"&&(p.second=v)}const h=new Date(p.year,p.month-1,p.day,p.hour,p.minute,p.second);return Number.isNaN(h.getTime())?null:B(h)},zr=(e,n)=>{switch(e.type){case"text":return{ok:!0,value:typeof n=="string"?n:String(n)};case"number":{const t=nr(n,e.decimal===","?",":".");return t==null?{ok:!1}:{ok:!0,value:t}}case"integer":{const t=nr(n,e.decimal===","?",":".");return t==null||!Number.isInteger(t)?{ok:!1}:{ok:!0,value:t}}case"boolean":{if(typeof n=="boolean")return{ok:!0,value:n};if(e.trueSet||e.falseSet){const r=String(n);return e.trueSet&&e.trueSet.has(r)?{ok:!0,value:!0}:e.falseSet&&e.falseSet.has(r)?{ok:!0,value:!1}:{ok:!1}}const t=G(n);return t==null?{ok:!1}:{ok:!0,value:t}}case"date":{const t=e.format||"iso";if(t==="epoch-s"){const o=Number(n),i=o*1e3;if(!Number.isFinite(o)||!Number.isFinite(i))return{ok:!1};const s=B(new Date(i));return s==null?{ok:!1}:{ok:!0,value:s}}if(t==="epoch-ms"){const o=Number(n);if(!Number.isFinite(o))return{ok:!1};const i=B(new Date(o));return i==null?{ok:!1}:{ok:!0,value:i}}if(t==="iso"){const o=B(n);return o==null?{ok:!1}:{ok:!0,value:o}}const r=qr(n,t);return r==null?{ok:!1}:{ok:!0,value:r}}case"json":{if(typeof n!="string")return{ok:!0,value:n};try{return{ok:!0,value:JSON.parse(n)}}catch{return{ok:!1}}}default:return{ok:!0,value:n}}},Ur=(e,n,t,r)=>{const o=t[n.name],i=o;let s;if(i==null||typeof i=="number"&&Number.isNaN(i))s=null;else if(n.nulls&&n.nulls.has(String(i)))s=null;else if(n.type==null)s=i;else if(n.type!=="text"&&typeof i=="string"&&i.trim()==="")s=null;else{const c=zr(n,i),p=e.explain.fields.get(n.name);c.ok?(p&&(p.coerced+=1),s=c.value):(Br(e,n,i),p&&(p.invalid+=1,Yt(p.samples,i)),s=null)}t[n.name]=s,r&&r.push({field:n.name,before:o,after:s})},Gr=(e,n,t)=>{for(const r of e.fields)Ur(e,r,n,t)},Lt=e=>e==null?null:String(e),Tn=(e,n)=>{if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t+=1)if(!Tn(e[t],n[t]))return!1;return!0}if(e&&n&&typeof e=="object"&&typeof n=="object"){const t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(const o of t)if(!Tn(e[o],n[o]))return!1;return!0}return!1},An=(e,n)=>{if(e===n)return!0;if(!e||!n)return!1;const t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(const o of t)if(!Tn(e[o],n[o]))return!1;return!0},Vr=Object.freeze(["count","sum","avg","min","max","distinctCount","first","last"]),_r=Object.freeze(["sum","avg","min","max","distinctCount","first","last"]),Jr=e=>{if(!e||typeof e!="object"||Array.isArray(e))return null;const n=[];for(const[t,r]of Object.entries(e)){if(!r||typeof r!="object"||typeof r.fn!="string"){F("data-router:join-aggregate-bad-spec",`join aggregate "${t}" is not a { fn, field? } reducer; the aggregate is skipped.`);continue}if(!Vr.includes(r.fn)){F("data-router:join-aggregate-bad-fn",`join aggregate "${t}" uses fn "${r.fn}", which is not count|sum|avg|min|max|distinctCount|first|last; the aggregate is skipped.`);continue}const o=typeof r.field=="string"&&r.field?r.field:null;if(_r.includes(r.fn)&&!o){F("data-router:join-aggregate-no-field",`join aggregate "${t}" (${r.fn}) needs a field; the aggregate is skipped.`);continue}const i=r.fn==="first"||r.fn==="last"?typeof r.orderBy=="string"&&r.orderBy?r.orderBy:o:null;n.push([t,{fn:r.fn,field:o,orderBy:i}])}return n.length?n:null},Nn=(e,n)=>{if(!(!e||typeof e!="object"))return n in e||F(`data-router:collect-select-field:${n}`,`a collect join's \`select\` names "${n}", which the collected rows do not have; it is collected as undefined.`),e[n]},Yr=(e,n)=>{if(!e||typeof e!="object")return null;const t=e.from!=null?String(e.from):null;if(!t)return F("data-router:join-no-from","join needs a `from` (the lookup source id); ignoring the join."),null;const r=e.many===!0||e.spread!=null;let o=e.localKey!=null?e.localKey:e.on;o==null&&r&&(o=ce);let i;if(typeof o=="function")i=o;else if(typeof o=="string")i=L=>L[o];else return F("data-router:join-no-localkey","join needs a `localKey` (a field name or fn); ignoring the join."),null;const s=e.foreignKey!=null?e.foreignKey:e.fromKey;let c,p;if(typeof s=="function")c=s,p=s;else if(typeof s=="string")c=L=>L[s],p=s;else if(typeof o=="string")c=L=>L[o],p=o;else return F("data-router:join-no-foreignkey","join with a fn `localKey` needs an explicit string/fn `foreignKey`; ignoring the join."),null;if(r){if(e.spread!=null){const Ae=e.spread&&typeof e.spread=="object"?e.spread:{},Ie=Ae.name,Ze=Ae.value;let Zt,Wn;if(typeof Ie=="function")Zt=Ie;else if(typeof Ie=="string"&&Ie.length)Zt=Ot=>Ot[Ie];else return F("data-router:spread-no-name","a spread join needs a `name` (the attribute-name field or fn); ignoring the join."),null;if(typeof Ze=="function")Wn=Ze;else if(typeof Ze=="string"&&Ze.length)Wn=Ot=>Ot[Ze];else return F("data-router:spread-no-value","a spread join needs a `value` (the attribute-value field or fn); ignoring the join."),null;const vo=typeof Ae.prefix=="string"?Ae.prefix:"";let Bn=null;const hn=Ae.include;if(typeof hn=="function")Bn=hn;else if(Array.isArray(hn)){const Ot=new Set(hn.map(zt=>String(zt)));Bn=zt=>Ot.has(zt)}const mr=new Map;if(Ae.type&&typeof Ae.type=="object"&&!Array.isArray(Ae.type))for(const[Ot,zt]of Object.entries(Ae.type))io.includes(zt)&&mr.set(Ot,zt);return{many:!0,spread:!0,from:t,localKey:i,foreignKeyFn:c,ffKey:p,nameFn:Zt,valueFn:Wn,prefix:vo,includeFn:Bn,typeOf:Ot=>mr.get(Ot),keyIndex:new Map,lastFk:new Map,owner:n,probe:null,spreadPrev:new Map,ex:Ct()}}let L=e.missing;if(L!=="hold"&&L!=="passthrough"&&L!=="null"&&(L!=null&&F("data-router:join-bad-missing",`join.missing "${L}" is not hold|passthrough|null; using "passthrough".`),L="passthrough"),e.aggregate!=null){const Ae=Jr(e.aggregate);if(!Ae)return F("data-router:join-aggregate-invalid","a join aggregate must be a non-empty object of named reducers; ignoring the join."),null;const Ie=typeof e.where=="function"?e.where:null;return{many:!0,aggregate:Ae,whereFn:Ie,from:t,localKey:i,foreignKeyFn:c,ffKey:p,missing:L,keyIndex:new Map,lastFk:new Map,owner:n,probe:null,ex:Ct()}}if(typeof e.as!="string"||!e.as)return F("data-router:join-no-as","a collect join (many: true) needs an `as` (the field to put the collected array into); ignoring the join."),null;let S=null;const ge=e.select!=null?e.select:e.fields;typeof ge=="function"?S=ge:typeof ge=="string"&&ge?S=Ae=>Nn(Ae,ge):Array.isArray(ge)&&ge.length?S=Ae=>{const Ie={};for(const Ze of ge)Ie[String(Ze)]=Nn(Ae,String(Ze));return Ie}:ge&&typeof ge=="object"&&!Array.isArray(ge)&&Object.keys(ge).length&&(S=Ae=>{const Ie={};for(const[Ze,Zt]of Object.entries(ge))Ie[String(Zt)]=Nn(Ae,Ze);return Ie}),S||(S=Ae=>Ae);const lt=e.distinct===!0,Bt=e.sort===!0?!0:typeof e.sort=="function"?e.sort:!1,Kt=e.onParentDelete==="cascade"||e.onParentDelete==="orphan"?e.onParentDelete:"keep";return{many:!0,from:t,localKey:i,foreignKeyFn:c,ffKey:p,as:e.as,selectFn:S,distinct:lt,sort:Bt,missing:L,onParentDelete:Kt,keyIndex:new Map,lastFk:new Map,owner:n,probe:null,ex:Ct()}}let h=null;const m=[],v=e.fields!=null?e.fields:e.select;if(typeof v=="function")h=v;else if(Array.isArray(v))for(const L of v)m.push([String(L),String(L)]);else if(v&&typeof v=="object")for(const[L,S]of Object.entries(v))m.push([L,String(S)]);else F("data-router:join-no-fields","join has no `fields`/`select`; rows pass through unenriched.");let A=e.missing;return A!=="hold"&&A!=="passthrough"&&A!=="null"&&(A!=null&&F("data-router:join-bad-missing",`join.missing "${A}" is not hold|passthrough|null; using "passthrough".`),A="passthrough"),{many:!1,from:t,localKey:i,foreignKeyFn:c,ffKey:p,pairs:m,selectFn:h,missing:A,keyIndex:new Map,lastFk:new Map,owner:n,probe:null,ex:Ct()}},Qr=(e,n)=>{const t=new Set,r=[e];for(;r.length;){const o=r.pop();if(o===n)return!0;if(t.has(o))continue;t.add(o);const i=Se.get(o);if(i)for(const s of i.joins)r.push(s.from)}return!1},rr=(e,n)=>{if(e==null)return[];const t=[];for(const o of Array.isArray(e)?e:[e]){const i=Yr(o,n);i&&t.push(i)}const r=[];for(const o of t){if(o.from===n.id||Qr(o.from,n.id)){F("router:join-cycle",`join from "${n.id}" to "${o.from}" would close a join cycle; the join is refused.`);continue}r.push(o)}return r},Zr=(e,n)=>{const t=new Set;let r=Se.get(e);for(;r&&r.unnestParentId!=null&&!t.has(r.id);){if(t.add(r.id),r.unnestParentId===n)return!0;r=Se.get(r.unnestParentId)}return!1},Xr=(e,n)=>{if(!e||typeof e!="object")return null;const t=typeof e.path=="string"&&e.path?e.path:null;if(!t)return F("data-router:unnest-no-path","an unnest needs a `path` (the dotted array field on the row); ignoring the unnest."),null;const r=typeof e.as=="string"&&e.as?e.as:null;if(!r)return F("data-router:unnest-no-as","an unnest needs an `as` (the child row type); ignoring the unnest."),null;if(r===n.id||Zr(n.id,r))return F("router:unnest-cycle",`unnest "${n.id}" → "${r}" would close an unnest cycle; the unnest is refused.`),null;const o=typeof e.parentKey=="string"&&e.parentKey?e.parentKey:`${n.id}Id`,i=e.keep===!0;let s;if(typeof e.key=="function")s=e.key;else if(typeof e.key=="string"&&e.key){const h=e.key;s=m=>m[h]}else s=null;let c=Se.get(r);if(!c){c={id:r,map:null,fields:null,ns:null,live:new Map,out:new Map,ingested:0,joins:[],unnests:[],unnestParentId:n.id},c.handle=tr(c),Se.set(r,c),c.joins=rr(e.join,c),c.hasSpread=c.joins.some(h=>h.spread),c.unnests=or(e.unnest,c);for(const h of c.joins)Se.has(h.from)&&un(Se.get(h.from),h);for(const h of Se.values())if(h!==c)for(const m of h.joins)m.from===r&&m.probe==null&&un(c,m);c.explain=Dn(c),Jt.set(r,In(c))}const p=e.onParentDelete==="orphan"||e.onParentDelete==="keep"?e.onParentDelete:"cascade";return{path:t,as:r,keyFn:s,parentKeyField:o,keep:i,owner:n,child:c,onParentDelete:p,prevChildren:new Map}},or=(e,n)=>{if(e==null)return[];const t=[];for(const r of Array.isArray(e)?e:[e]){const o=Xr(r,n);o&&t.push(o)}return t},eo=(e,n)=>{const t=[];let r=0;const o=e.owner.explain.unnest.get(e.as);o&&(o.parentIn+=(n||[]).length);for(const i of n||[]){if(!i||!i.row)continue;const s=String(i.row[ce]),c=e.prevChildren.get(s)||new Map;if(i.op==="delete"){for(const[v,A]of c)if(e.onParentDelete==="orphan"){if(A.__orphan===!0)continue;const L={...A,__orphan:!0};e.child.live.set(v,L),t.push({op:"upsert",row:L}),r+=1}else e.onParentDelete==="keep"||(e.child.live.delete(v),t.push({op:"delete",row:A}),he&&st(v,"removed-by-cascade",`the parent row (key ${JSON.stringify(s)}) was deleted, cascading the delete to this unnested child.`,{parentKey:s}));e.prevChildren.delete(s);continue}const p=$(i.row,e.path),h=Array.isArray(p)?p:[],m=new Map;for(let v=0;v<h.length;v+=1){const A=h[v],L=e.keyFn?e.keyFn(A,i.row,v):null,S=L==null?`${s}:${v}`:String(L);m.has(S)&&F("router:unnest-duplicate-key",`the unnest "${e.as}" produced the child key "${S}" more than once for one parent; the later child (source order) wins.`);const ge={...A&&typeof A=="object"?A:{}};ge[e.parentKeyField]=i.row[ce],ge[ce]=S,b&&(ge[b]=e.as);const lt=e.child.live.get(S);lt&<.__orphan===!0&&(ge.__orphan=void 0),m.set(S,ge)}for(const[v,A]of c)m.has(v)||(e.child.live.delete(v),t.push({op:"delete",row:A}),he&&st(v,"removed-by-cascade",`the parent row (key ${JSON.stringify(s)}) no longer lists this child at "${e.path}".`,{parentKey:s}));for(const[v,A]of m){const L=c.get(v);if((L===void 0||!An(L,A))&&(e.child.live.set(v,A),t.push({op:"upsert",row:A}),he)){const S=Qt(e.as,v,v);S.lastRow=A,S.steps.push({kind:"unnest",parentKey:s})}}e.prevChildren.set(s,m)}return r>0&&F("router:orphaned-rows",`${r} child row(s) were orphaned when their parent was deleted; they are kept and marked __orphan: true (onParentDelete: 'orphan').`),o&&(o.childOut+=t.length),t},ir=(e,n,t)=>{const r={...n};if(e.selectFn){const o=e.selectFn(t,n);return o&&typeof o=="object"&&Object.assign(r,o),r}for(const[o,i]of e.pairs)r[i]=t?t[o]:null;return r},to=(e,n,t)=>{const r=Se.get(e.from),o=[];if(t!=null&&r&&e.probe){const c=e.probe.index.get(t);if(c)for(const p of c){const h=r.out?r.out.get(p):void 0;h!==void 0&&o.push(e.selectFn(h,n))}}const i=o.length>0;if(e.missing==="hold"&&o.length===0)return{hold:!0,matched:i};if(e.missing==="null"&&o.length===0)return{hold:!1,value:null,matched:i};let s=o;if(e.distinct){const c=new Map,p=[];for(const h of s){const m=typeof h=="object"&&h!==null?JSON.stringify(h):`${typeof h}:${String(h)}`;c.has(m)||(c.set(m,!0),p.push(h))}s=p}return e.sort&&(s=s.slice().sort(e.sort===!0?sr:e.sort)),{hold:!1,value:s,matched:i}},sr=(e,n)=>{if(e===n)return 0;if(e==null)return-1;if(n==null)return 1;if(typeof e=="number"&&typeof n=="number")return e-n;const t=String(e),r=String(n);return t<r?-1:t>r?1:0},no=(e,n)=>{const{fn:t,field:r,orderBy:o}=e;if(t==="count")return n.length;if(t==="first"||t==="last"){if(!n.length)return null;let s=n[0];for(let c=1;c<n.length;c+=1){const p=sr(n[c][o],s[o]);(t==="first"&&p<0||t==="last"&&p>0)&&(s=n[c])}return r?s[r]:s}if(t==="distinctCount"){if(!n.length)return null;const s=new Set;for(const c of n)s.add(c[r]);return s.size}const i=r?n.map(s=>Number(s[r])).filter(s=>Number.isFinite(s)):[];return t==="sum"?i.reduce((s,c)=>s+c,0):t==="avg"?i.length?i.reduce((s,c)=>s+c,0)/i.length:null:t==="min"?i.length?Math.min(...i):null:t==="max"&&i.length?Math.max(...i):null},ro=(e,n)=>e.map(([t,r])=>[t,no(r,n)]),oo=(e,n)=>{const t=Se.get(e.from),r=[];let o=!1;if(n!=null&&t&&e.probe){const i=e.probe.index.get(n);if(i)for(const s of i){const c=t.out?t.out.get(s):void 0;c!==void 0&&(o=!0,(!e.whereFn||e.whereFn(c))&&r.push(c))}}return e.missing==="hold"&&!o?{hold:!0,matched:o}:{hold:!1,values:ro(e.aggregate,r),matched:o}},io=Object.freeze(["number","date","boolean","text"]);function so(e,n){if(e==null)return e;if(n==="number"){if(typeof e=="number")return e;const t=Number(e);return Number.isFinite(t)?t:e}if(n==="date"){if(e instanceof Date)return e;const t=new Date(e);return Number.isNaN(t.getTime())?e:t}if(n==="boolean"){if(typeof e=="boolean")return e;if(typeof e=="string"){const t=e.trim().toLowerCase();if(t==="true"||t==="1"||t==="yes")return!0;if(t==="false"||t==="0"||t==="no"||t==="")return!1}return!!e}return n==="text"?String(e):e}const lo=(e,n)=>{const t=Se.get(e.from),r=new Map;if(n!=null&&t&&e.probe){const o=e.probe.index.get(n);if(o)for(const i of o){const s=t.out?t.out.get(i):void 0;if(s===void 0)continue;const c=e.nameFn(s);if(c==null)continue;const p=String(c);if(e.includeFn&&!e.includeFn(p,s))continue;const h=e.prefix+p;r.has(h)&&F("router:spread-duplicate",`a spread join wrote the field "${h}" more than once for one parent; the last attribute row (source order) wins.`),r.set(h,so(e.valueFn(s),e.typeOf?e.typeOf(p):void 0))}}return r},Fn=(e,n,t)=>{const r=e.lastFk.get(n);if(r!==void 0&&r!==t){const i=e.keyIndex.get(r);i&&(i.delete(n),i.size||e.keyIndex.delete(r))}if(t==null){e.lastFk.set(n,null);return}let o=e.keyIndex.get(t);o||(o=new Set,e.keyIndex.set(t,o)),o.add(n),e.lastFk.set(n,t)},xn=(e,n,t)=>{const r=e.joins.indexOf(t);for(let o=r+1;o<e.joins.length;o+=1){const i=e.joins[o];Fn(i,n,null),i.lastFk.delete(n)}},lr=(e,n,t)=>{let r={...n};if(e.unnests&&e.unnests.length)for(const o of e.unnests)o.keep||ee(r,o.path);for(const o of e.joins){const i=o.localKey(r),s=Lt(i);if(Fn(o,t,s),o.spread){e.explain.spread.touched+=1,he&&at(t,{kind:"spread",origin:o.from});const c=lo(o,s),p=o.spreadPrev.get(t)||new Set,h=new Set;for(const[m,v]of c){if(Object.prototype.hasOwnProperty.call(n,m)){F("router:spread-collision",`a spread join skipped the field "${m}" because the parent row already carries it; a spread field never overwrites a base parent field.`),h.add(m);continue}r[m]=v,Xt.add(m),h.add(m)}for(const m of p)h.has(m)||(r[m]=void 0);o.spreadPrev.set(t,h)}else if(o.many)if(o.aggregate){const c=oo(o,s);if(c.matched?o.ex.matched+=1:(o.ex.unmatchedCount+=1,Yt(o.ex.unmatchedSamples,i)),he&&at(t,{kind:"join",from:o.from,matchedKey:s,matched:c.matched}),c.hold)return he&&st(t,"join-no-partner",`no row in source "${o.from}" matches key ${JSON.stringify(s)}; the row is withheld (missing: 'hold').`,{key:s,source:o.from}),xn(e,t,o),{emit:!1,row:n};for(const[p,h]of c.values)r[p]=h}else{const c=to(o,r,s);if(c.matched?o.ex.matched+=1:(o.ex.unmatchedCount+=1,Yt(o.ex.unmatchedSamples,i)),he&&at(t,{kind:"collect",from:o.from,matchedKey:s,matched:c.matched}),c.hold)return he&&st(t,"join-no-partner",`no row in source "${o.from}" matches key ${JSON.stringify(s)}; the row is withheld (missing: 'hold').`,{key:s,source:o.from}),xn(e,t,o),{emit:!1,row:n};r[o.as]=c.value}else{const c=s!=null&&o.probe?o.probe.index.get(s):null;let p=null;if(c&&c.size){c.size>1&&(o.ex.duplicateCount+=1,Yt(o.ex.duplicateSamples,i));const h=Se.get(o.from);if(h&&h.out){let m;for(m of c);p=h.out.get(m)||null}}if(p)o.ex.matched+=1,he&&at(t,{kind:"join",from:o.from,matchedKey:s,matched:!0}),r=ir(o,r,p);else{if(o.ex.unmatchedCount+=1,Yt(o.ex.unmatchedSamples,i),he&&at(t,{kind:"join",from:o.from,matchedKey:s,matched:!1}),o.missing==="hold")return he&&st(t,"join-no-partner",`no row in source "${o.from}" matches key ${JSON.stringify(s)}; the row is withheld (missing: 'hold').`,{key:s,source:o.from}),xn(e,t,o),{emit:!1,row:n};o.missing==="null"&&(r=ir(o,r,null))}}}return{emit:!0,row:r}},un=(e,n)=>{e.probes||(e.probes=new Map);let t=e.probes.get(n.ffKey);if(!t){t={fn:n.foreignKeyFn,index:new Map,prev:new Map,specs:new Set},e.probes.set(n.ffKey,t);for(const[r,o]of e.live){const i=Lt(t.fn(o));if(i==null)continue;let s=t.index.get(i);s||(s=new Set,t.index.set(i,s)),s.add(r),t.prev.set(r,i)}}t.specs.add(n),n.probe=t},ar=(e,n,t,r)=>{const o=e.live.get(n);if(!o)return;he&&r&&at(n,{kind:"cascade",origin:r});const i=e.out.get(n),s=lr(e,o,n);let c=!1;s.emit?(e.out.set(n,s.row),(i===void 0||!An(i,s.row))&&(t.push({op:"upsert",row:s.row}),c=!0)):(e.out.delete(n),i!==void 0&&(t.push({op:"delete",row:i}),c=!0)),e.hasSpread&&c&&(e.explain.spread.reemitted+=1),c&&ur(e,new Set([n]),t)},ur=(e,n,t)=>{if(!(!e.probes||!e.probes.size))for(const r of e.probes.values()){const o=new Set;for(const i of n){const s=e.live.get(i),c=s?Lt(r.fn(s)):null;c!=null&&o.add(c)}if(o.size)for(const i of r.specs)for(const s of o){const c=i.keyIndex.get(s);if(c)for(const p of[...c]){const h=t.length;ar(i.owner,p,t,e.id),e.explain.cascade.touched+=1,t.length>h&&(e.explain.cascade.reemitted+=1)}}}},_t=(e,n,t)=>{const r=qt();if(e.unnests&&e.unnests.length)for(const p of e.unnests){const h=eo(p,n);h.length&&_t(p.child,h,t)}{const p=[],h=[];for(const m of n)!m||!m.row||(m.op==="delete"?p.push(m.row):h.push(m.row));if(p.length||h.length){const m=[];for(const S of e.joins)if(S.many&&!S.aggregate&&!S.spread&&(S.onParentDelete==="cascade"||S.onParentDelete==="orphan")){const ge=Se.get(S.from);m.push({childSource:ge,pkFn:S.localKey,fkFn:S.foreignKeyFn,index:S.probe?S.probe.index:null,mode:S.onParentDelete,writeBack:!1})}for(const S of x)S.parentId===e.id&&m.push({childSource:Se.get(S.childId),pkFn:S.pkFn,fkFn:S.fkFn,index:S.probe?S.probe.index:null,mode:S.onParentDelete,writeBack:S.writeBack,ex:S.ex});const v=new Map;let A=0;const L=S=>{let ge=v.get(S.id);return ge||(ge={source:S,deltas:[],writeBack:[]},v.set(S.id,ge)),ge};for(const S of m)if(!(!S.childSource||!S.index)){for(const ge of p){const lt=Lt(S.pkFn(ge));if(lt==null)continue;const Bt=S.index.get(lt);if(!Bt)continue;const Kt=L(S.childSource);for(const Ae of[...Bt]){const Ie=S.childSource.live.get(Ae);if(Ie){if(S.ex&&(S.ex.matched+=1),he&&at(Ae,{kind:"relate",parentKey:lt,matchedKey:lt}),S.mode==="cascade")S.childSource.live.delete(Ae),Kt.deltas.push({op:"delete",row:Ie}),he&&st(Ae,"removed-by-cascade",`the parent row (key ${JSON.stringify(lt)}) was deleted, cascading the delete to this child.`,{parentKey:lt}),S.writeBack&&Kt.writeBack.push(Ie);else if(Ie.__orphan!==!0){const Ze={...Ie,__orphan:!0};S.childSource.live.set(Ae,Ze),Kt.deltas.push({op:"upsert",row:Ze}),A+=1}}}}if(S.mode==="orphan")for(const ge of h){const lt=Lt(S.pkFn(ge));if(lt==null)continue;const Bt=S.index.get(lt);if(!Bt)continue;const Kt=L(S.childSource);for(const Ae of[...Bt]){const Ie=S.childSource.live.get(Ae);if(!Ie||Ie.__orphan!==!0)continue;const Ze={...Ie,__orphan:void 0};S.childSource.live.set(Ae,Ze),Kt.deltas.push({op:"upsert",row:Ze})}}}A>0&&F("router:orphaned-rows",`${A} child row(s) were orphaned when their parent was deleted; they are kept and marked __orphan: true (onParentDelete: 'orphan').`);for(const S of v.values())if(S.deltas.length&&_t(S.source,S.deltas,t),S.writeBack.length&&ze)for(const ge of S.writeBack)try{ze({op:"delete",key:String(ge[ce]),row:ge},{route:null,source:S.source.handle})}catch{}}}const o=new Map;if(e.probes&&e.probes.size)for(const p of e.probes.values()){const h=new Set;for(const m of n){const v=String(m.row[ce]);if(m.op==="delete"){const S=p.prev.get(v);if(S!=null){const ge=p.index.get(S);ge&&(ge.delete(v),ge.size||p.index.delete(S)),h.add(S)}p.prev.delete(v);continue}const A=Lt(p.fn(m.row)),L=p.prev.get(v);if(L!=null&&L!==A){const S=p.index.get(L);S&&(S.delete(v),S.size||p.index.delete(L)),h.add(L)}if(A!=null){let S=p.index.get(A);S||(S=new Set,p.index.set(A,S)),S.add(v),h.add(A)}p.prev.set(v,A)}h.size&&o.set(p,h)}const i=[],s=new Set;for(const p of n){const h=String(p.row[ce]);if(p.op==="delete"){for(const L of e.joins)Fn(L,h,null),L.lastFk.delete(h),L.spread&&L.spreadPrev.delete(h);const A=e.out.get(h);e.out.delete(h),A!==void 0&&(i.push(p),s.add(h));continue}const m=e.out.get(h),v=lr(e,p.row,h);v.emit?(e.out.set(h,v.row),(m===void 0||!An(m,v.row))&&(i.push({...p,row:v.row}),s.add(h),e.hasSpread&&(e.explain.spread.reemitted+=1))):(e.out.delete(h),m!==void 0&&(i.push({op:"delete",row:m}),s.add(h)))}t(i);const c=[];if(o.size)for(const[p,h]of o)for(const m of p.specs)for(const v of h){const A=m.keyIndex.get(v);if(A)for(const L of[...A]){const S=c.length;ar(m.owner,L,c,e.id),e.explain.cascade.touched+=1,c.length>S&&(e.explain.cascade.reemitted+=1)}}s.size&&ur(e,s,c),e.explain.timingMs+=qt()-r,c.length&&tt.apply(c)},$n=(e,n,t)=>{const r=T.get(e);if(T.set(e,{cur:n,t}),!r)return 0;const o=(t-r.t)/1e3;return o<=0?0:(n-r.cur)/o},ao=()=>{if(!Re)return 0;let e=0;for(const n of Ne)n.pos>=Fe&&(e+=1);return e},cr=(e,n)=>{const t=we.get(e);if(t)for(const r of t)try{r(n)}catch{}},uo=()=>{fe||We<=0||(fe=setInterval(()=>cr("metrics",tt.metrics()),We),fe&&typeof fe.unref=="function"&&fe.unref())},fr=()=>{fe&&(clearInterval(fe),fe=null)};let cn=0,dr=0,pr=0;const Jt=new Map,gt=new Map,qt=()=>typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),Yt=(e,n)=>{e.length<5&&e.push(n)},Ct=()=>({matched:0,unmatchedCount:0,unmatchedSamples:[],duplicateCount:0,duplicateSamples:[]}),Dn=e=>{const n=new Map;if(e.fields)for(const r of e.fields)n.set(r.name,{coerced:0,invalid:0,samples:[]});const t=new Map;if(e.unnests)for(const r of e.unnests)t.set(r.as,{parentIn:0,childOut:0});return{rowsLoaded:0,rowsApplied:0,rowsRemoved:0,fields:n,unnest:t,spread:{touched:0,reemitted:0},cascade:{touched:0,reemitted:0},timingMs:0}},hr=()=>({whenRouted:0,filterIn:0,filterOut:0,transformIn:0,transformOut:0,sortCount:0,rollupIn:0,rollupOut:0,rollupGroups:0,writeAdd:0,writeUpdate:0,writeRemove:0,timingMs:0}),At=()=>{if(cn+=1,!(cn>1)){dr=qt(),Wt+=1;for(const e of Se.values()){e.explain=Dn(e);for(const n of e.joins)n.ex=Ct()}for(const e of x)e.ex=Ct();for(const e of Oe())e.explain=hr();for(const e of Le)e.explain={whenRouted:0,filterIn:0,filterOut:0}}},Nt=()=>{if(cn-=1,!(cn>0)){pr=qt()-dr;for(const e of Se.values())Jt.set(e.id,In(e));for(const e of Oe())gt.set(e.routeId,fn(e));for(const e of Le)gt.set(e.routeId,Mn(e))}},co=e=>e.label!=null?e.label:e.hasPartValue?e.partValue:e.routeId,fo=e=>{const n=[];for(const t of e.joins){if(t.spread)continue;const r=t.aggregate?"rollup":t.as?"collect":"lookup",o=[];if(t.probe)for(const i of t.probe.index.keys())t.keyIndex.has(i)||o.push(i);n.push({kind:r,from:t.from,as:t.as||null,matched:t.ex.matched,unmatched:{left:{count:t.ex.unmatchedCount,samples:t.ex.unmatchedSamples.slice()},right:{count:o.length,samples:o.slice(0,5)}},duplicates:{count:t.ex.duplicateCount,samples:t.ex.duplicateSamples.slice()}})}for(const t of x)t.childId===e.id&&n.push({kind:"relateRows",from:t.parentId,as:null,matched:t.ex.matched,unmatched:{left:{count:0,samples:[]},right:{count:0,samples:[]}},duplicates:{count:0,samples:[]}});return n},In=e=>{const n={};for(const[r,o]of e.explain.fields)n[r]={coerced:o.coerced,invalid:o.invalid,samples:o.samples.slice()};const t={};for(const[r,o]of e.explain.unnest)t[r]={parentRowsIn:o.parentIn,childRowsOut:o.childOut};return{source:e.id,rows:{loaded:e.explain.rowsLoaded,applied:e.explain.rowsApplied,removed:e.explain.rowsRemoved},fields:n,unnest:t,joins:fo(e),spread:{touched:e.explain.spread.touched,reemitted:e.explain.spread.reemitted},cascade:{touched:e.explain.cascade.touched,reemitted:e.explain.cascade.reemitted},timingMs:e.explain.timingMs}},fn=e=>({route:co(e),label:e.label||null,when:{routed:e.explain.whenRouted,unrouted:ot},filter:{in:e.explain.filterIn,out:e.explain.filterOut},transform:{in:e.explain.transformIn,out:e.explain.transformOut},sort:{count:e.explain.sortCount},rollup:e.rollup?{in:e.explain.rollupIn,out:e.explain.rollupOut,groups:e.explain.rollupGroups}:null,write:{add:e.explain.writeAdd,update:e.explain.writeUpdate,remove:e.explain.writeRemove},timingMs:e.explain.timingMs}),Mn=e=>({route:e.label!=null?e.label:e.routeId,label:e.label||null,kind:e.kind==="monitor"?"monitor":"alert",when:{routed:e.explain.whenRouted,unrouted:ot},filter:{in:e.explain.filterIn,out:e.explain.filterOut},transform:null,sort:null,rollup:null,write:null,timingMs:0});let he=!!g.trace,Wt=0,po=Number.isFinite(g.traceLimit)?Math.max(0,Number(g.traceLimit)):1e4;const Je=new Map,dn=new Map,ho=()=>{for(;Je.size>po;){const e=Je.keys().next().value,n=Je.get(e);Je.delete(e),n&&dn.delete(`${n.source.id}::${n.source.key}`)}},Qt=(e,n,t)=>{let r=Je.get(t);return r?(Je.delete(t),Je.set(t,r),r.settleGen!==Wt&&(r.dropped=null,r.settleGen=Wt),r):(r={source:{id:e,key:n},steps:[],write:null,dropped:null,lastRow:null,lastSeq:void 0,settleGen:Wt},Je.set(t,r),dn.set(`${e}::${n}`,t),ho(),r)},at=(e,n)=>{const t=Je.get(e);t&&(t.steps.push(n),t.settleGen=Wt)},st=(e,n,t,r)=>{const o=Je.get(e);o&&(o.dropped||(o.dropped={reason:n,message:t,...r||{}}),o.settleGen=Wt)},gr=(e,n,t)=>{const r=Je.get(e);r&&(r.dropped=null,r.settleGen=Wt,r.write={op:t,label:n.label||null,routeId:n.routeId,seq:r.lastSeq},r.steps.push({kind:"route",label:n.label||null,op:t,seq:r.lastSeq}))},go=(e,n)=>{const t=Je.get(String(n));return t?{known:!0,source:[{id:t.source.id,key:t.source.key}],steps:t.steps.map(r=>({...r})),route:t.write?{label:t.write.label}:null,write:t.write?{op:t.write.op,seq:t.write.seq}:null}:{known:!1,reason:"not-traced"}},mo=(e,n,t)=>{const r=dn.get(`${String(e)}::${String(n)}`),o=r!=null?Je.get(r):null;if(!o)return{known:!1,reason:"not-traced"};const i=t!==void 0?[Z(t)].filter(Boolean):Oe();if(o.lastRow)for(const s of i){const c=D([s.keyOf(o.lastRow)]);if(s.keys&&s.keys.has(c))return{known:!0,present:!0,message:"this row is in the grid.",route:{label:s.label||null}}}if(t!==void 0){const s=Z(t);if(s&&o.lastRow&&!s.match(o.lastRow))return{known:!0,present:!1,reason:"predicate-false",label:s.label||null,message:`the row did not match route "${s.label||s.routeId}"'s predicate.`}}return o.dropped?{known:!0,present:!1,...o.dropped}:{known:!0,present:!1,reason:"unrouted",message:"no route (and no default sink) matched this row."}},pn=(e,n)=>go(e,n);pn.enable=()=>{he=!0},pn.disable=()=>{he=!1},pn.missing=(e,n,t)=>mo(e,n,t);const yo=e=>{const n=e.indexedDB||(typeof indexedDB<"u"?indexedDB:null);if(!n)return null;const t=typeof e.dbName=="string"?e.dbName:"lattice-router",r=typeof e.storeName=="string"?e.storeName:"snapshots";let o=null;const i=()=>o||(o=new Promise((s,c)=>{let p;try{p=n.open(t,1)}catch(h){c(h);return}p.onupgradeneeded=()=>{const h=p.result;h.objectStoreNames.contains(r)||h.createObjectStore(r)},p.onsuccess=()=>s(p.result),p.onerror=()=>c(p.error)}),o);return{set(s,c){return i().then(p=>new Promise((h,m)=>{const v=p.transaction(r,"readwrite");v.objectStore(r).put(c,s),v.oncomplete=()=>h(),v.onerror=()=>m(v.error),v.onabort=()=>m(v.error)}))},get(s){return i().then(c=>new Promise((p,h)=>{const v=c.transaction(r,"readonly").objectStore(r).get(s);v.onsuccess=()=>p(v.result),v.onerror=()=>h(v.error)}))},close(){o&&o.then(s=>{try{s.close()}catch{}},()=>{})}}},bo=()=>Re?[...rn(void 0,ve).values()]:Vt(),wo=()=>({v:1,world:bo(),maxSeq:P,checkpoint:Object.fromEntries(_),buffer:Re?{on:!0,max:se,window:ke,domain:ve,pos:_e,baseSeq:Me,baseT:yt,base:[...Ve.entries()],log:Ne.map(e=>({pos:e.pos,seq:e.seq,t:e.t,op:e.op,key:e.key,row:e.row}))}:{on:!1}}),ko=e=>{if(!e||typeof e!="object")return!1;xe=!0;try{tt.load(Array.isArray(e.world)?e.world:[])}finally{xe=!1}e.checkpoint&&tt.seenThrough(e.checkpoint),Number.isFinite(e.maxSeq)&&(P===void 0||e.maxSeq>P)&&(P=e.maxSeq);const n=e.buffer;if(n&&n.on){Re=!0,se=Number.isFinite(n.max)?n.max:null,ke=Number.isFinite(n.window)?n.window:null,ve=n.domain==="seq"||n.domain==="time"?n.domain:De?"seq":"time",Ve=new Map(Array.isArray(n.base)?n.base:[]),Ne.length=0;for(const t of Array.isArray(n.log)?n.log:[])Ne.push({...t});_e=Number.isFinite(n.pos)?n.pos:Ne.length,Me=n.baseSeq,yt=n.baseT,Fe=_e}return!0},Ln=()=>{if(!ue)return Promise.resolve();const e=wo(),n=Promise.resolve().then(()=>ue.set(et,e)).catch(()=>{});return Ge=n,n.then(()=>{Ge===n&&(Ge=null)})},Cn=()=>{if(!(!me||!ue||xe)){if(ft<=0){Ln();return}Ee||(Ee=setTimeout(()=>{Ee=null,Ln()},ft),Ee&&typeof Ee.unref=="function"&&Ee.unref())}},tt={attach(e,n,t={}){const r=typeof n!="function",o=r?s=>d(s)===n:n;r&&Gn(n);const i=En(e,o,t);return r&&(i.hasPartValue=!0,i.partValue=n),Xe.push(i),gt.set(i.routeId,fn(i)),i.writable&&Rr(i),this},attachDefault(e,n={}){return Ye=En(e,()=>!1,n),Ye.isDefault=!0,gt.set(Ye.routeId,fn(Ye)),this},subscribe(e,n,t={}){const r=typeof e!="function",o=r?s=>d(s)===e:e;r&&Gn(e);const i=En(n,o,t);return r&&(i.hasPartValue=!0,i.partValue=e),Xe.push(i),gt.set(i.routeId,fn(i)),this},alert(e,n,t,r={}){const o=typeof e=="function"?e:s=>d(s)===e,i={routeId:q(),label:typeof r.label=="string"?r.label:null,match:o,keyOf:ne(R(r.rowKey,"alerts"),f),filter:typeof r.filter=="function"?r.filter:null,condition:typeof n=="function"?n:()=>!1,handler:typeof t=="function"?t:()=>{},debounceMs:Number.isFinite(r.debounce)?Number(r.debounce):0,armed:!0,timer:null,pending:null,partition:new Map,explain:{whenRouted:0,filterIn:0,filterOut:0}};return Le.push(i),jn(i,Vt()),nn(i),gt.set(i.routeId,Mn(i)),this},monitor(e,n,t,r={}){const o=typeof e=="function"?e:s=>d(s)===e,i={kind:"monitor",routeId:q(),label:typeof r.label=="string"?r.label:null,match:o,keyOf:ne(R(r.rowKey,"alerts"),f),filter:typeof r.filter=="function"?r.filter:null,evaluate:typeof n=="function"?n:()=>{},handler:typeof t=="function"?t:()=>{},armed:!0,timer:null,pending:null,partition:new Map,explain:{whenRouted:0,filterIn:0,filterOut:0}};return Le.push(i),jn(i,Vt()),nn(i),gt.set(i.routeId,Mn(i)),()=>{const s=Le.indexOf(i);s>=0&&Le.splice(s,1),i.timer&&(clearTimeout(i.timer),i.timer=null),i.partition.clear()}},configure(e={}){const n=t=>({rowKey:t.rowKey,transform:t.transform,filter:t.filter,sort:t.sort,rollup:t.rollup,debounce:t.debounce,where:t.where,writable:t.writable,onWrite:t.onWrite,onConflict:t.onConflict,backpressure:t.backpressure,label:t.label});for(const t of e.routes||[])if(t){if(t.default!==void 0){this.attachDefault(t.default,n(t));continue}if(t.alert!==void 0){this.alert(t.when,t.condition,t.alert,n(t));continue}if(t.subscribe!==void 0){this.subscribe(t.when,t.subscribe,n(t));continue}this.attach(t.grid,t.when,n(t))}for(const t of e.links||[])t&&t.from&&t.to&&this.link(t.from,t.to,t.on!==void 0?t.on:t.relation);return e.relate&&this.relate(e.relate),e.buffer&&this.buffer(e.buffer),this},link(e,n,t){const r={from:e,to:n,relation:t,predicate:null};rt.push(r),zn(e),Ht(r);const o=St(n);return o&&jt(o),this},relate(e){for(const n of e||[]){if(!n||!n.from||!n.to)continue;const t=n.on!==void 0?n.on:n.relation!==void 0?n.relation:n.rel;Ue.push({from:n.from,to:n.to,rel:t}),n.mutual&&Ue.push({from:n.to,to:n.from,rel:qe(t)})}for(const n of Gt())zn(n);Mt();for(const n of Gt()){const t=St(n);t&&jt(t)}return this},flush(){return Sn(),this},detach(e){const n=new Set;for(let o=rt.length-1;o>=0;o--){const i=rt[o];(i.from===e||i.to===e)&&(i.to!==e&&n.add(i.to),Un(i.from),rt.splice(o,1))}let t=!1;for(let o=Ue.length-1;o>=0;o--)(Ue[o].from===e||Ue[o].to===e)&&(Un(Ue[o].from),Ue.splice(o,1),t=!0);for(let o=Xe.length-1;o>=0;o--)Xe[o].grid===e&&Xe.splice(o,1);Ye&&Ye.grid===e&&(Ye=null),Dt.delete(e);const r=Tt.get(e);if(r&&(r(),Tt.delete(e)),t){Mt();for(const o of Gt())n.add(o)}for(const o of n){const i=St(o);i&&jt(i)}return this},load(e){At();try{ot=0;const n=new Map(Oe().map(r=>[r,[]]));for(const r of e||[]){he&&(Qt("router",r[ce],String(r[ce])).lastRow=r);const o=Et(r);if(!o.length){ot+=1,K&&K(r),he&&st(String(r[ce]),"unrouted","no route (and no default sink) matched this row.");continue}for(const i of o)n.get(i).push(r)}for(const r of Oe()){const o=n.get(r);r.partition=new Map(o.map(i=>[String(r.keyOf(i)),i])),r.metricRows+=o.length,r.explain.whenRouted+=o.length,re+=o.length}if(De)for(const r of e||[]){const o=De(r);if(!Number.isFinite(o))continue;const i=String(a(r)),s=_.get(i);(s===void 0||o>s)&&_.set(i,o),(P===void 0||o>P)&&(P=o)}for(const r of rt)Ht(r);Mt();for(const r of Le)jn(r,e||[]),nn(r);for(const r of Oe())r.bp&&kr(r);const t=Oe().map(r=>jt(r));return Re&&Yn(),Fe=_e,je&&!Be&&ln(Zn()),Cn(),t}finally{Nt()}},apply(e){At();try{let n=(e||[]).filter(o=>o&&o.row);if(he)for(const o of n)Qt("router",o.row[ce],String(o.row[ce]));if(nt){n=n.map((i,s)=>[i,s]).sort((i,s)=>{const c=$t(i[0]),p=$t(s[0]);return c===void 0||p===void 0?i[1]-s[1]:c-p||i[1]-s[1]}).map(i=>i[0]);const o=[];for(const i of n){const s=$t(i);if(s!==void 0){const c=String(a(i.row)),p=_.get(c);if(p!==void 0&&s<=p){X+=1,he&&st(String(i.row[ce]),"deduped-stale-seq",`seq ${s} is not newer than the last applied seq ${p} for this row; the delta was dropped.`);continue}_.set(c,s),(P===void 0||s>P)&&(P=s)}o.push(i)}n=o}if(he)for(const o of n){if(!o.row)continue;const i=$t(o);if(i===void 0)continue;const s=Je.get(String(o.row[ce]));s&&(s.lastSeq=i)}if(je&&!Be&&n.length&&ln({t:"delta",deltas:n.map(o=>({op:o.op,row:o.row,seq:o.seq}))}),Re){for(const o of n)Fr(o);Nr()}for(const o of Le)Ar(o,n),nn(o);if(bt){Cn();return}const t=new Map(Oe().map(o=>[o,new Map]));for(const o of n){const i=o&&o.row;if(!i)continue;if(o.op==="delete"){let c=!1;for(const p of Oe()){const h=String(p.keyOf(i));(p.partition.has(h)||t.get(p).has(h))&&(t.get(p).set(h,{op:"del"}),c=!0)}!c&&!Et(i).length&&(ot+=1,K&&K(o));continue}if(he){const c=Je.get(String(i[ce]));c&&(c.lastRow=i)}const s=Et(i);if(!s.length){ot+=1,K&&K(o),he&&st(String(i[ce]),"unrouted","no route (and no default sink) matched this row.");continue}for(const c of Oe()){if(s.includes(c))continue;const p=String(c.keyOf(i));(c.partition.has(p)||t.get(c).get(p)?.op==="set")&&t.get(c).set(p,{op:"del"})}for(const c of s)t.get(c).set(String(c.keyOf(i)),{op:"set",row:i})}const r=new Map;for(const o of Oe()){let i=0;const s=t.get(o).size;for(const[c,p]of t.get(o)){if(p.op==="del"){o.partition.delete(c);continue}o.partition.set(c,p.row),i+=1}o.metricRows+=i,o.explain.whenRouted+=i,re+=i,r.set(o,s)}for(const o of rt)Ht(o);Mt();for(const o of Oe()){const i=he?[...t.get(o).values()].filter(s=>s.op==="set").map(s=>s.row):null;wr(o,r.get(o)||0,i)}Fe=_e,Cn()}finally{Nt()}},push(e){const n=Array.isArray(e)?e:[e];if(!I)return this.apply(n),this;for(const t of n)if(Q.push(t),he&&t&&t.row){const r=String(t.row[ce]),o=Je.has(r)?Je.get(r):Qt("router",t.row[ce],r);o.lastRow=t.row,st(r,"not-yet-flushed","the delta is buffered for batch/coalesce and has not been applied yet.")}return y!==null&&(y<=0?this.flushStream():l||(l=setTimeout(()=>this.flushStream(),y))),this},flushStream(){if(l&&(clearTimeout(l),l=null),!Q.length)return this;const e=Q.splice(0,Q.length);return this.apply(e),this},flushBackpressure(){At();try{for(const e of Oe())e.bp&&(e.bpTimer||e.bpPending>0)&&en(e)}finally{Nt()}return this},addSource(e,n){let t,r;e&&typeof e=="object"?(r=e,t=r.id!=null?String(r.id):`source${++Ut}`):(t=e!=null?String(e):`source${++Ut}`,r=n||{});const o=Se.get(t);if(o)return F("data-router:duplicate-source",`addSource("${t}") was already registered; returning the existing source handle. Use a distinct id per feed.`),o.handle;const i={id:t,map:typeof r.map=="function"?r.map:null,fields:Hr(r.fields),ns:Lr(t,r.key),live:new Map,out:new Map,ingested:0,joins:[],unnests:[]};i.handle=tr(i),i.joins=rr(r.join,i),i.hasSpread=i.joins.some(s=>s.spread),Se.set(t,i);for(const s of i.joins)Se.has(s.from)&&un(Se.get(s.from),s);for(const s of Se.values())if(s!==i)for(const c of s.joins)c.from===t&&c.probe==null&&un(i,c);return i.unnests=or(r.unnest,i),i.explain=Dn(i),Jt.set(t,In(i)),i.handle},removeSource(e){const n=e&&typeof e=="object"&&e.id!==void 0?String(e.id):String(e),t=Se.get(n);return t&&t.handle.remove(),this},sources(){return[...Se.keys()]},relateRows(e={}){const n=m=>m&&typeof m=="object"&&m.id!==void 0?String(m.id):String(m),t=n(e.child),r=n(e.parent),o=Se.get(t),i=Se.get(r);if(!o||!i)return F("data-router:relaterows-missing-source","relateRows needs both `child` and `parent` to be registered source ids (or the handles addSource returned); the rule was ignored."),this;let s,c;if(typeof e.foreignKey=="function")s=e.foreignKey,c=`fn:${s.toString()}`;else if(typeof e.foreignKey=="string"&&e.foreignKey)s=m=>m[e.foreignKey],c=e.foreignKey;else return F("data-router:relaterows-no-foreignkey","relateRows needs a `foreignKey` (the child field holding the parent key); the rule was ignored."),this;const p=e.onParentDelete==="cascade"||e.onParentDelete==="orphan"?e.onParentDelete:null;if(!p)return this;o.probes||(o.probes=new Map);let h=o.probes.get(c);if(!h){h={fn:s,index:new Map,prev:new Map,specs:new Set},o.probes.set(c,h);for(const[m,v]of o.live){const A=Lt(h.fn(v));if(A==null)continue;let L=h.index.get(A);L||(L=new Set,h.index.set(A,L)),L.add(m),h.prev.set(m,A)}}return x.push({parentId:r,childId:t,fkFn:s,pkFn:m=>m[ce],onParentDelete:p,writeBack:e.writeBack===!0,probe:h,ex:Ct()}),this},fieldsOf(e){const n=Z(e);return!n||!n.spreadFields?[]:[...n.spreadFields.keys()]},metrics(){const e=k(),n=Oe().map((r,o)=>({index:o,label:r.label||(r.isDefault?"default":null),kind:typeof r.grid=="function"?"view":"grid",rows:r.partition.size,shown:r.keys.size,routed:r.metricRows,throughput:$n(`route:${o}`,r.metricRows,e),backpressure:r.bp?{pending:r.bpPending,coalesced:r.bpCoalesced}:null})),t=[...Se.values()].map(r=>({id:r.id,rows:r.live.size,ingested:r.ingested,throughput:$n(`source:${r.id}`,r.ingested,e)}));return{routes:n,sources:t,unrouted:ot,dropped:X,buffered:Ne.length,lag:ao(),throughput:$n("total",re,e)}},explain(e={}){const n=e&&e.source!=null?String(e.source):null,t=e&&e.route!==void 0?e.route:void 0;if(n!=null||t!==void 0){const o={};if(n!=null&&(o.source=Jt.get(n)||null),t!==void 0){const i=Z(t);if(i)o.route=gt.get(i.routeId)||null;else{const s=Le.find(c=>c.handler===t||c.label!=null&&c.label===t);o.route=s&>.get(s.routeId)||null}}return o}const r=[];for(const o of Oe()){const i=gt.get(o.routeId);i&&r.push(i)}for(const o of Le){const i=gt.get(o.routeId);i&&r.push(i)}return{sources:Object.fromEntries(Jt),routes:r,unrouted:ot,timingMs:pr}},trace:pn,on(e,n){if(typeof n!="function")return()=>{};let t=we.get(e);return t||(t=new Set,we.set(e,t)),t.add(n),e==="metrics"&&uo(),()=>{t.delete(n),e==="metrics"&&t.size===0&&fr()}},mountDevtools(e,n={}){return ae(this,e,n)},get unrouted(){return ot},get dropped(){return X},lastSeq(){return P},checkpoint(){return new Map(_)},seenThrough(e){const n=e instanceof Map?e.entries():Object.entries(e||{});for(const[t,r]of n){const o=Number(r);if(!Number.isFinite(o))continue;const i=_.get(String(t));(i===void 0||o>i)&&_.set(String(t),o),(P===void 0||o>P)&&(P=o)}return this},persist(e={}){if(me=!0,typeof e.key=="string"&&(et=e.key),Number.isFinite(e.debounce)&&(ft=Number(e.debounce)),e.storage&&typeof e.storage.get=="function"&&typeof e.storage.set=="function")ue=e.storage;else{let n=null;try{n=yo(e)}catch{n=null}n?ue=n:(ue=null,F("data-router:no-indexeddb","router.persist() found no usable IndexedDB (a non-browser runtime, private mode, or blocked storage); the router runs in-memory with no durable resume. Pass { storage } to use another backend."))}return this},async restore(){if(!ue)return!1;let e;try{e=await ue.get(et)}catch{return!1}return e==null?!1:ko(e)},async flushPersist(){return Ee&&(clearTimeout(Ee),Ee=null),await Ln(),Ge&&await Ge,this},get persisting(){return me&&!!ue},buffer(e={}){return Re=!0,Number.isFinite(e.max)?se=Number(e.max):"max"in e&&e.max==null&&(se=null),Number.isFinite(e.window)?ke=Number(e.window):"window"in e&&e.window==null&&(ke=null),se==null&&ke==null&&(se=M,F("data-router:buffer-default-cap",`buffer() called with no window or max; applying a default cap of ${M} deltas so the buffer stays bounded. Pass { window } or { max } to size it.`)),ve=De?"seq":"time",Yn(),this},scrubTo(e,n={}){if(!Pn("scrubTo"))return this;sn(),bt=!0;const t=n.by||ve;dt=rn(e,t),on([...dt.values()]),Fe=0;for(const r of Ne){const o=On(r,t);if(e!==void 0&&o!==void 0&&o>e)break;Fe=r.pos+1}return this},replay(e,n,t={}){if(!Pn("replay"))return Promise.resolve();sn(),bt=!0;const r=t.by||ve;return mn=r,pt=Number.isFinite(t.speed)?Number(t.speed):0,dt=rn(e,r),on([...dt.values()]),Ft=Ne.filter(o=>{const i=On(o,r);return i!==void 0&&i>e&&i<=n}).slice().sort((o,i)=>o.pos-i.pos),xt=0,Pt=!1,new Promise(o=>{vt=o,Rn()})},pause(){return Pt=!0,ct&&(clearTimeout(ct),ct=null),this},resume(){return Pt?(Pt=!1,Rn(),this):this},live(){return Pn("live")?(sn(),bt=!1,dt=null,on([...rn(void 0,ve).values()]),Fe=_e,this):this},get traveling(){return bt},get buffered(){return Ne.length},broadcast(e={}){if(typeof BroadcastChannel!="function")return F("data-router:no-broadcastchannel","router.broadcast() needs the BroadcastChannel API, which this runtime does not provide; cross-tab mirroring is off."),this;const n=e&&typeof e.channel=="string"?e.channel:"";return n?(je&&(je.close(),je=null),je=new BroadcastChannel(n),je.onmessage=Dr,ln({t:"hello"}),this):(F("data-router:broadcast-channel","router.broadcast({ channel }) needs a string channel name; nothing was mirrored."),this)},get broadcasting(){return!!je},async query(e,n={}){if(!e||typeof e.execute!="function")return F("data-router:bad-query-source","router.query(adapter) needs an adapter with an execute(query) function (a DFQL/DuckDB adapter or a pushdown source); nothing was fetched."),this;const t=oe(e.capabilities),r=n||{},o=r.filters||null,i=[];ot=0;const s=Oe().filter(p=>p.where),c=Oe().filter(p=>!p.where);for(const p of s){const h=Ce(o,p.where),m=be({...r,filters:h},t);let A=((await e.execute(m.pushed,r)).rows||[]).slice();m.residual&&m.residual.filters&&(A=A.filter(L=>ie(m.residual.filters,L))),A=A.filter(L=>p.match(L)),Ir(p,A),i.push({route:p.grid,pushedFilter:!!(m.pushed&&m.pushed.filters),residual:m.unpushed.slice()})}if(c.length){const p=be(r,t);let m=((await e.execute(p.pushed,r)).rows||[]).slice();p.residual&&p.residual.filters&&(m=m.filter(v=>ie(p.residual.filters,v))),Mr(m,c),i.push({base:!0,pushedFilter:!!(p.pushed&&p.pushed.filters),residual:p.unpushed.slice()})}ht=i;for(const p of rt)Ht(p);Mt();for(const p of Oe())jt(p);return this},lastQueryPlan(){return ht?ht.map(e=>({...e})):null},destroy(){if(wt&&(clearTimeout(wt),wt=null),l&&(clearTimeout(l),l=null),Ee&&(clearTimeout(Ee),Ee=null),ue&&typeof ue.close=="function")try{ue.close()}catch{}me=!1,ue=null,je&&(je.close(),je=null),Be=!1,sn(),Re=!1,bt=!1,dt=null,Ne.length=0,Ve.clear();for(const e of Rt.values())e.off();Rt.clear();for(const e of Tt.values())e();Tt.clear(),It.clear(),Se.clear(),fr(),we.clear(),T.clear();for(const e of Le)e.timer&&(clearTimeout(e.timer),e.timer=null);Le.length=0;for(const e of Oe())e.bpTimer&&(clearTimeout(e.bpTimer),e.bpTimer=null);rt.length=0,Ue.length=0,Dt.clear(),Q.length=0,_.clear(),Xe.length=0,Ye=null,Je.clear(),dn.clear()}};return g.config&&tt.configure(g.config),tt}function kt(g,d){if(g===d)return!0;if(!g||!d)return!1;const f=Object.keys(g),b=Object.keys(d);if(f.length!==b.length)return!1;for(const E of f)if(g[E]!==d[E])return!1;return!0}const He=Ke});var gn=qn("packages/modules/data-router/index.js");typeof module=="object"&&module.exports?module.exports=gn:typeof define=="function"&&define.amd?define(function(){return gn}):yr.LatticeGridDataRouter=gn})(typeof globalThis<"u"?globalThis:this);
|
|
7
7
|
|
|
8
8
|
//# sourceMappingURL=data-router.min.js.map
|