@livenetworks/ashlar 2.1.9 → 2.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- var LnAshlarComponent=(function(C){"use strict";function j(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function S(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let a=null;for(let l=1;l<t.length;l++)if(t[l]&&t[l].nodeType===1){a=t[l];break}if(!S(a))return}e.apply(console,t)}}function pe(e,t){window.lnCore=window.lnCore||{},window.lnCore._debugSink=e,window.lnCore._debugIsContained=t||null}function he(e,t,n){const a=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,a),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:a}))}function h(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){h(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function be(e){const t=e.querySelector('input[name="_method"]');return((t&&t.value!==""?t.value:e.method)||"").toUpperCase()}function me(e,t){const n=!!(t&&t.typed),a=t&&t.exclude,l={},i=e.elements,r={};if(n)for(let d=0;d<i.length;d++){const o=i[d];o.name&&o.type==="checkbox"&&!o.disabled&&(r[o.name]=(r[o.name]||0)+1)}for(let d=0;d<i.length;d++){const o=i[d];if(!(!o.name||o.disabled||o.type==="file"||o.type==="submit"||o.type==="button")&&!(a&&o.matches&&o.matches(a)))if(o.type==="checkbox")n&&r[o.name]===1?l[o.name]=o.checked:(l[o.name]||(l[o.name]=[]),o.checked&&l[o.name].push(o.value));else if(o.type==="radio")o.checked&&(l[o.name]=o.value);else if(o.type==="select-multiple"){l[o.name]=[];for(let s=0;s<o.options.length;s++)o.options[s].selected&&l[o.name].push(o.options[s].value)}else if(n&&o.type==="hidden")l[o.name]=o.value;else if(n&&(o.type==="number"||o.type==="range")){const s=Number(o.value);l[o.name]=o.value===""||isNaN(s)?null:s}else l[o.name]=o.value}return l}function ge(e){if(typeof e!="string")return!!e;const t=e.trim().toLowerCase();return t!=="false"&&t!=="0"&&t!==""&&t!=="off"&&t!=="no"}function ye(e,t){const n=e.elements,a=[],l={};for(let i=0;i<n.length;i++){const r=n[i];r.name&&r.type==="checkbox"&&(l[r.name]=(l[r.name]||0)+1)}for(let i=0;i<n.length;i++){const r=n[i];if(r.type==="file"||r.type==="submit"||r.type==="button")continue;const d=r.getAttribute("data-ln-fill-as")||r.name;if(!d||!(d in t))continue;const o=t[d];if(r.type==="checkbox"){if(Array.isArray(o))r.checked=o.indexOf(r.value)!==-1;else if(l[r.name]>1){const s=String(o).split(",").map(function(c){return c.trim()});r.checked=s.indexOf(r.value)!==-1}else r.checked=ge(o);a.push(r)}else if(r.type==="radio")r.checked=r.value===String(o),a.push(r);else if(r.type==="select-multiple"){if(Array.isArray(o))for(let s=0;s<r.options.length;s++)r.options[s].selected=o.indexOf(r.options[s].value)!==-1;a.push(r)}else r.value=o,r.tagName==="SELECT"&&o!=null&&r.setAttribute("data-ln-value",o),a.push(r)}return a}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.populateForm=ye,window.lnCore.serializeForm=me,window.lnCore.resolveFormMethod=be);const B={};function Ce(e,t){B[e]=t}function Ae(e){return B[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=Ce,window.lnCore.getDataMapper=Ae);function ve(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,h(function(){new MutationObserver(function(){he(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const W={};function Se(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];W[n]=t}function xe(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return W[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=Se,window.lnCore.getLocaleFallback=xe,window.lnCore.ensureLocaleObserver=ve);const x={};function ke(e,t){x[e]||(x[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=x[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function U(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let r=0;r<n.length;r++){const d=n[r],o=d.getAttribute("data-ln-field");t[o]!=null&&(d.textContent=t[o])}const a=e.querySelectorAll("[data-ln-attr]");for(let r=0;r<a.length;r++){const d=a[r],o=d.getAttribute("data-ln-attr").split(",");for(let s=0;s<o.length;s++){const c=o[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();t[f]!=null&&d.setAttribute(u,t[f])}}const l=e.querySelectorAll("[data-ln-show]");for(let r=0;r<l.length;r++){const d=l[r],o=d.getAttribute("data-ln-show");o in t&&d.classList.toggle("hidden",!t[o])}const i=e.querySelectorAll("[data-ln-class]");for(let r=0;r<i.length;r++){const d=i[r],o=d.getAttribute("data-ln-class").split(",");for(let s=0;s<o.length;s++){const c=o[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();f in t&&d.classList.toggle(u,!!t[f])}}return e}function _e(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<n.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[a],t??null),n[a].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)U(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function V(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(r,d){return t[d]!==void 0?t[d]:""}))}const a=function(i,r){return t[r]!==void 0?t[r]:""},l=Array.from(e.querySelectorAll("*"));e.nodeType===1&&l.push(e);for(let i=0;i<l.length;i++){const r=l[i],d=r.attributes;for(let o=0;o<d.length;o++){const s=d[o];s.value.indexOf("{{")!==-1&&r.setAttribute(s.name,s.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return e}function De(e,t,n,a,l,i){const r={};for(let o=0;o<e.children.length;o++){const s=e.children[o],c=s.getAttribute("data-ln-render-key");c&&(r[c]=s)}const d=document.createDocumentFragment();for(let o=0;o<t.length;o++){const s=t[o],c=String(a(s));let u=r[c];if(u)l(u,s,o);else{const f=ke(n,i);if(!f||(V(f,s),u=f.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",c),l(u,s,o)}d.appendChild(u)}e.textContent="",e.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=V,window.lnCore.fill=U,window.lnCore.lnFill=_e,window.lnCore.renderList=De);function k(e,t,n){const a=e.getAttribute(t);return a===null?n:a}function H(e,t,n){const a=parseInt(e.getAttribute(t),10);return isNaN(a)?n:a}function z(e,t,n=!1){const a=e.getAttribute(t);if(a===null)return!!n;const l=a.trim().toLowerCase();return!(l==="false"||l==="0")}function G(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const _=new Map;function Q(e,t){const n=(e?e.join("|"):"")+"::"+t;if(_.has(n))return _.get(n);const a=new Set(e||[]),l=function(i,r){const d=i.getAttribute(r);return d!==null&&a.has(d)?d:t};return _.set(n,l),l}function P(e,t,n){const a=parseFloat(e.getAttribute(t));return isNaN(a)?n:a}function J(e,t,n){const a=e.getAttribute(t);if(!a)return n;try{return JSON.parse(a)}catch{return n}}function K(e,t,n,a,l){if(!e||t===null)return!0;const i=a||"ln-component",r=e.type;if(r==="trigger"||r==="marker"||r==="string"||r==="list"||!r||t===""&&e.fallback!==void 0)return!0;const d=o=>{l?console.warn(o,l):console.warn(o)};if(r==="boolean"){const o=t.trim().toLowerCase();return o!==""&&o!=="true"&&o!=="false"&&o!=="1"&&o!=="0"?(d(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(r==="enum"){const o=e.values||[];return o.includes(t)?!0:(d(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${o.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(r==="integer"){if(!/^-?\d+$/.test(t))return d(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const o=parseInt(t,10);return e.min!==void 0&&o<e.min?(d(`[${i}] Value ${o} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&o>e.max?(d(`[${i}] Value ${o} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(r==="float")return isNaN(Number(t))?(d(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(r==="json")try{return JSON.parse(t),!0}catch(o){return d(`[${i}] Invalid JSON for attribute "${n}": ${o.message}. Fallback: ${e.fallback}.`),!1}return!0}function Ee(e,t,n){for(const a in n){const[l,i,r]=n[a];Object.defineProperty(e,a,{get:function(){return l(t,i,r)},enumerable:!0,configurable:!0})}return e}function qe(e){const t={};for(const n in e){const a=e[n];if(!a||!a.prop)continue;let l=a.read;if(!l&&a.type)switch(a.type){case"enum":l=Q(a.values,a.fallback);break;case"integer":l=H;break;case"float":l=P;break;case"boolean":l=z;break;case"list":l=G;break;case"json":l=J;break;case"string":default:l=k;break}l||(l=k),t[a.prop]=[l,n,a.fallback]}return t}function Ie(e){const t={};for(const n in e){const a=e[n];a&&a.effect&&(t[n]=a.effect)}return Object.keys(t).length?t:null}function $e(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.defineAttrs=Ee,window.lnCore.attrSpec=qe,window.lnCore.attrStr=k,window.lnCore.attrInt=H,window.lnCore.attrBool=z,window.lnCore.attrList=G,window.lnCore.attrEnum=Q,window.lnCore.attrFloat=P,window.lnCore.attrJson=J);function b(e,t){if(!e[t.attribute]){window.lnCore._persistSink&&e.hasAttribute&&e.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(e,t.selector);try{e[t.attribute]=new t.ComponentFn(e)}catch(n){console.error("["+t.attribute+"] init failed",e,n)}}}function X(e,t,n,a){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",r={selector:t,attribute:n,ComponentFn:a};if(e.matches&&e.matches(i)&&b(e,r),e.querySelectorAll){const d=e.querySelectorAll(i);for(let o=0;o<d.length;o++)b(d[o],r)}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function Y(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function Z(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function ee(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function te(e){const t=ee(),n=e.observed||[];for(let a=0;a<n.length;a++){const l=n[a];t.byAttr.has(l)||t.byAttr.set(l,[]),t.byAttr.get(l).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const a in e.attributes){t.byDeclaredAttr.has(a)||t.byDeclaredAttr.set(a,[]);const l=t.byDeclaredAttr.get(a);l.some(i=>i.componentTag===e.componentTag)||l.push({spec:e.attributes[a],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const a=$e(e);if(a===null)t.reactiveWildcard.push(e);else for(const l of a)t.byReactive.has(l)||t.byReactive.set(l,[]),t.byReactive.get(l).push(e)}e.persist&&t.persist.push(e)}function ne(e,t,n,a){for(let l=0;l<e.length;l++){const i=e[l];if(!t[i.attribute])continue;const r=i.effects&&i.effects[n];r?r(t,n,a):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,a)}}function Le(e){const t=e.attributeName,n=t.indexOf("data-ln-")===0,a=ee(),l=a.byAttr.get(t),i=j()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(t);if(!n&&!l&&!i)return;const r=e.target;if(e.oldValue!==r.getAttribute(t)){if(i&&S(r)){const d=a.byDeclaredAttr.get(t),o=r.getAttribute(t);for(let s=0;s<d.length;s++)K(d[s].spec,o,t,d[s].componentTag,r)}if(window.lnCore._debugSink&&(n||l)&&window.lnCore._debugSink("attr",t,r,{oldValue:e.oldValue,newValue:r.getAttribute(t)}),n){const d=a.byReactive.get(t);d&&ne(d,r,t,e.oldValue),a.reactiveWildcard.length&&ne(a.reactiveWildcard,r,t,e.oldValue)}if(l)for(let d=0;d<l.length;d++){const o=l[d];if(o.handler){o.handler(r,t,e.oldValue);continue}o.onAttributeChange&&r[o.attribute]?o.onAttributeChange(r,t):(X(r,o.selector,o.attribute,o.ComponentFn),o.onInit&&o.onInit(r))}}}function ae(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,h(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{Le(t[n])}catch(a){console.error("[ln-core] mutation handler failed",t[n].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function D(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function E(){return window.lnCore=window.lnCore||{},window.lnCore._subtreeRegistry=window.lnCore._subtreeRegistry||[]}function q(e,t){if(!document.contains(e))if(t.attribute){const n=e[t.attribute];if(n&&typeof n.destroy=="function")try{n.destroy()}catch(a){console.error("["+t.attribute+"] destroy failed",e,a)}delete e[t.attribute]}else t.onDestroy&&t.onDestroy(e)}function oe(e){const t=D();if(!t.length)return;const n=e.target;if(n){const l=n.nodeType===1?n:n.parentElement;if(l&&(l.isContentEditable||l.closest&&l.closest('[contenteditable]:not([contenteditable="false"])')))return}const a=E();if(e.target&&a.length)for(let l=0;l<a.length;l++){const i=a[l],r=i.query,d=e.target.nodeType===1?e.target.matches&&e.target.matches(r)?e.target:e.target.closest?e.target.closest(r):null:e.target.parentElement&&e.target.parentElement.closest?e.target.parentElement.closest(r):null;d&&i.onSubtreeChange(d,e)}for(let l=0;l<e.addedNodes.length;l++){const i=e.addedNodes[l];if(i.nodeType===1){const r=!!(i.firstElementChild||i.children&&i.children.length);for(let d=0;d<t.length;d++){const o=t[d];if(o.selector&&o.attribute&&o.ComponentFn){if(!r)i.matches&&i.matches(o.query)&&b(i,o);else if(i.matches&&i.matches(o.query)&&b(i,o),i.querySelectorAll){const s=i.querySelectorAll(o.query);for(let c=0;c<s.length;c++)b(s[c],o)}}o.onInit&&o.onInit(i)}}}for(let l=0;l<e.removedNodes.length;l++){const i=e.removedNodes[l];if(i.nodeType===1){if(document.contains(i))continue;const r=!!(i.firstElementChild||i.children&&i.children.length);for(let d=0;d<t.length;d++){const o=t[d],s=o.query;if(s){if(!r)i.matches&&i.matches(s)&&q(i,o);else if(i.matches&&i.matches(s)&&q(i,o),i.querySelectorAll){const c=i.querySelectorAll(s);for(let u=0;u<c.length;u++)q(c[u],o)}}}}}}function re(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,h(function(){const e=new MutationObserver(function(t){for(let n=0;n<t.length;n++){const a=t[n];if(a.type==="childList")try{oe(a)}catch(l){console.error("[ln-core] lifecycle handler failed",a.target,l)}}});window.lnCore._lifecycleObserver=e,e.observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function Oe(e){if(typeof window>"u")return e();window.lnCore=window.lnCore||{};const t=window.lnCore._lifecycleObserver;if(!t)return e();const n=t.takeRecords();for(let a=0;a<n.length;a++){const l=n[a];if(l.type==="childList")try{oe(l)}catch(i){console.error("[ln-core] lifecycle handler failed",l.target,i)}}t.disconnect();try{return e()}finally{t.observe(document.body,{childList:!0,subtree:!0})}}function Te(e,t){te({observed:e,handler:t}),ae()}function Re(e){D().push(e),e.onSubtreeChange&&e.query&&E().push(e),re()}function le(e,t,n,a,l={}){const i=l.extraAttributes||[],r=l.onAttributeChange||null,d=l.onSubtreeChange||null,o=l.onInit||null,s=l.onAttrChange||null,c=l.effects||null,u=l.attributes||null,f=u?Ie(u):c,O=u?new Set(Object.keys(u)):null,ct=l.persist||null;function v(R){const w=R||document.body;if(X(w,e,t,n),u&&j())for(const y in u){const ft=u[y],F=Array.from(w.querySelectorAll("["+y+"]"));w.matches&&w.matches("["+y+"]")&&F.push(w);for(let M=0;M<F.length;M++){const N=F[M];S(N)&&K(ft,N.getAttribute(y),y,a,N)}}o&&o(w)}const T=[];if(e.indexOf("[")!==-1){const R=/\[([\w-]+)/g;let w;for(;(w=R.exec(e))!==null;)T.push(w[1])}else T.push(e);te({selector:e,attribute:t,componentTag:a,attributes:u,ComponentFn:n,onInit:o,observed:T.concat(i),onAttributeChange:r,onAttrChange:s,effects:f,declared:O,persist:ct}),ae();const ut=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1,ue=l.subtreeQuery||(ut?e:"["+e+"]"),fe={selector:e,attribute:t,ComponentFn:n,onInit:o,onSubtreeChange:d,query:ue};D().push(fe),d&&ue&&E().push(fe),re(),window[t]=v,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerComponent=le,window.lnCore.observeLifecycle=Re,window.lnCore.withoutLifecycle=Oe);function we(){Y()>0?Z(function(){v(document.body)}):v(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",we):we(),v}function ie(e){return(e||"").replace(/^#/,"")}function I(e){const t=e===void 0?location.hash:e,n={},a=ie(t);if(!a)return n;const l=a.split("&");for(let i=0;i<l.length;i++){const r=l[i];if(!r)continue;const d=r.indexOf(":"),o=d>-1?r.slice(0,d):r,s=d>-1?r.slice(d+1):"";if(o)try{n[o]=decodeURIComponent(s)}catch{n[o]=s}}return n}function Fe(e){if(!e)return null;const t=I();return e in t?t[e]:null}function Me(e,t){if(!e)return;const n=I();t==null?delete n[e]:n[e]=String(t);const l=Object.keys(n).map(function(i){const r=n[i];return r===""?i:i+":"+encodeURIComponent(r)}).join("&");ie(location.hash)!==l&&(location.hash=l)}function Ne(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function je(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const a=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return a?t?a+"-"+t:a:t||null}function Be(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function We(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function Ue(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function Ve(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),a=e.slice(t+1),l=a?a.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:l}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=I,window.lnCore.hashGet=Fe,window.lnCore.hashSet=Me,window.lnCore.hashLinkClick=Ne,window.lnCore.resolveHashNamespace=je,window.lnCore.hashSortEncode=Be,window.lnCore.hashSortDecode=We,window.lnCore.hashFilterEncode=Ue,window.lnCore.hashFilterDecode=Ve);function He(e){return(e||"").replace(/^\?/,"")}function ze(e){const t=e===void 0?typeof window<"u"?window.location.search:"":e,n={},a=He(t);if(!a)return n;const l=new URLSearchParams(a);for(const[i,r]of l.entries())n[i]=r;return n}function Ge(e){if(!e||typeof window>"u")return null;const t=new URLSearchParams(window.location.search);return t.has(e)?t.get(e):null}function Qe(e,t){if(!e||typeof window>"u")return;const n=new URL(window.location.href);if(t==null||t===""?n.searchParams.delete(e):n.searchParams.set(e,String(t)),n.search===window.location.search)return;const a=n.pathname+n.search+n.hash;window.history.replaceState(window.history.state,"",a)}function Pe(e,t){if(!e||!e.hasAttribute("data-ln-query"))return null;const n=e.getAttribute("data-ln-query");if(n&&n.trim()!=="")return n.trim();const a=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return a?t?a+"_"+t:a:t||null}function Je(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function Ke(e,t){if(e&&typeof e=="string"){if(e.endsWith(".asc"))return{fieldOrColumn:e.slice(0,-4),direction:"asc"};if(e.endsWith(".desc"))return{fieldOrColumn:e.slice(0,-5),direction:"desc"}}if(t&&typeof t=="object"){const n=t.sort_field||t.sort_by;if(n){const a=t.sort_dir&&String(t.sort_dir).toLowerCase()==="desc"?"desc":"asc";return{fieldOrColumn:n,direction:a}}}return null}function Xe(e){return!Array.isArray(e)||e.length===0?null:e.map(encodeURIComponent).join(",")}function Ye(e){return!e||typeof e!="string"?[]:e.split(",").map(function(t){try{return decodeURIComponent(t.trim())}catch{return t.trim()}}).filter(Boolean)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.queryParse=ze,window.lnCore.queryGet=Ge,window.lnCore.querySet=Qe,window.lnCore.resolveQueryParam=Pe,window.lnCore.querySortEncode=Je,window.lnCore.querySortDecode=Ke,window.lnCore.queryFilterEncode=Xe,window.lnCore.queryFilterDecode=Ye);function Ze(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.uuid=Ze);const $=new Set(["data-ln-accordion","data-ln-ajax","data-ln-api-base-url","data-ln-api-connector","data-ln-api-connector-query-debounce","data-ln-api-endpoint","data-ln-api-headers","data-ln-api-param-limit","data-ln-api-param-offset","data-ln-api-param-search","data-ln-api-param-sort-dir","data-ln-api-param-sort-field","data-ln-api-path","data-ln-api-queue","data-ln-api-queue-online","data-ln-attr","data-ln-autoresize","data-ln-autosave","data-ln-autosave-clear","data-ln-autosave-debounce-input","data-ln-autosave-exclude","data-ln-chart","data-ln-chart-area","data-ln-chart-count","data-ln-chart-empty","data-ln-chart-labels","data-ln-chart-line","data-ln-chart-max","data-ln-chart-min","data-ln-chart-padding","data-ln-chart-plot","data-ln-chart-sort","data-ln-chart-source","data-ln-chart-type","data-ln-chart-x","data-ln-chart-y","data-ln-chart-zero","data-ln-circular-progress","data-ln-circular-progress-label","data-ln-circular-progress-max","data-ln-class","data-ln-col","data-ln-confirm","data-ln-confirm-active","data-ln-confirm-announcer","data-ln-confirm-idle","data-ln-confirm-state","data-ln-confirm-timeout","data-ln-connector","data-ln-couchdb-auth","data-ln-couchdb-connector","data-ln-couchdb-db","data-ln-couchdb-headers","data-ln-couchdb-url","data-ln-data-coordinator","data-ln-data-coordinator-connector","data-ln-data-coordinator-filters","data-ln-data-coordinator-mapper","data-ln-data-coordinator-no-autosync","data-ln-data-coordinator-scope","data-ln-data-coordinator-search","data-ln-data-coordinator-sort-direction","data-ln-data-coordinator-sort-field","data-ln-data-coordinator-stale","data-ln-data-store","data-ln-data-store-frozen","data-ln-data-store-indexes","data-ln-data-store-no-autosync","data-ln-data-store-no-local-query","data-ln-data-store-search-fields","data-ln-data-store-stale","data-ln-data-store-window","data-ln-data-store-window-page","data-ln-date","data-ln-date-dict","data-ln-date-dict-key","data-ln-date-field","data-ln-date-format","data-ln-date-label","data-ln-date-locale","data-ln-debug","data-ln-dropdown","data-ln-dropdown-menu","data-ln-dropdown-placement","data-ln-dropdown-position","data-ln-editor","data-ln-editor-action","data-ln-editor-source","data-ln-empty","data-ln-empty-state","data-ln-empty-when","data-ln-error","data-ln-external-link","data-ln-field","data-ln-fill-as","data-ln-fill-form","data-ln-fill-id","data-ln-fillable","data-ln-filter","data-ln-filter-col","data-ln-filter-hide","data-ln-filter-key","data-ln-filter-options","data-ln-filter-reset","data-ln-filter-search","data-ln-filter-target","data-ln-filter-value","data-ln-filter-values","data-ln-form","data-ln-form-action-edit","data-ln-form-action-method","data-ln-hash","data-ln-include","data-ln-initial-value","data-ln-item","data-ln-item-action","data-ln-item-id","data-ln-item-select","data-ln-key","data-ln-key-allow-input","data-ln-key-for","data-ln-key-modifier","data-ln-key-target","data-ln-link","data-ln-list","data-ln-list-body","data-ln-list-count","data-ln-list-empty","data-ln-list-field","data-ln-list-filtered","data-ln-list-select-all","data-ln-list-selectable","data-ln-list-selected","data-ln-list-source","data-ln-list-total","data-ln-list-window","data-ln-list-window-page","data-ln-list-window-threshold","data-ln-modal","data-ln-modal-close","data-ln-modal-for","data-ln-modal-mode","data-ln-modal-when","data-ln-nav","data-ln-nav-exact","data-ln-number","data-ln-number-decimals","data-ln-number-max","data-ln-number-min","data-ln-obfuscator","data-ln-obfuscator-codec","data-ln-obfuscator-key","data-ln-options","data-ln-options-label","data-ln-options-value","data-ln-outlet","data-ln-panel","data-ln-persist","data-ln-persist-scope","data-ln-picklist","data-ln-picklist-list","data-ln-picklist-max","data-ln-popover","data-ln-popover-for","data-ln-popover-placement","data-ln-popover-position","data-ln-progress","data-ln-progress-max","data-ln-query","data-ln-render-key","data-ln-route","data-ln-route-keep","data-ln-route-target","data-ln-route-title","data-ln-router-base","data-ln-router-hydrate","data-ln-scroll","data-ln-scroll-behavior","data-ln-scroll-block","data-ln-scroll-delay","data-ln-scroll-focus","data-ln-scroll-set","data-ln-scroll-update-hash","data-ln-search","data-ln-search-clear","data-ln-search-clear-for","data-ln-search-exclude","data-ln-search-fields","data-ln-search-for","data-ln-search-hide","data-ln-search-items","data-ln-show","data-ln-slug-from","data-ln-sort","data-ln-sort-dir","data-ln-sort-exclude","data-ln-sort-field","data-ln-sort-icon","data-ln-sort-items","data-ln-sort-state","data-ln-sortable","data-ln-sortable-handle","data-ln-stat","data-ln-stat-card","data-ln-stat-filter","data-ln-stat-label","data-ln-stat-trend","data-ln-stat-value","data-ln-step","data-ln-step-label","data-ln-stepper","data-ln-store","data-ln-tab","data-ln-table","data-ln-table-body","data-ln-table-cell-attr","data-ln-table-clear","data-ln-table-clear-all","data-ln-table-col","data-ln-table-col-filter","data-ln-table-col-select","data-ln-table-col-sort","data-ln-table-coordinator","data-ln-table-count","data-ln-table-dict","data-ln-table-empty","data-ln-table-empty-when","data-ln-table-filter-col","data-ln-table-filtered","data-ln-table-row","data-ln-table-row-action","data-ln-table-row-id","data-ln-table-row-select","data-ln-table-select-all-label","data-ln-table-selectable","data-ln-table-selected","data-ln-table-sort","data-ln-table-source","data-ln-table-total","data-ln-table-window","data-ln-table-window-page","data-ln-table-window-threshold","data-ln-tabs","data-ln-tabs-active","data-ln-tabs-default","data-ln-tabs-focus","data-ln-tabs-key","data-ln-template","data-ln-time","data-ln-time-locale","data-ln-toast","data-ln-toast-close","data-ln-toast-item","data-ln-toast-max","data-ln-toast-timeout","data-ln-toast-when","data-ln-toggle","data-ln-toggle-action","data-ln-toggle-for","data-ln-tooltip","data-ln-tooltip-enhance","data-ln-tooltip-enhanced","data-ln-tooltip-placement","data-ln-tooltip-position","data-ln-translatable","data-ln-translatable-lang","data-ln-translations","data-ln-translations-active","data-ln-translations-add","data-ln-translations-default","data-ln-translations-lang","data-ln-translations-locales","data-ln-translations-placeholder","data-ln-translations-prefix","data-ln-translations-remove-label","data-ln-ui-coordinator","data-ln-upload","data-ln-upload-accept","data-ln-upload-action","data-ln-upload-delete","data-ln-upload-dict","data-ln-upload-ext","data-ln-upload-file-field","data-ln-upload-id","data-ln-upload-ids-field","data-ln-upload-item","data-ln-upload-list","data-ln-upload-local-id","data-ln-upload-max-files","data-ln-upload-max-size","data-ln-upload-progress","data-ln-upload-size","data-ln-upload-state","data-ln-upload-zone","data-ln-validate","data-ln-validate-error","data-ln-validate-errors","data-ln-value","data-ln-websocket-connector","data-ln-websocket-connector-url"]);function et(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;const n=[];for(let a=0;a<=t.length;a++)n[a]=[a];for(let a=0;a<=e.length;a++)n[0][a]=a;for(let a=1;a<=t.length;a++)for(let l=1;l<=e.length;l++)t.charAt(a-1)===e.charAt(l-1)?n[a][l]=n[a-1][l-1]:n[a][l]=Math.min(n[a-1][l-1]+1,n[a][l-1]+1,n[a-1][l]+1);return n[t.length][e.length]}function tt(e,t=$){if(t.has(e))return null;let n=null,a=1/0;for(const i of t){const r=et(e,i);r<a&&(a=r,n=i)}const l=Math.max(3,Math.floor(e.length*.4));return a<=l?n:null}function de(e){return typeof CSS<"u"&&CSS.escape?CSS.escape(e):e.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function nt(e=document){const t=e.ownerDocument||e,n=e.nodeType===9?e.body||e.documentElement:e;if(!n)return[];const a=[],l=[n,...n.querySelectorAll("*")];for(let i=0;i<l.length;i++){const r=l[i];if(r.attributes)for(let d=0;d<r.attributes.length;d++){const o=r.attributes[d];if(o.name.startsWith("data-ln-")&&o.name.endsWith("-for")){const s=(o.value||"").trim();if(!s){a.push({type:"id-empty",element:r,attribute:o.name,targetId:"",message:`[ln-debug] Empty ID reference in <${r.tagName.toLowerCase()} ${o.name}="">.`});continue}t.getElementById(s)||t.querySelector("#"+de(s))||a.push({type:"id-unresolved",element:r,attribute:o.name,targetId:s,message:`[ln-debug] Unresolved ID reference: <${r.tagName.toLowerCase()} ${o.name}="${s}"> targets "#${s}", but no element with id="${s}" exists in the document.`})}}}return a}function at(e=document){const t=e.ownerDocument||e,n=e.nodeType===9?e.body||e.documentElement:e;if(!n)return[];const a=[],l=[n,...n.querySelectorAll("*")];for(let i=0;i<l.length;i++){const r=l[i];if(r.attributes)for(let d=0;d<r.attributes.length;d++){const o=r.attributes[d];if(o.name.startsWith("data-ln-")&&(o.name.endsWith("-source")||o.name.endsWith("-store"))&&o.name!=="data-ln-data-store"){const c=(o.value||"").trim();if(!c){a.push({type:"store-empty",element:r,attribute:o.name,storeName:"",message:`[ln-debug] Empty store reference in <${r.tagName.toLowerCase()} ${o.name}="">.`});continue}const u=de(c),f=t.querySelector(`[data-ln-data-store="${u}"], [data-ln-store="${u}"]`),O=typeof window<"u"&&window.lnDataStore&&typeof window.lnDataStore.getStore=="function"&&window.lnDataStore.getStore(c);!f&&!O&&a.push({type:"store-unresolved",element:r,attribute:o.name,storeName:c,message:`[ln-debug] Unresolved store reference: <${r.tagName.toLowerCase()} ${o.name}="${c}"> targets store "${c}", but no [data-ln-data-store="${c}"] exists in the document.`})}}}return a}function ot(e=document){e.ownerDocument;const t=e.nodeType===9?e.body||e.documentElement:e;if(!t)return[];const n=[],a=Array.from(t.querySelectorAll("[data-ln-data-store]"));t.hasAttribute&&t.hasAttribute("data-ln-data-store")&&a.unshift(t);const l=new Map;for(let i=0;i<a.length;i++){const r=a[i],d=(r.getAttribute("data-ln-data-store")||"").trim();d&&(l.has(d)||l.set(d,[]),l.get(d).push(r))}for(const[i,r]of l.entries())r.length>1&&n.push({type:"store-duplicate",storeName:i,elements:r,message:`[ln-debug] Duplicate store name: Multiple elements declare data-ln-data-store="${i}". Store names must be unique across the document.`});return n}function rt(e=document,t=$){const n=e.nodeType===9?e.body||e.documentElement:e;if(!n)return[];const a=[],l=[n,...n.querySelectorAll("*")];for(let i=0;i<l.length;i++){const r=l[i];if(r.attributes)for(let d=0;d<r.attributes.length;d++){const o=r.attributes[d];if(o.name.startsWith("data-ln-")&&!t.has(o.name)){const s=tt(o.name,t),c=s?` Did you mean "${s}"?`:"";a.push({type:"attribute-unknown",element:r,attribute:o.name,suggestion:s,message:`[ln-debug] Unknown attribute "${o.name}" on <${r.tagName.toLowerCase()}>.${c}`})}}}return a}function A(e=typeof document<"u"?document:null,t={}){if(!e)return{idIssues:[],storeIssues:[],uniquenessIssues:[],spellingIssues:[],total:0};const n=t.validAttributes||$,a=nt(e),l=at(e),i=ot(e),r=rt(e,n),d=[...a,...l,...i,...r];if(!t.silent)for(let o=0;o<d.length;o++)console.warn(d[o].message);return{idIssues:a,storeIssues:l,uniquenessIssues:i,spellingIssues:r,total:d.length}}let m=null;function g(e=typeof document<"u"?document:null,t=50,n=null){if(!e)return;m&&(clearTimeout(m),m=null);function a(){m=setTimeout(()=>{m=null;const l=A(e);n&&n(l)},t)}Y()>0?Z(a):a()}function lt(e,t,n,a){e==="event"?(console.groupCollapsed("[ln-debug] event",t),console.log("target",n),console.log("detail",a),console.groupEnd()):e==="attr"&&(console.groupCollapsed("[ln-debug] attr",t),console.log("target",n),console.log("old → new",a.oldValue,"→",a.newValue),console.groupEnd())}let p=[];function it(){p=Array.from(document.body.querySelectorAll("[data-ln-debug]")),document.body.hasAttribute("data-ln-debug")&&p.push(document.body)}function se(e){if(e===window||e===document)return p.indexOf(document.body)!==-1;for(let t=0;t<p.length;t++)if(p[t].contains(e))return!0;return!1}function dt(e,t,n,a){se(n)&&lt(e,t,n,a)}function L(){it(),pe(p.length>0?dt:null,p.length>0?se:null)}function ce(){L()}function st(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._debugGateBound&&(window.lnCore._debugGateBound=!0,h(function(){L(),Te(["data-ln-debug"],L)},"ln-debug")))}return(function(){const e="data-ln-debug",t="lnDebug";if(typeof window<"u"&&window[t]!==void 0)return;const n={"data-ln-debug":{type:"marker",description:"Enables developer diagnostics overlay, live validation badges, and inspection logging"}};st();function a(i){return this.dom=i,g(i.ownerDocument||document),ce(),this}a.prototype.verify=function(i,r){return A(i||(this.dom?this.dom.ownerDocument||this.dom:document),r)},a.prototype.destroy=function(){delete this.dom[t],ce()};const l=le(e,t,a,"ln-debug",{attributes:n,onInit:function(i){typeof document<"u"&&g(i&&i.ownerDocument?i.ownerDocument:document)},onSubtreeChange:function(i){typeof document<"u"&&g(i&&i.ownerDocument?i.ownerDocument:document)}});l.verify=function(i,r){return A(i||document,r)},l.schedule=function(i,r,d){return g(i||document,r,d)}})(),C.scheduleVerification=g,C.verifyDOM=A,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"}),C})({});
1
+ var LnAshlarComponent=(function(C){"use strict";function j(){return typeof window>"u"?!1:window.lnDebug===!0||window.lnCore&&window.lnCore._debugSink?!0:typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug")||document.body.querySelector("[data-ln-debug]")!==null:!1}function S(e){if(typeof window>"u")return!1;if(window.lnDebug===!0)return!0;if(window.lnCore&&window.lnCore._debugIsContained)return e?window.lnCore._debugIsContained(e):window.lnCore._debugSink!==null;if(e&&e.closest){const t=e.closest("[data-ln-debug]");return!(!t||typeof document<"u"&&t===document.documentElement)}return typeof document<"u"&&document.body?document.body.hasAttribute("data-ln-debug"):!1}if(typeof window<"u"&&(window.lnCore=window.lnCore||{},!window.lnCore._warnBound)){window.lnCore._warnBound=!0;const e=console.warn;console.warn=function(...t){if(typeof t[0]=="string"&&(t[0].startsWith("[ln-")||t[0].startsWith("[lnCore"))){let a=null;for(let l=1;l<t.length;l++)if(t[l]&&t[l].nodeType===1){a=t[l];break}if(!S(a))return}e.apply(console,t)}}function pe(e,t){window.lnCore=window.lnCore||{},window.lnCore._debugSink=e,window.lnCore._debugIsContained=t||null}function he(e,t,n){const a=n||{};window.lnCore._debugSink&&window.lnCore._debugSink("event",t,e,a),e.dispatchEvent(new CustomEvent(t,{bubbles:!0,detail:a}))}function h(e,t){if(!document.body){document.addEventListener("DOMContentLoaded",function(){h(e,t)}),console.warn("["+t+'] Script loaded before <body> — add "defer" to your <script> tag');return}e()}function be(e){const t=e.querySelector('input[name="_method"]');return((t&&t.value!==""?t.value:e.method)||"").toUpperCase()}function me(e,t){const n=!!(t&&t.typed),a=t&&t.exclude,l={},i=e.elements,r={};if(n)for(let d=0;d<i.length;d++){const o=i[d];o.name&&o.type==="checkbox"&&!o.disabled&&(r[o.name]=(r[o.name]||0)+1)}for(let d=0;d<i.length;d++){const o=i[d];if(!(!o.name||o.disabled||o.type==="file"||o.type==="submit"||o.type==="button")&&!(a&&o.matches&&o.matches(a)))if(o.type==="checkbox")n&&r[o.name]===1?l[o.name]=o.checked:(l[o.name]||(l[o.name]=[]),o.checked&&l[o.name].push(o.value));else if(o.type==="radio")o.checked&&(l[o.name]=o.value);else if(o.type==="select-multiple"){l[o.name]=[];for(let s=0;s<o.options.length;s++)o.options[s].selected&&l[o.name].push(o.options[s].value)}else if(n&&o.type==="hidden")l[o.name]=o.value;else if(n&&(o.type==="number"||o.type==="range")){const s=Number(o.value);l[o.name]=o.value===""||isNaN(s)?null:s}else l[o.name]=o.value}return l}function ge(e){if(typeof e!="string")return!!e;const t=e.trim().toLowerCase();return t!=="false"&&t!=="0"&&t!==""&&t!=="off"&&t!=="no"}function ye(e,t){const n=e.elements,a=[],l={};for(let i=0;i<n.length;i++){const r=n[i];r.name&&r.type==="checkbox"&&(l[r.name]=(l[r.name]||0)+1)}for(let i=0;i<n.length;i++){const r=n[i];if(r.type==="file"||r.type==="submit"||r.type==="button")continue;const d=r.getAttribute("data-ln-fill-as")||r.name;if(!d||!(d in t))continue;const o=t[d];if(r.type==="checkbox"){if(Array.isArray(o))r.checked=o.indexOf(r.value)!==-1;else if(l[r.name]>1){const s=String(o).split(",").map(function(c){return c.trim()});r.checked=s.indexOf(r.value)!==-1}else r.checked=ge(o);a.push(r)}else if(r.type==="radio")r.checked=r.value===String(o),a.push(r);else if(r.type==="select-multiple"){if(Array.isArray(o))for(let s=0;s<r.options.length;s++)r.options[s].selected=o.indexOf(r.options[s].value)!==-1;a.push(r)}else r.value=o,r.tagName==="SELECT"&&o!=null&&r.setAttribute("data-ln-value",o),a.push(r)}return a}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.populateForm=ye,window.lnCore.serializeForm=me,window.lnCore.resolveFormMethod=be);const B={};function Ce(e,t){B[e]=t}function Ae(e){return B[e]||{ingress:t=>t,egress:t=>t}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerDataMapper=Ce,window.lnCore.getDataMapper=Ae);function ve(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._localeObserverBound&&(window.lnCore._localeObserverBound=!0,h(function(){new MutationObserver(function(){he(document,"ln-core:locale-change",{})}).observe(document.documentElement,{attributes:!0,attributeFilter:["lang"],subtree:!0})},"ln-core")))}const W={};function Se(e,t){if(!e||typeof t!="object")return;const n=e.toLowerCase().split("-")[0];W[n]=t}function xe(e){if(!e)return null;const t=e.toLowerCase().split("-")[0];return W[t]||null}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerLocaleFallback=Se,window.lnCore.getLocaleFallback=xe,window.lnCore.ensureLocaleObserver=ve);const x={};function ke(e,t){x[e]||(x[e]=document.querySelector('[data-ln-template="'+e+'"]'));const n=x[e];return n?n.content.cloneNode(!0):(console.warn("["+(t||"ln-core")+'] Template "'+e+'" not found'),null)}function U(e,t){if(!e||!t)return e;const n=e.querySelectorAll("[data-ln-field]");for(let r=0;r<n.length;r++){const d=n[r],o=d.getAttribute("data-ln-field");t[o]!=null&&(d.textContent=t[o])}const a=e.querySelectorAll("[data-ln-attr]");for(let r=0;r<a.length;r++){const d=a[r],o=d.getAttribute("data-ln-attr").split(",");for(let s=0;s<o.length;s++){const c=o[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();t[f]!=null&&d.setAttribute(u,t[f])}}const l=e.querySelectorAll("[data-ln-show]");for(let r=0;r<l.length;r++){const d=l[r],o=d.getAttribute("data-ln-show");o in t&&d.classList.toggle("hidden",!t[o])}const i=e.querySelectorAll("[data-ln-class]");for(let r=0;r<i.length;r++){const d=i[r],o=d.getAttribute("data-ln-class").split(",");for(let s=0;s<o.length;s++){const c=o[s].trim().split(":");if(c.length!==2)continue;const u=c[0].trim(),f=c[1].trim();f in t&&d.classList.toggle(u,!!t[f])}}return e}function _e(e,t){e.matches&&e.matches("[data-ln-form], [data-ln-fillable]")&&(window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",e,t??null),e.dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0})));const n=e.querySelectorAll("[data-ln-form], [data-ln-fillable]");for(let a=0;a<n.length;a++)window.lnCore._debugSink&&window.lnCore._debugSink("event","ln-fill",n[a],t??null),n[a].dispatchEvent(new CustomEvent("ln-fill",{detail:t??null,bubbles:!0}));return e}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._fillBound||(window.lnCore._fillBound=!0,document.addEventListener("ln-fill",function(e){if(!(!e.target.matches||!e.target.matches("[data-ln-fillable]")))if(e.detail)U(e.target,e.detail);else{const t=e.target.querySelectorAll("[data-ln-field]");for(let n=0;n<t.length;n++)t[n].textContent=""}})));function V(e,t){if(!e||!t)return e;const n=document.createTreeWalker(e,NodeFilter.SHOW_TEXT);for(;n.nextNode();){const i=n.currentNode;i.textContent.indexOf("{{")!==-1&&(i.textContent=i.textContent.replace(/\{\{\s*(\w+)\s*\}\}/g,function(r,d){return t[d]!==void 0?t[d]:""}))}const a=function(i,r){return t[r]!==void 0?t[r]:""},l=Array.from(e.querySelectorAll("*"));e.nodeType===1&&l.push(e);for(let i=0;i<l.length;i++){const r=l[i],d=r.attributes;for(let o=0;o<d.length;o++){const s=d[o];s.value.indexOf("{{")!==-1&&r.setAttribute(s.name,s.value.replace(/\{\{\s*(\w+)\s*\}\}/g,a))}}return e}function De(e,t,n,a,l,i){const r={};for(let o=0;o<e.children.length;o++){const s=e.children[o],c=s.getAttribute("data-ln-render-key");c&&(r[c]=s)}const d=document.createDocumentFragment();for(let o=0;o<t.length;o++){const s=t[o],c=String(a(s));let u=r[c];if(u)l(u,s,o);else{const f=ke(n,i);if(!f||(V(f,s),u=f.firstElementChild,!u))continue;u.setAttribute("data-ln-render-key",c),l(u,s,o)}d.appendChild(u)}e.textContent="",e.appendChild(d)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.fillTemplate=V,window.lnCore.fill=U,window.lnCore.lnFill=_e,window.lnCore.renderList=De);function k(e,t,n){const a=e.getAttribute(t);return a===null?n:a}function H(e,t,n){const a=parseInt(e.getAttribute(t),10);return isNaN(a)?n:a}function z(e,t,n=!1){const a=e.getAttribute(t);if(a===null)return!!n;const l=a.trim().toLowerCase();return!(l==="false"||l==="0")}function G(e,t){return(e.getAttribute(t)||"").split(",").map(n=>n.trim()).filter(Boolean)}const _=new Map;function Q(e,t){const n=(e?e.join("|"):"")+"::"+t;if(_.has(n))return _.get(n);const a=new Set(e||[]),l=function(i,r){const d=i.getAttribute(r);return d!==null&&a.has(d)?d:t};return _.set(n,l),l}function P(e,t,n){const a=parseFloat(e.getAttribute(t));return isNaN(a)?n:a}function J(e,t,n){const a=e.getAttribute(t);if(!a)return n;try{return JSON.parse(a)}catch{return n}}function K(e,t,n,a,l){if(!e||t===null)return!0;const i=a||"ln-component",r=e.type;if(r==="trigger"||r==="marker"||r==="string"||r==="list"||!r||t===""&&e.fallback!==void 0)return!0;const d=o=>{l?console.warn(o,l):console.warn(o)};if(r==="boolean"){const o=t.trim().toLowerCase();return o!==""&&o!=="true"&&o!=="false"&&o!=="1"&&o!=="0"?(d(`[${i}] Invalid value "${t}" for boolean attribute "${n}". Allowed: "true", "false", or presence-only.`),!1):!0}if(r==="enum"){const o=e.values||[];return o.includes(t)?!0:(d(`[${i}] Invalid value "${t}" for attribute "${n}". Allowed: ${o.join(", ")}. Fallback: "${e.fallback}".`),!1)}if(r==="integer"){if(!/^-?\d+$/.test(t))return d(`[${i}] Invalid integer "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1;const o=parseInt(t,10);return e.min!==void 0&&o<e.min?(d(`[${i}] Value ${o} for attribute "${n}" is less than min (${e.min}).`),!1):e.max!==void 0&&o>e.max?(d(`[${i}] Value ${o} for attribute "${n}" is greater than max (${e.max}).`),!1):!0}if(r==="float")return isNaN(Number(t))?(d(`[${i}] Invalid float "${t}" for attribute "${n}". Fallback: ${e.fallback}.`),!1):!0;if(r==="json")try{return JSON.parse(t),!0}catch(o){return d(`[${i}] Invalid JSON for attribute "${n}": ${o.message}. Fallback: ${e.fallback}.`),!1}return!0}function Ee(e,t,n){for(const a in n){const[l,i,r]=n[a];Object.defineProperty(e,a,{get:function(){return l(t,i,r)},enumerable:!0,configurable:!0})}return e}function qe(e){const t={};for(const n in e){const a=e[n];if(!a||!a.prop)continue;let l=a.read;if(!l&&a.type)switch(a.type){case"enum":l=Q(a.values,a.fallback);break;case"integer":l=H;break;case"float":l=P;break;case"boolean":l=z;break;case"list":l=G;break;case"json":l=J;break;case"string":default:l=k;break}l||(l=k),t[a.prop]=[l,n,a.fallback]}return t}function Ie(e){const t={};for(const n in e){const a=e[n];a&&a.effect&&(t[n]=a.effect)}return Object.keys(t).length?t:null}function $e(e){if(e.onAttrChange&&!e.declared)return null;const t=new Set;if(e.effects)for(const n in e.effects)t.add(n);if(e.onAttrChange&&e.declared)for(const n of e.declared)t.add(n);return t}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.defineAttrs=Ee,window.lnCore.attrSpec=qe,window.lnCore.attrStr=k,window.lnCore.attrInt=H,window.lnCore.attrBool=z,window.lnCore.attrList=G,window.lnCore.attrEnum=Q,window.lnCore.attrFloat=P,window.lnCore.attrJson=J);function b(e,t){if(!e[t.attribute]){window.lnCore._persistSink&&e.hasAttribute&&e.hasAttribute("data-ln-persist")&&window.lnCore._persistSink(e,t.selector);try{e[t.attribute]=new t.ComponentFn(e)}catch(n){console.error("["+t.attribute+"] init failed",e,n)}}}function X(e,t,n,a){if(e.nodeType!==1)return;const i=t.indexOf("[")!==-1||t.indexOf(".")!==-1||t.indexOf("#")!==-1?t:"["+t+"]",r={selector:t,attribute:n,ComponentFn:a};if(e.matches&&e.matches(i)&&b(e,r),e.querySelectorAll){const d=e.querySelectorAll(i);for(let o=0;o<d.length;o++)b(d[o],r)}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[]);function Y(){return typeof window<"u"&&window.lnCore&&window.lnCore._bootHolds||0}function Z(e){typeof window<"u"?(window.lnCore=window.lnCore||{},window.lnCore._bootHolds=window.lnCore._bootHolds||0,window.lnCore._bootQueue=window.lnCore._bootQueue||[],window.lnCore._bootHolds>0?window.lnCore._bootQueue.push(e):setTimeout(e,0)):e()}function ee(){window.lnCore=window.lnCore||{};const e=window.lnCore._attrRegistry=window.lnCore._attrRegistry||{byAttr:new Map,reactive:[],persist:[]};return e.byReactive=e.byReactive||new Map,e.reactiveWildcard=e.reactiveWildcard||[],e}function te(e){const t=ee(),n=e.observed||[];for(let a=0;a<n.length;a++){const l=n[a];t.byAttr.has(l)||t.byAttr.set(l,[]),t.byAttr.get(l).push(e)}if(t.byDeclaredAttr=t.byDeclaredAttr||new Map,e.attributes)for(const a in e.attributes){t.byDeclaredAttr.has(a)||t.byDeclaredAttr.set(a,[]);const l=t.byDeclaredAttr.get(a);l.some(i=>i.componentTag===e.componentTag)||l.push({spec:e.attributes[a],componentTag:e.componentTag})}if(e.onAttrChange||e.effects){t.reactive.push(e);const a=$e(e);if(a===null)t.reactiveWildcard.push(e);else for(const l of a)t.byReactive.has(l)||t.byReactive.set(l,[]),t.byReactive.get(l).push(e)}e.persist&&t.persist.push(e)}function ne(e,t,n,a){for(let l=0;l<e.length;l++){const i=e[l];if(!t[i.attribute])continue;const r=i.effects&&i.effects[n];r?r(t,n,a):i.onAttrChange&&(!i.declared||i.declared.has(n))&&i.onAttrChange(t,n,a)}}function Le(e){const t=e.attributeName,n=t.indexOf("data-ln-")===0,a=ee(),l=a.byAttr.get(t),i=j()&&a.byDeclaredAttr&&a.byDeclaredAttr.has(t);if(!n&&!l&&!i)return;const r=e.target;if(e.oldValue!==r.getAttribute(t)){if(i&&S(r)){const d=a.byDeclaredAttr.get(t),o=r.getAttribute(t);for(let s=0;s<d.length;s++)K(d[s].spec,o,t,d[s].componentTag,r)}if(window.lnCore._debugSink&&(n||l)&&window.lnCore._debugSink("attr",t,r,{oldValue:e.oldValue,newValue:r.getAttribute(t)}),n){const d=a.byReactive.get(t);d&&ne(d,r,t,e.oldValue),a.reactiveWildcard.length&&ne(a.reactiveWildcard,r,t,e.oldValue)}if(l)for(let d=0;d<l.length;d++){const o=l[d];if(o.handler){o.handler(r,t,e.oldValue);continue}o.onAttributeChange&&r[o.attribute]?o.onAttributeChange(r,t):(X(r,o.selector,o.attribute,o.ComponentFn),o.onInit&&o.onInit(r))}}}function ae(){window.lnCore=window.lnCore||{},!window.lnCore._attrObserverBound&&(window.lnCore._attrObserverBound=!0,h(function(){new MutationObserver(function(t){for(let n=0;n<t.length;n++)try{Le(t[n])}catch(a){console.error("[ln-core] mutation handler failed",t[n].target,a)}}).observe(document.body,{attributes:!0,subtree:!0,attributeOldValue:!0})},"ln-core"))}function D(){return window.lnCore=window.lnCore||{},window.lnCore._lifecycleRegistry=window.lnCore._lifecycleRegistry||[]}function E(){return window.lnCore=window.lnCore||{},window.lnCore._subtreeRegistry=window.lnCore._subtreeRegistry||[]}function q(e,t){if(!document.contains(e))if(t.attribute){const n=e[t.attribute];if(n&&typeof n.destroy=="function")try{n.destroy()}catch(a){console.error("["+t.attribute+"] destroy failed",e,a)}delete e[t.attribute]}else t.onDestroy&&t.onDestroy(e)}function oe(e){const t=D();if(!t.length)return;const n=e.target;if(n){const l=n.nodeType===1?n:n.parentElement;if(l&&(l.isContentEditable||l.closest&&l.closest('[contenteditable]:not([contenteditable="false"])')))return}const a=E();if(e.target&&a.length)for(let l=0;l<a.length;l++){const i=a[l],r=i.query,d=e.target.nodeType===1?e.target.matches&&e.target.matches(r)?e.target:e.target.closest?e.target.closest(r):null:e.target.parentElement&&e.target.parentElement.closest?e.target.parentElement.closest(r):null;d&&i.onSubtreeChange(d,e)}for(let l=0;l<e.addedNodes.length;l++){const i=e.addedNodes[l];if(i.nodeType===1){const r=!!(i.firstElementChild||i.children&&i.children.length);for(let d=0;d<t.length;d++){const o=t[d];if(o.selector&&o.attribute&&o.ComponentFn){if(!r)i.matches&&i.matches(o.query)&&b(i,o);else if(i.matches&&i.matches(o.query)&&b(i,o),i.querySelectorAll){const s=i.querySelectorAll(o.query);for(let c=0;c<s.length;c++)b(s[c],o)}}o.onInit&&o.onInit(i)}}}for(let l=0;l<e.removedNodes.length;l++){const i=e.removedNodes[l];if(i.nodeType===1){if(document.contains(i))continue;const r=!!(i.firstElementChild||i.children&&i.children.length);for(let d=0;d<t.length;d++){const o=t[d],s=o.query;if(s){if(!r)i.matches&&i.matches(s)&&q(i,o);else if(i.matches&&i.matches(s)&&q(i,o),i.querySelectorAll){const c=i.querySelectorAll(s);for(let u=0;u<c.length;u++)q(c[u],o)}}}}}}function re(){window.lnCore=window.lnCore||{},!window.lnCore._lifecycleObserverBound&&(window.lnCore._lifecycleObserverBound=!0,h(function(){const e=new MutationObserver(function(t){for(let n=0;n<t.length;n++){const a=t[n];if(a.type==="childList")try{oe(a)}catch(l){console.error("[ln-core] lifecycle handler failed",a.target,l)}}});window.lnCore._lifecycleObserver=e,e.observe(document.body,{childList:!0,subtree:!0})},"ln-core"))}function Oe(e){if(typeof window>"u")return e();window.lnCore=window.lnCore||{};const t=window.lnCore._lifecycleObserver;if(!t)return e();const n=t.takeRecords();for(let a=0;a<n.length;a++){const l=n[a];if(l.type==="childList")try{oe(l)}catch(i){console.error("[ln-core] lifecycle handler failed",l.target,i)}}t.disconnect();try{return e()}finally{t.observe(document.body,{childList:!0,subtree:!0})}}function Te(e,t){te({observed:e,handler:t}),ae()}function Re(e){D().push(e),e.onSubtreeChange&&e.query&&E().push(e),re()}function le(e,t,n,a,l={}){const i=l.extraAttributes||[],r=l.onAttributeChange||null,d=l.onSubtreeChange||null,o=l.onInit||null,s=l.onAttrChange||null,c=l.effects||null,u=l.attributes||null,f=u?Ie(u):c,O=u?new Set(Object.keys(u)):null,ct=l.persist||null;function v(R){const w=R||document.body;if(X(w,e,t,n),u&&j())for(const y in u){const ft=u[y],F=Array.from(w.querySelectorAll("["+y+"]"));w.matches&&w.matches("["+y+"]")&&F.push(w);for(let M=0;M<F.length;M++){const N=F[M];S(N)&&K(ft,N.getAttribute(y),y,a,N)}}o&&o(w)}const T=[];if(e.indexOf("[")!==-1){const R=/\[([\w-]+)/g;let w;for(;(w=R.exec(e))!==null;)T.push(w[1])}else T.push(e);te({selector:e,attribute:t,componentTag:a,attributes:u,ComponentFn:n,onInit:o,observed:T.concat(i),onAttributeChange:r,onAttrChange:s,effects:f,declared:O,persist:ct}),ae();const ut=e.indexOf("[")!==-1||e.indexOf(".")!==-1||e.indexOf("#")!==-1,ue=l.subtreeQuery||(ut?e:"["+e+"]"),fe={selector:e,attribute:t,ComponentFn:n,onInit:o,onSubtreeChange:d,query:ue};D().push(fe),d&&ue&&E().push(fe),re(),window[t]=v,typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.registerComponent=le,window.lnCore.observeLifecycle=Re,window.lnCore.withoutLifecycle=Oe);function we(){Y()>0?Z(function(){v(document.body)}):v(document.body)}return document.readyState==="loading"?document.addEventListener("DOMContentLoaded",we):we(),v}function ie(e){return(e||"").replace(/^#/,"")}function I(e){const t=e===void 0?location.hash:e,n={},a=ie(t);if(!a)return n;const l=a.split("&");for(let i=0;i<l.length;i++){const r=l[i];if(!r)continue;const d=r.indexOf(":"),o=d>-1?r.slice(0,d):r,s=d>-1?r.slice(d+1):"";if(o)try{n[o]=decodeURIComponent(s)}catch{n[o]=s}}return n}function Fe(e){if(!e)return null;const t=I();return e in t?t[e]:null}function Me(e,t){if(!e)return;const n=I();t==null?delete n[e]:n[e]=String(t);const l=Object.keys(n).map(function(i){const r=n[i];return r===""?i:i+":"+encodeURIComponent(r)}).join("&");ie(location.hash)!==l&&(location.hash=l)}function Ne(e){return e.button===1||e.ctrlKey||e.metaKey||e.shiftKey?!1:(e.preventDefault(),!0)}function je(e,t){if(!e||!e.hasAttribute("data-ln-hash"))return null;const n=e.getAttribute("data-ln-hash");if(n&&n.trim()!=="")return n.trim();const a=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return a?t?a+"-"+t:a:t||null}function Be(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function We(e){return!e||typeof e!="string"?null:e.endsWith(".asc")?{fieldOrColumn:e.slice(0,-4),direction:"asc"}:e.endsWith(".desc")?{fieldOrColumn:e.slice(0,-5),direction:"desc"}:null}function Ue(e,t){return!e||!Array.isArray(t)||t.length===0?null:e+":"+t.map(encodeURIComponent).join(",")}function Ve(e){if(!e||typeof e!="string")return null;const t=e.indexOf(":");if(t===-1)return null;const n=e.slice(0,t),a=e.slice(t+1),l=a?a.split(",").map(function(i){try{return decodeURIComponent(i)}catch{return i}}).filter(Boolean):[];return{key:n,values:l}}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.hashParse=I,window.lnCore.hashGet=Fe,window.lnCore.hashSet=Me,window.lnCore.hashLinkClick=Ne,window.lnCore.resolveHashNamespace=je,window.lnCore.hashSortEncode=Be,window.lnCore.hashSortDecode=We,window.lnCore.hashFilterEncode=Ue,window.lnCore.hashFilterDecode=Ve);function He(e){return(e||"").replace(/^\?/,"")}function ze(e){const t=e===void 0?typeof window<"u"?window.location.search:"":e,n={},a=He(t);if(!a)return n;const l=new URLSearchParams(a);for(const[i,r]of l.entries())n[i]=r;return n}function Ge(e){if(!e||typeof window>"u")return null;const t=new URLSearchParams(window.location.search);return t.has(e)?t.get(e):null}function Qe(e,t){if(!e||typeof window>"u")return;const n=new URL(window.location.href);if(t==null||t===""?n.searchParams.delete(e):n.searchParams.set(e,String(t)),n.search===window.location.search)return;const a=n.pathname+n.search+n.hash;window.history.replaceState(window.history.state,"",a)}function Pe(e,t){if(!e||!e.hasAttribute("data-ln-query"))return null;const n=e.getAttribute("data-ln-query");if(n&&n.trim()!=="")return n.trim();const a=e.getAttribute("data-ln-sort")||e.getAttribute("data-ln-search-for")||e.getAttribute("data-ln-search")||e.getAttribute("data-ln-filter")||e.id;return a?t?a+"_"+t:a:t||null}function Je(e,t){return!t||t==="none"||e===null||e===void 0?null:String(e)+"."+t}function Ke(e,t){if(e&&typeof e=="string"){if(e.endsWith(".asc"))return{fieldOrColumn:e.slice(0,-4),direction:"asc"};if(e.endsWith(".desc"))return{fieldOrColumn:e.slice(0,-5),direction:"desc"}}if(t&&typeof t=="object"){const n=t.sort_field||t.sort_by;if(n){const a=t.sort_dir&&String(t.sort_dir).toLowerCase()==="desc"?"desc":"asc";return{fieldOrColumn:n,direction:a}}}return null}function Xe(e){return!Array.isArray(e)||e.length===0?null:e.map(encodeURIComponent).join(",")}function Ye(e){return!e||typeof e!="string"?[]:e.split(",").map(function(t){try{return decodeURIComponent(t.trim())}catch{return t.trim()}}).filter(Boolean)}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.queryParse=ze,window.lnCore.queryGet=Ge,window.lnCore.querySet=Qe,window.lnCore.resolveQueryParam=Pe,window.lnCore.querySortEncode=Je,window.lnCore.querySortDecode=Ke,window.lnCore.queryFilterEncode=Xe,window.lnCore.queryFilterDecode=Ye);function Ze(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}typeof window<"u"&&(window.lnCore=window.lnCore||{},window.lnCore.uuid=Ze);const $=new Set(["data-ln-accordion","data-ln-ajax","data-ln-api-base-url","data-ln-api-connector","data-ln-api-connector-query-debounce","data-ln-api-endpoint","data-ln-api-headers","data-ln-api-param-limit","data-ln-api-param-offset","data-ln-api-param-search","data-ln-api-param-sort-dir","data-ln-api-param-sort-field","data-ln-api-path","data-ln-api-queue","data-ln-api-queue-online","data-ln-attr","data-ln-autoresize","data-ln-autosave","data-ln-autosave-clear","data-ln-autosave-debounce-input","data-ln-autosave-exclude","data-ln-chart","data-ln-chart-area","data-ln-chart-count","data-ln-chart-empty","data-ln-chart-labels","data-ln-chart-line","data-ln-chart-max","data-ln-chart-min","data-ln-chart-padding","data-ln-chart-plot","data-ln-chart-sort","data-ln-chart-source","data-ln-chart-type","data-ln-chart-x","data-ln-chart-y","data-ln-chart-zero","data-ln-circular-progress","data-ln-circular-progress-label","data-ln-circular-progress-max","data-ln-class","data-ln-col","data-ln-confirm","data-ln-confirm-active","data-ln-confirm-announcer","data-ln-confirm-idle","data-ln-confirm-state","data-ln-confirm-timeout","data-ln-connector","data-ln-couchdb-auth","data-ln-couchdb-connector","data-ln-couchdb-db","data-ln-couchdb-headers","data-ln-couchdb-url","data-ln-data-coordinator","data-ln-data-coordinator-connector","data-ln-data-coordinator-filters","data-ln-data-coordinator-mapper","data-ln-data-coordinator-no-autosync","data-ln-data-coordinator-scope","data-ln-data-coordinator-search","data-ln-data-coordinator-sort-direction","data-ln-data-coordinator-sort-field","data-ln-data-coordinator-stale","data-ln-data-store","data-ln-data-store-frozen","data-ln-data-store-indexes","data-ln-data-store-no-autosync","data-ln-data-store-no-local-query","data-ln-data-store-search-fields","data-ln-data-store-seed","data-ln-data-store-stale","data-ln-data-store-window","data-ln-data-store-window-page","data-ln-date","data-ln-date-dict","data-ln-date-dict-key","data-ln-date-field","data-ln-date-format","data-ln-date-label","data-ln-date-locale","data-ln-debug","data-ln-dropdown","data-ln-dropdown-menu","data-ln-dropdown-placement","data-ln-dropdown-position","data-ln-editor","data-ln-editor-action","data-ln-editor-source","data-ln-empty","data-ln-empty-state","data-ln-empty-when","data-ln-error","data-ln-external-link","data-ln-field","data-ln-fill-as","data-ln-fill-form","data-ln-fill-id","data-ln-fillable","data-ln-filter","data-ln-filter-col","data-ln-filter-hide","data-ln-filter-key","data-ln-filter-options","data-ln-filter-reset","data-ln-filter-search","data-ln-filter-target","data-ln-filter-value","data-ln-filter-values","data-ln-form","data-ln-form-action-edit","data-ln-form-action-method","data-ln-hash","data-ln-include","data-ln-initial-value","data-ln-item","data-ln-item-action","data-ln-item-id","data-ln-item-select","data-ln-key","data-ln-key-allow-input","data-ln-key-for","data-ln-key-modifier","data-ln-key-target","data-ln-link","data-ln-list","data-ln-list-body","data-ln-list-count","data-ln-list-empty","data-ln-list-field","data-ln-list-filtered","data-ln-list-select-all","data-ln-list-selectable","data-ln-list-selected","data-ln-list-source","data-ln-list-total","data-ln-list-window","data-ln-list-window-page","data-ln-list-window-threshold","data-ln-modal","data-ln-modal-close","data-ln-modal-for","data-ln-modal-mode","data-ln-modal-when","data-ln-nav","data-ln-nav-exact","data-ln-number","data-ln-number-decimals","data-ln-number-max","data-ln-number-min","data-ln-obfuscator","data-ln-obfuscator-codec","data-ln-obfuscator-key","data-ln-options","data-ln-options-label","data-ln-options-value","data-ln-outlet","data-ln-panel","data-ln-persist","data-ln-persist-scope","data-ln-picklist","data-ln-picklist-list","data-ln-picklist-max","data-ln-popover","data-ln-popover-for","data-ln-popover-placement","data-ln-popover-position","data-ln-progress","data-ln-progress-max","data-ln-query","data-ln-render-key","data-ln-route","data-ln-route-keep","data-ln-route-target","data-ln-route-title","data-ln-router-base","data-ln-router-hydrate","data-ln-scroll","data-ln-scroll-behavior","data-ln-scroll-block","data-ln-scroll-delay","data-ln-scroll-focus","data-ln-scroll-set","data-ln-scroll-update-hash","data-ln-search","data-ln-search-clear","data-ln-search-clear-for","data-ln-search-exclude","data-ln-search-fields","data-ln-search-for","data-ln-search-hide","data-ln-search-items","data-ln-show","data-ln-slug-from","data-ln-sort","data-ln-sort-dir","data-ln-sort-exclude","data-ln-sort-field","data-ln-sort-icon","data-ln-sort-items","data-ln-sort-state","data-ln-sortable","data-ln-sortable-handle","data-ln-stat","data-ln-stat-card","data-ln-stat-filter","data-ln-stat-label","data-ln-stat-trend","data-ln-stat-value","data-ln-step","data-ln-step-label","data-ln-stepper","data-ln-store","data-ln-tab","data-ln-table","data-ln-table-body","data-ln-table-cell-attr","data-ln-table-clear","data-ln-table-clear-all","data-ln-table-col","data-ln-table-col-filter","data-ln-table-col-select","data-ln-table-col-sort","data-ln-table-coordinator","data-ln-table-dict","data-ln-table-empty","data-ln-table-empty-when","data-ln-table-filter-col","data-ln-table-filtered","data-ln-table-loading","data-ln-table-row","data-ln-table-row-action","data-ln-table-row-id","data-ln-table-row-select","data-ln-table-select-all-label","data-ln-table-selectable","data-ln-table-selected","data-ln-table-sort","data-ln-table-source","data-ln-table-total","data-ln-table-window","data-ln-tabs","data-ln-tabs-active","data-ln-tabs-default","data-ln-tabs-focus","data-ln-tabs-key","data-ln-template","data-ln-time","data-ln-time-locale","data-ln-toast","data-ln-toast-close","data-ln-toast-item","data-ln-toast-max","data-ln-toast-timeout","data-ln-toast-when","data-ln-toggle","data-ln-toggle-action","data-ln-toggle-for","data-ln-tooltip","data-ln-tooltip-enhance","data-ln-tooltip-enhanced","data-ln-tooltip-placement","data-ln-tooltip-position","data-ln-translatable","data-ln-translatable-lang","data-ln-translations","data-ln-translations-active","data-ln-translations-add","data-ln-translations-default","data-ln-translations-lang","data-ln-translations-locales","data-ln-translations-placeholder","data-ln-translations-prefix","data-ln-translations-remove-label","data-ln-ui-coordinator","data-ln-upload","data-ln-upload-accept","data-ln-upload-action","data-ln-upload-delete","data-ln-upload-dict","data-ln-upload-ext","data-ln-upload-file-field","data-ln-upload-id","data-ln-upload-ids-field","data-ln-upload-item","data-ln-upload-list","data-ln-upload-local-id","data-ln-upload-max-files","data-ln-upload-max-size","data-ln-upload-progress","data-ln-upload-size","data-ln-upload-state","data-ln-upload-zone","data-ln-validate","data-ln-validate-error","data-ln-validate-errors","data-ln-value","data-ln-websocket-connector","data-ln-websocket-connector-url"]);function et(e,t){if(e===t)return 0;if(!e.length)return t.length;if(!t.length)return e.length;const n=[];for(let a=0;a<=t.length;a++)n[a]=[a];for(let a=0;a<=e.length;a++)n[0][a]=a;for(let a=1;a<=t.length;a++)for(let l=1;l<=e.length;l++)t.charAt(a-1)===e.charAt(l-1)?n[a][l]=n[a-1][l-1]:n[a][l]=Math.min(n[a-1][l-1]+1,n[a][l-1]+1,n[a-1][l]+1);return n[t.length][e.length]}function tt(e,t=$){if(t.has(e))return null;let n=null,a=1/0;for(const i of t){const r=et(e,i);r<a&&(a=r,n=i)}const l=Math.max(3,Math.floor(e.length*.4));return a<=l?n:null}function de(e){return typeof CSS<"u"&&CSS.escape?CSS.escape(e):e.replace(/([!"#$%&'()*+,.\/:;<=>?@[\\\]^`{|}~])/g,"\\$1")}function nt(e=document){const t=e.ownerDocument||e,n=e.nodeType===9?e.body||e.documentElement:e;if(!n)return[];const a=[],l=[n,...n.querySelectorAll("*")];for(let i=0;i<l.length;i++){const r=l[i];if(r.attributes)for(let d=0;d<r.attributes.length;d++){const o=r.attributes[d];if(o.name.startsWith("data-ln-")&&o.name.endsWith("-for")){const s=(o.value||"").trim();if(!s){a.push({type:"id-empty",element:r,attribute:o.name,targetId:"",message:`[ln-debug] Empty ID reference in <${r.tagName.toLowerCase()} ${o.name}="">.`});continue}t.getElementById(s)||t.querySelector("#"+de(s))||a.push({type:"id-unresolved",element:r,attribute:o.name,targetId:s,message:`[ln-debug] Unresolved ID reference: <${r.tagName.toLowerCase()} ${o.name}="${s}"> targets "#${s}", but no element with id="${s}" exists in the document.`})}}}return a}function at(e=document){const t=e.ownerDocument||e,n=e.nodeType===9?e.body||e.documentElement:e;if(!n)return[];const a=[],l=[n,...n.querySelectorAll("*")];for(let i=0;i<l.length;i++){const r=l[i];if(r.attributes)for(let d=0;d<r.attributes.length;d++){const o=r.attributes[d];if(o.name.startsWith("data-ln-")&&(o.name.endsWith("-source")||o.name.endsWith("-store"))&&o.name!=="data-ln-data-store"){const c=(o.value||"").trim();if(!c){a.push({type:"store-empty",element:r,attribute:o.name,storeName:"",message:`[ln-debug] Empty store reference in <${r.tagName.toLowerCase()} ${o.name}="">.`});continue}const u=de(c),f=t.querySelector(`[data-ln-data-store="${u}"], [data-ln-store="${u}"]`),O=typeof window<"u"&&window.lnDataStore&&typeof window.lnDataStore.getStore=="function"&&window.lnDataStore.getStore(c);!f&&!O&&a.push({type:"store-unresolved",element:r,attribute:o.name,storeName:c,message:`[ln-debug] Unresolved store reference: <${r.tagName.toLowerCase()} ${o.name}="${c}"> targets store "${c}", but no [data-ln-data-store="${c}"] exists in the document.`})}}}return a}function ot(e=document){e.ownerDocument;const t=e.nodeType===9?e.body||e.documentElement:e;if(!t)return[];const n=[],a=Array.from(t.querySelectorAll("[data-ln-data-store]"));t.hasAttribute&&t.hasAttribute("data-ln-data-store")&&a.unshift(t);const l=new Map;for(let i=0;i<a.length;i++){const r=a[i],d=(r.getAttribute("data-ln-data-store")||"").trim();d&&(l.has(d)||l.set(d,[]),l.get(d).push(r))}for(const[i,r]of l.entries())r.length>1&&n.push({type:"store-duplicate",storeName:i,elements:r,message:`[ln-debug] Duplicate store name: Multiple elements declare data-ln-data-store="${i}". Store names must be unique across the document.`});return n}function rt(e=document,t=$){const n=e.nodeType===9?e.body||e.documentElement:e;if(!n)return[];const a=[],l=[n,...n.querySelectorAll("*")];for(let i=0;i<l.length;i++){const r=l[i];if(r.attributes)for(let d=0;d<r.attributes.length;d++){const o=r.attributes[d];if(o.name.startsWith("data-ln-")&&!t.has(o.name)){const s=tt(o.name,t),c=s?` Did you mean "${s}"?`:"";a.push({type:"attribute-unknown",element:r,attribute:o.name,suggestion:s,message:`[ln-debug] Unknown attribute "${o.name}" on <${r.tagName.toLowerCase()}>.${c}`})}}}return a}function A(e=typeof document<"u"?document:null,t={}){if(!e)return{idIssues:[],storeIssues:[],uniquenessIssues:[],spellingIssues:[],total:0};const n=t.validAttributes||$,a=nt(e),l=at(e),i=ot(e),r=rt(e,n),d=[...a,...l,...i,...r];if(!t.silent)for(let o=0;o<d.length;o++)console.warn(d[o].message);return{idIssues:a,storeIssues:l,uniquenessIssues:i,spellingIssues:r,total:d.length}}let m=null;function g(e=typeof document<"u"?document:null,t=50,n=null){if(!e)return;m&&(clearTimeout(m),m=null);function a(){m=setTimeout(()=>{m=null;const l=A(e);n&&n(l)},t)}Y()>0?Z(a):a()}function lt(e,t,n,a){e==="event"?(console.groupCollapsed("[ln-debug] event",t),console.log("target",n),console.log("detail",a),console.groupEnd()):e==="attr"&&(console.groupCollapsed("[ln-debug] attr",t),console.log("target",n),console.log("old → new",a.oldValue,"→",a.newValue),console.groupEnd())}let p=[];function it(){p=Array.from(document.body.querySelectorAll("[data-ln-debug]")),document.body.hasAttribute("data-ln-debug")&&p.push(document.body)}function se(e){if(e===window||e===document)return p.indexOf(document.body)!==-1;for(let t=0;t<p.length;t++)if(p[t].contains(e))return!0;return!1}function dt(e,t,n,a){se(n)&&lt(e,t,n,a)}function L(){it(),pe(p.length>0?dt:null,p.length>0?se:null)}function ce(){L()}function st(){typeof window>"u"||(window.lnCore=window.lnCore||{},!window.lnCore._debugGateBound&&(window.lnCore._debugGateBound=!0,h(function(){L(),Te(["data-ln-debug"],L)},"ln-debug")))}return(function(){const e="data-ln-debug",t="lnDebug";if(typeof window<"u"&&window[t]!==void 0)return;const n={"data-ln-debug":{type:"marker",description:"Enables developer diagnostics overlay, live validation badges, and inspection logging"}};st();function a(i){return this.dom=i,g(i.ownerDocument||document),ce(),this}a.prototype.verify=function(i,r){return A(i||(this.dom?this.dom.ownerDocument||this.dom:document),r)},a.prototype.destroy=function(){delete this.dom[t],ce()};const l=le(e,t,a,"ln-debug",{attributes:n,onInit:function(i){typeof document<"u"&&g(i&&i.ownerDocument?i.ownerDocument:document)},onSubtreeChange:function(i){typeof document<"u"&&g(i&&i.ownerDocument?i.ownerDocument:document)}});l.verify=function(i,r){return A(i||document,r)},l.schedule=function(i,r,d){return g(i||document,r,d)}})(),C.scheduleVerification=g,C.verifyDOM=A,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"}),C})({});
@@ -70,6 +70,7 @@ export const VALID_ATTRIBUTES = new Set([
70
70
  'data-ln-data-store-no-autosync',
71
71
  'data-ln-data-store-no-local-query',
72
72
  'data-ln-data-store-search-fields',
73
+ 'data-ln-data-store-seed',
73
74
  'data-ln-data-store-stale',
74
75
  'data-ln-data-store-window',
75
76
  'data-ln-data-store-window-page',
@@ -223,12 +224,12 @@ export const VALID_ATTRIBUTES = new Set([
223
224
  'data-ln-table-col-select',
224
225
  'data-ln-table-col-sort',
225
226
  'data-ln-table-coordinator',
226
- 'data-ln-table-count',
227
227
  'data-ln-table-dict',
228
228
  'data-ln-table-empty',
229
229
  'data-ln-table-empty-when',
230
230
  'data-ln-table-filter-col',
231
231
  'data-ln-table-filtered',
232
+ 'data-ln-table-loading',
232
233
  'data-ln-table-row',
233
234
  'data-ln-table-row-action',
234
235
  'data-ln-table-row-id',
@@ -240,8 +241,6 @@ export const VALID_ATTRIBUTES = new Set([
240
241
  'data-ln-table-source',
241
242
  'data-ln-table-total',
242
243
  'data-ln-table-window',
243
- 'data-ln-table-window-page',
244
- 'data-ln-table-window-threshold',
245
244
  'data-ln-tabs',
246
245
  'data-ln-tabs-active',
247
246
  'data-ln-tabs-default',
@@ -9,9 +9,13 @@
9
9
 
10
10
  ## 🧭 Philosophical Modes
11
11
 
12
- 1. **Server-Rendered (SSR) Mode**:
12
+ 1. **Server-Rendered (SSR) Seed Mode (0ms Boot Lag)**:
13
+ Instead of generating thousands of heavy `<tr><td>` elements on the server (which freezes browser HTML parsers), the server embeds an authoritative JSON array inside `<script type="application/json">` (or pairs with a seeded `ln-data-store`). `ln-table` ingests this dataset instantly with zero network requests.
14
+ 2. **Cheetah / Glide Style DOM Row Recycling Pool (60 FPS Virtualization)**:
15
+ Instead of destroying and recreating DOM rows on scroll (`innerHTML` or `replaceChildren`), `ln-table` allocates a fixed pool of ~30-40 `<tr>` elements and updates values in-place via pre-compiled binding descriptors. Zero Garbage Collection pauses, constant memory, and fluid 60 FPS scrolling even with 50,000+ records.
16
+ 3. **Legacy Server-Rendered (SSR) Markup Mode**:
13
17
  Hydrates standard, backend-printed HTML tables in-place. Reads the existing `<tbody>` rows once on load and layers sorting, filtering, text searches, and scroll virtualization on top of pre-rendered markup.
14
- 2. **Data-Driven Mode**:
18
+ 4. **Data-Driven Mode**:
15
19
  Operates as a dynamic presenter engine. Clones templates, interpolates double-curly braces (`{{ field }}`), manages checkbox selection lists, updates footers, and coordinates dataset requests via AJAX coordinators.
16
20
 
17
21
  ---
@@ -72,6 +76,14 @@ External UI controls (`ln-search`, `ln-filter`, filter header buttons, clear but
72
76
  <tbody data-ln-table-body></tbody>
73
77
  </table>
74
78
 
79
+ <!-- Initial Loading State Template -->
80
+ <template data-ln-template="products-loading">
81
+ <article data-ln-empty-state="loading">
82
+ <svg class="ln-icon ln-ajax-spinner" aria-hidden="true"><use href="#ln-icon-loader-2"></use></svg>
83
+ <p>Loading products...</p>
84
+ </article>
85
+ </template>
86
+
75
87
  <!-- Row Template -->
76
88
  <template data-ln-template="products-row">
77
89
  <tr data-ln-table-row>
@@ -79,7 +91,70 @@ External UI controls (`ln-search`, `ln-filter`, filter header buttons, clear but
79
91
  <td>{{ category }}</td>
80
92
  </tr>
81
93
  </template>
94
+
95
+ <footer>
96
+ <span>Showing <span data-ln-table-filtered>0</span> of <strong data-ln-table-total>0</strong> products</span>
97
+ <!-- Background Loading Indicator (hidden by default, displayed during re-fetching) -->
98
+ <div data-ln-table-loading class="table-loading hidden" aria-hidden="true">
99
+ <svg class="ln-icon ln-ajax-spinner"><use href="#ln-icon-loader-2"></use></svg>
100
+ </div>
101
+ </footer>
82
102
  </section>
103
+
104
+ ### 3. Injected JSON Seed Mode (0ms Network, Recycled DOM Row Pool)
105
+ ```html
106
+ <section data-ln-table-coordinator>
107
+ <ul data-ln-data-coordinator="seed-docs" id="seed-table-coordinator" hidden>
108
+ <li data-ln-data-store="seed-docs"
109
+ data-ln-data-store-seed="seed-docs-data"
110
+ data-ln-data-store-indexes="department,status,priority"
111
+ data-ln-data-store-search-fields="title,department,owner,status,priority"
112
+ id="seed-docs"></li>
113
+ </ul>
114
+
115
+ <!-- Injected JSON Dataset (e.g. 10,000 records) -->
116
+ <script type="application/json" id="seed-docs-data">
117
+ [
118
+ { "id": 1, "title": "Security Policy", "department": "IT", "status": "Approved", "owner": "Alice", "file_size": 11112, "file_size_display": "10.9 KB", "updated_at": 1776339624, "updated_display": "2026-04-16" }
119
+ ]
120
+ </script>
121
+
122
+ <!-- Table Viewport with Recycled DOM Row Pool -->
123
+ <section data-ln-table="seed-docs"
124
+ data-ln-table-source="seed-docs"
125
+ data-ln-table-selectable
126
+ id="seed-table"
127
+ class="data-table-demo"
128
+ style="max-height: 540px; overflow-y: auto;">
129
+ <table>
130
+ <thead>
131
+ <tr>
132
+ <th data-ln-table-col-select style="width: 40px;"></th>
133
+ <th data-ln-table-col="title">Title</th>
134
+ <th data-ln-table-col="department">Department</th>
135
+ </tr>
136
+ </thead>
137
+ <tbody data-ln-table-body></tbody>
138
+ </table>
139
+
140
+ <footer class="ln-table__footer">
141
+ <p>
142
+ <span class="hidden"><span data-ln-table-filtered></span> / </span>
143
+ <span data-ln-table-total data-ln-number></span> items
144
+ </p>
145
+ </footer>
146
+
147
+ <!-- Row Template Cloned Once for the Pool (~38 rows) -->
148
+ <template data-ln-template="seed-docs-row" data-ln-table-row>
149
+ <tr data-ln-table-row data-ln-table-row-id="{{ id }}">
150
+ <td><input type="checkbox" data-ln-table-row-select></td>
151
+ <td><strong>{{ title }}</strong></td>
152
+ <td>{{ department }}</td>
153
+ </tr>
154
+ </template>
155
+ </section>
156
+ </section>
157
+ ```
83
158
  ```
84
159
 
85
160
  > Row templates support `{{ field }}` (text) and
@@ -94,9 +169,8 @@ External UI controls (`ln-search`, `ln-filter`, filter header buttons, clear but
94
169
  | Attribute | Elements | Description |
95
170
  | :--- | :--- | :--- |
96
171
  | `data-ln-table` | Root wrapper | Component identifier. Target must carry a unique `id`. |
97
- | `data-ln-table-source` | Root wrapper | Opt-in indicator for Data-Driven Mode. |
172
+ | `data-ln-table-source` | Root wrapper | Opt-in indicator for Data-Driven Mode (maps to `ln-data-store` ID). |
98
173
  | `data-ln-table-selectable` | Root wrapper | Enables checkbox-based row selections. |
99
- | `data-ln-table-window="N"` | Root wrapper | Opt-in server-side sliding-window virtualization. `N` sets the resident-row cap (default 1000). Requires Data-Driven Mode. Observable: add/remove toggles windowed mode ON/OFF live; changing `N` while windowed reconfigures the live cache. |
100
174
  | ~~`data-ln-table-search`~~ | — | **Removed.** Drive the search input with `data-ln-search-for="<tableId>"` — `ln-table` consumes `ln-search:change` directly in SSR mode only; data-driven mode relies on `ln-table-coordinator` to translate it into `ln-table:set-search`. |
101
175
  | `data-ln-table-col="field"` | `<th>` | Maps column header to data object field keys. |
102
176
  | `data-ln-value` | `<td>` | Raw machine value behind a formatted cell — sorting/filtering operate on this, not the displayed text. Read via `ln-core.readValue`. |
@@ -106,6 +180,7 @@ External UI controls (`ln-search`, `ln-filter`, filter header buttons, clear but
106
180
  | `data-ln-table-row` | `<tr>` | Target row container in row templates. |
107
181
  | `data-ln-table-row-select` | `<input>` | Selection checkbox in row templates. |
108
182
  | `data-ln-table-row-action="name"`| `<button>` | Action button trigger in row templates. |
183
+ | `data-ln-table-loading` | Indicator / Template | Loading indicator element in footer (revealed during background re-fetch) or loading state template. |
109
184
 
110
185
  ---
111
186
 
@@ -116,7 +191,7 @@ External UI controls (`ln-search`, `ln-filter`, filter header buttons, clear but
116
191
  - **`ln-table:ready`** `{ total }`
117
192
  Fired after the initial DOM rows are parsed.
118
193
  - **`ln-table:request-data`** `{ table, sort, filters, search }`
119
- Requests a fresh dataset when sort, filter, or search is changed. Windowed mode (`data-ln-table-window`) adds `{ offset, limit, queryGen }`.
194
+ Requests a fresh dataset when sort, filter, or search is changed (Data-Driven mode).
120
195
  - **`ln-table:rendered`** `{ table, total, visible }`
121
196
  Fired after a dynamic template render finishes drawing.
122
197
  - **`ln-table:row-click`** `{ table, id, record }`
@@ -129,13 +204,10 @@ External UI controls (`ln-search`, `ln-filter`, filter header buttons, clear but
129
204
  ### Received Events
130
205
 
131
206
  - **`ln-table:set-data`** `{ data, total, filtered, filterOptions }`
132
- Applies the payload array and triggers rendering. Windowed mode expects `{ offset, queryGen }` echoed back — routed straight into the internal window cache.
207
+ Applies the payload array and triggers rendering.
133
208
  - **`ln-table:set-loading`** `{ loading }`
134
209
  Toggles the visual loading dimmed state overlay.
135
- - **`ln-table:page-failed`** `{ offset }`
136
- Windowed mode: the coordinator reports the page fetch at `offset` failed. Releases it from the cache's in-flight set — no auto-retry; the next `ensure()` (scroll, filter, resize) requests it again.
137
- - **`ln-table:request-revalidate`**
138
- Windowed mode: the coordinator asks the cache to re-fetch the currently visible page after a local mutation. Stale rows stay visible until the response lands; does not jump back to page 0.
210
+
139
211
 
140
212
  ---
141
213
 
@@ -193,55 +265,32 @@ Options come from the domain (backend enum or lookup), never derived from the da
193
265
 
194
266
  ---
195
267
 
196
- ## Windowed Mode
197
-
198
- Opt-in server-side sliding-window virtualization for datasets too large to cache client-side. Add `data-ln-table-window="N"` to a Data-Driven Mode table; the component owns a bounded `ln-core.createWindowCache` instance instead of the full dataset.
268
+ ## Virtual Scrolling & Large Datasets
199
269
 
200
- ### What it does
270
+ For large datasets, `ln-table` automatically activates DOM row virtualization (`calculateVirtualWindow`) when the row count exceeds `VIRTUAL_THRESHOLD` (200 rows). It mounts top/bottom spacer elements and maintains a recycled pool of ~35–50 rows in the DOM corresponding to the active scroll viewport, providing smooth 60fps scrolling over tens of thousands of records.
201
271
 
202
- 1. Caches at most `N` rows (default 1000), LRU-evicting the least-recently-touched rows once the cap is exceeded.
203
- 2. Extends `ln-table:request-data` with `{ offset, limit, queryGen }` on every scroll pass that needs new rows.
204
- 3. Reads `{ offset, queryGen }` off `ln-table:set-data` and routes it into the window cache, dropping the response if `queryGen` no longer matches the current query.
205
- 4. Renders blank placeholder rows (no shimmer) for logical rows not yet resident.
206
- 5. Hides the select-all checkbox (D4) — per-row selection still works and survives eviction.
207
-
208
- ### Live observability
209
-
210
- `data-ln-table-window`, `data-ln-table-window-page`, `data-ln-table-window-threshold`, and `data-ln-table-count` are all observed and apply live, without re-init. Adding `data-ln-table-window` to an initialized, non-windowed, data-driven table enables windowing live — the cache seeds from resident rows, honoring `data-ln-table-count` if present. Removing it disables windowing live: the cache is destroyed and the table issues a fresh full `ln-table:request-data` (no `offset`/`limit`) to repopulate the complete dataset before rendering non-windowed again.
211
-
212
- ### What it does NOT do
213
-
214
- - Does not cache the full dataset client-side — that's the non-windowed Data-Driven path.
215
- - Does not paginate — scrolling stays continuous; `offset`/`limit` address server-side pages, not user-facing "Page 2" navigation.
216
- - Does not retry a dropped stale response — the next `ensure()` pass re-requests it under the current `queryGen`.
217
-
218
- ### Markup contract
219
-
220
- ```html
221
- <section data-ln-table="documents" data-ln-table-source="documents" data-ln-table-window="1000" id="documents-table">
222
- ...
223
- </section>
224
- ```
272
+ For remote sliding-window caching, windowing is handled at the data layer by `ln-data-store` (`data-ln-data-store-window` and `data-ln-data-store-window-page`). The table consumes the streamed records cleanly via `ln-table:set-data` without needing private table-level window caches.
225
273
 
226
274
  ---
227
275
 
228
276
  ## 🔧 Internals
229
277
 
230
- Source: `components/ln-table/ln-table.js`. Sort is a separate, co-loaded component — see `components/ln-sort/ln-sort.js`. Imports from `ln-core`: `cloneTemplateScoped`, `dispatch`, `fill`, `fillTemplate`, `registerComponent`, `createWindowCache`, `readValue`, `detectValueType`, `compareValues`.
278
+ Source: `components/ln-table/ln-table.js`. Sort is a separate, co-loaded component — see `components/ln-sort/ln-sort.js`. Imports from `ln-core`: `cloneTemplateScoped`, `dispatch`, `fill`, `fillTemplate`, `registerComponent`, `readValue`, `detectValueType`, `compareValues`.
231
279
 
232
280
  ### Mode detection & lifecycle
233
281
 
234
282
  - The constructor branches once, at construction: `this.isDataDriven = dom.hasAttribute('data-ln-table-source')`.
235
283
  - **SSR**: reads `<tbody>` rows once at bootstrap, caches them as static HTML strings in `_data`, and re-sorts/filters that in-memory cache on `ln-search:change`, `ln-sort:change`, and `ln-filter:change`.
236
284
  - **Data-driven**: `isLoaded = false` until the first `ln-table:set-data`. If `<tbody>` already has rows (hybrid), they're parsed synchronously first — instant local sort/filter/search response before the authoritative dataset arrives. When the background sync lands, `_vStart`/`_vEnd` reset to `-1` and virtual scroll re-initializes against the full dataset.
237
- - **Loading state**: `ln-table:set-loading {loading:true}` adds `.ln-table--loading` to the wrapper; `ln-table:set-data` clears it automatically.
285
+ - **Loading state**: In Data-Driven mode with no initial rows, `_showLoadingState()` immediately renders the loading state template and sets `aria-busy="true"`, preventing empty-state flash before data arrives. When `_initialLoaded = true`, subsequent `ln-table:set-loading {loading:true}` events preserve existing rows, toggle `.ln-table--loading`, and display the `[data-ln-table-loading]` footer indicator. `ln-table:set-data` clears loading state automatically.
238
286
 
239
287
  ### DOM mutations
240
288
 
241
289
  | Phase | Mutation |
242
290
  |---|---|
243
- | `set-loading` | `.ln-table--loading` on the wrapper |
244
- | `set-data` / sort / filter / search | `<tbody>` rows re-rendered (cloned templates in data-driven mode, cached HTML in SSR); footer counters (`data-ln-table-total` / `-filtered` / `-selected`) updated |
291
+ | Initial load (data-driven) | Clones loading template into `<tbody>` with `colspan`, sets `aria-busy="true"` on wrapper |
292
+ | `set-loading` (subsequent) | `.ln-table--loading` on wrapper, toggles `[data-ln-table-loading]` in footer, sets `aria-busy` |
293
+ | `set-data` / sort / filter / search | `<tbody>` rows re-rendered (cloned templates in data-driven mode, cached HTML in SSR); footer counters (`data-ln-table-total` / `-filtered` / `-selected`) updated; `[data-ln-table-loading]` hidden |
245
294
  | sort click | `data-ln-sort-state` on the `[data-ln-sort]` element, owned entirely by `ln-sort` — `ln-table` never touches it |
246
295
  | filter change | `.ln-filter-active` toggled on the column's filter button |
247
296