UNPKG

@optionfactory/ful

Version:

- Import the lib via CDN:

1 lines 56.5 kB
var ful=function(t,e){"use strict";class s{static encode(t,e){const r=e||s.URL_SAFE,i=t.byteLength,a=new Uint8Array(t);let n="";for(let t=0;t<i;t+=3){n+=r[a[t]>>2]+r[(3&a[t])<<4|a[t+1]>>4]+r[(15&a[t+1])<<2|a[t+2]>>6]+r[63&a[t+2]]}return i%3==2?n=n.substring(0,n.length-1):i%3==1&&(n=n.substring(0,n.length-2)),n}static decode(t,e){const r=e||s.URL_SAFE;let i=Math.floor(.75*t.length);for(let e=0;e!==t.length&&"="===t[t.length-e-1];++e)--i;const a=new Uint8Array(i);let n=0,l=0;for(;n<.75*t.length;){const e=r.indexOf(t.charAt(l++)),s=r.indexOf(t.charAt(l++)),i=r.indexOf(t.charAt(l++)),o=r.indexOf(t.charAt(l++));a[n++]=e<<2|s>>4,a[n++]=(15&s)<<4|i>>2,a[n++]=(3&i)<<6|o}return a.buffer}}s.STANDARD="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",s.URL_SAFE="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";class r extends Error{constructor(t,e,s){super(t,{cause:s}),this.name="Failure",this.problems=e}dropping(t){return new r(this.message,r.dropProblemsContext(this.problems,t),this)}static dropProblemsContext(t,e){return t.map(({type:t,context:s,reason:r,details:i})=>({type:t,context:s?.startsWith(e)?s.substring(e.length):s,reason:r,details:i}))}}class i{#t;#e;constructor(t,e){this.#t=t,this.#e=e}get normalized(){return`${this.#t}/${this.#e}`}get type(){return this.#t}get subtype(){return this.#e}static parse(t){if(!t)return new i("unknown","unknown");const[e,s]=t.split(";"),[r,a]=e.trim().split("/");return new i(r.toLowerCase(),a?.toLowerCase())}}class a extends r{constructor(t,e,s,r){super(t,s,r),this.name="HttpClientError",this.status=e}dropping(t){return new a(this.message,this.status,r.dropProblemsContext(this.problems,t),this)}static of(t,e){return new a(e.message,0,[{type:t,context:null,reason:e.message,details:null}],e)}static async fromResponse(t){switch(i.parse(t.headers.get("Content-Type")).normalized){case"application/failures+json":{const e=await t.json(),s=`${t.status} ${t.statusText}: ${e.length} failures`;return new a(s,t.status,e)}case"application/problem+json":{const e=await t.json(),s=`${t.status} ${t.statusText}: ${e.title} ${e.detail}`;return new a(s,t.status,e.problems||[{type:"GENERIC_PROBLEM",context:null,reason:s,details:null}])}default:{const e=await t.text(),s=`${t.status} ${t.statusText}: ${e}`;return new a(s,t.status,[{type:"GENERIC_PROBLEM",context:null,reason:s,details:null}])}}}}class n{#s;#r;constructor(){this.#s=document.querySelector("meta[name='_csrf_header']")?.getAttribute("content"),this.#r=document.querySelector("meta[name='_csrf']")?.getAttribute("content")}async intercept(t,e,s){return this.#s&&this.#r&&e.headers.set(this.#s,this.#r),await s.proceed(t,e)}}class l{#i;constructor(t){this.#i=t}async intercept(t,e,s){const r=await s.proceed(t,e);return 401===r.status&&(window.location.href=this.#i),r}}class o{#a;constructor(){this.#a=[]}withCsrfToken(){return this.#a.push(new n),this}withRedirectOnUnauthorized(t){return this.#a.push(new l(t)),this}withInterceptors(...t){return this.#a.push(...t),this}build(){return new d(this.#a)}}class u{async intercept(t,e,s){return await fetch(new Request(t,e))}}class c{#a;#n;constructor(t,e){this.#a=t,this.#n=e}async proceed(t,e){const s=this.#a[this.#n];return await s.intercept(t,e,new c(this.#a,this.#n+1))}}class d{#a;static builder(){return new o}constructor(t){this.#a=t||[]}async exchange(t,e,s){const r=[...this.#a,...s||[],new u],i=new c(r,0),a=new URL(new Request(t).url);return await i.proceed(a,e??{})}request(t,e){return p.create(this,t,e)}get(t){return p.create(this,"GET",t)}head(t){return p.create(this,"HEAD",t)}post(t){return p.create(this,"POST",t)}put(t){return p.create(this,"PUT",t)}patch(t){return p.create(this,"PATCH",t)}delete(t){return p.create(this,"DELETE",t)}}const h=async(t,e)=>{try{return await t[e]()}catch(t){throw a.of("UNMARSHALING_PROBLEM",t)}};class p{#l;#o;#u;#c;#d;#h;#p;#a;static create(t,e,s){return new p(t,e,s,new URLSearchParams,new Headers,void 0,{},[])}constructor(t,e,s,r,i,a,n,l){this.#l=t,this.#o=e,this.#u=s,this.#c=r,this.#h=a,this.#d=i,this.#p=n,this.#a=l}headers(t){for(const[e,s]of new Headers(t).entries())null==s?this.#d.delete(e):this.#d.set(e,s);return this}header(t,e){return null==e?this.#d.delete(t):this.#d.set(t,e),this}params(t){for(const[e,s]of new URLSearchParams(t).entries())null==s?this.#c.delete(e):this.#c.set(e,s);return this}param(t,...e){if(0===e.length||null===e[0]||void 0===e[0])return this.#c.delete(t),this;for(const s of e)this.#c.append(t,s);return this}body(t){return this.#h=t,this}json(t){return this.#d.set("Content-Type","application/json"),this.#h=JSON.stringify(t),this}multipart(t){const e=new FormData;return t(new f(e)),this.#h=e,this}options(t){for(const[e,s]of Object.entries(t))this.#p[e]=s;return this}option(t,e){return this.#p[t]=e,this}interceptors(t){for(const e of t)this.#a.push(e);return this}interceptor(t){return this.#a.push(t),this}async exchange(){const t=this.#c.size?`${this.#u}?${this.#c}`:this.#u,e={...this.#p,headers:this.#d,method:this.#o,body:this.#h};return await this.#l.exchange(t,e,this.#a)}async fetch(){const t=this.#c.size?`${this.#u}?${this.#c}`:this.#u,e={...this.#p,headers:this.#d,method:this.#o,body:this.#h};try{const s=await this.#l.exchange(t,e,this.#a);if(!s.ok)throw await a.fromResponse(s);return s}catch(t){if(t instanceof r)throw t;throw a.of("CONNECTION_PROBLEM",t)}}async fetchText(){const t=await this.fetch();return await h(t,"text")}async fetchJson(){const t=await this.fetch();return await h(t,"json")}async fetchBlob(){const t=await this.fetch();return await h(t,"blob")}async fetchArrayBuffer(){const t=await this.fetch();return await h(t,"arrayBuffer")}}class f{#f;constructor(t){this.#f=t}field(t,e){return this.#f.append(t,e),this}blob(t,e,s){return this.#f.append(t,e,s),this}blobs(t,e){for(let s of e)this.#f.append(t,s);return this}json(t,e,s){const r=new Blob([JSON.stringify(e)],{type:"application/json"});return this.#f.append(t,r,s),this}}class m extends Storage{static save(t,e){localStorage.setItem(t,JSON.stringify(e))}static load(t){const e=localStorage.getItem(t);return null===e?void 0:JSON.parse(e)}static remove(t){localStorage.removeItem(t)}static pop(t){const e=m.load(t);return m.remove(t),e}}class b extends Storage{static save(t,e){sessionStorage.setItem(t,JSON.stringify(e))}static load(t){const e=sessionStorage.getItem(t);return null===e?void 0:JSON.parse(e)}static remove(t){sessionStorage.removeItem(t)}static pop(t){const e=b.load(t);return b.remove(t),e}}class v{static save(t,e,s){m.save(t,{revision:e,data:s})}static load(t,e){const s=m.load(t);if(void 0!==s){if(s.revision===e)return s.data;localStorage.removeItem(t)}}}class g{static forKeycloak(t,e,s,r){return new g(t,r??"openid profile",{auth:new URL("protocol/openid-connect/auth",e),token:new URL("protocol/openid-connect/token",e),logout:new URL("protocol/openid-connect/logout",e),registration:new URL("protocol/openid-connect/registrations",e),redirect:s})}constructor(t,e,{auth:s,token:r,registration:i,logout:a,redirect:n}){this.clientId=t,this.scope=e,this.uri={auth:s,token:r,registration:i,logout:a,redirect:n}}async action(t,e){const r=s.encode(crypto.getRandomValues(new Uint8Array(32)).buffer),i=s.encode(await crypto.subtle.digest("SHA-256",(new TextEncoder).encode(r))),a=this.clientId+s.encode(crypto.getRandomValues(new Uint8Array(16)).buffer);b.save(`${g.PKCE_AND_STATE_KEY}-${this.clientId}`,{state:a,verifier:r});const n=new URL(t);n.searchParams.set("client_id",this.clientId),n.searchParams.set("redirect_uri",this.uri.redirect),n.searchParams.set("response_type","code"),n.searchParams.set("scope",this.scope),n.searchParams.set("state",a),n.searchParams.set("code_challenge",i),n.searchParams.set("code_challenge_method","S256"),Object.entries(e||{}).forEach(t=>{n.searchParams.set(t[0],t[1])}),window.location.href=n.toString()}async registration(t){await this.action(this.uri.registration,t)}async applicationInitiatedAction(t,e){await this.action(this.uri.auth,{...e,kc_action:t})}async#m(t,e){window.history.replaceState("","",this.uri.redirect);const s=b.pop(`${g.PKCE_AND_STATE_KEY}-${this.clientId}`);if(s.state!==e)throw new Error("State mismatch");const r=await fetch(this.uri.token,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams([["client_id",this.clientId],["code",t],["grant_type","authorization_code"],["code_verifier",s.verifier],["state",s.state],["redirect_uri",this.uri.redirect]])});if(!r.ok){const t=await r.text();throw new Error("Error:"+r.status+": "+t)}const i=await r.json();return new y(this.clientId,i,this.uri)}async ensureLoggedIn(){const t=new URL(window.location.href),e=t.searchParams.get("code");if(e&&b.load(`${g.PKCE_AND_STATE_KEY}-${this.clientId}`)){const s=t.searchParams.get("state");return await this.#m(e,s)}return await this.action(this.uri.auth,{}),null}}g.PKCE_AND_STATE_KEY="state-and-verifier";class y{static parseToken(t){const[e,r,i]=t.split("."),a=new TextDecoder("utf-8");return{header:JSON.parse(a.decode(s.decode(e,s.STANDARD))),payload:JSON.parse(a.decode(s.decode(r,s.STANDARD))),signature:i}}constructor(t,e,{token:s,logout:r,redirect:i}){this.clientId=t,this.token=e,this.idToken=y.parseToken(e.id_token),this.accessToken=y.parseToken(e.access_token),this.refreshToken=y.parseToken(e.refresh_token),this.uri={token:s,logout:r,redirect:i},this.refreshCallback=null}onRefresh(t){this.refreshCallback=t}async refresh(){const t=await fetch(this.uri.token,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams([["client_id",this.clientId],["grant_type","refresh_token"],["refresh_token",this.token.refresh_token]])});if(!t.ok){const e=await t.text();throw new Error("Error:"+t.status+": "+e)}const e=await t.json();this.token=e,this.idToken=y.parseToken(e.id_token),this.accessToken=y.parseToken(e.access_token),this.refreshToken=y.parseToken(e.refresh_token),this.refreshCallback&&this.refreshCallback(this.token,this.accessToken,this.refreshToken)}shouldBeRefreshed(t){const e=(new Date).getTime(),s=1e3*this.refreshToken.payload.exp;return!(e>s)&&e-t>s}async refreshIf(t){this.shouldBeRefreshed(t)&&await this.refresh()}logout(){const t=new URL(this.uri.logout);t.searchParams.set("post_logout_redirect_uri",this.uri.redirect),t.searchParams.set("id_token_hint",this.token.id_token),window.location.href=t.toString()}bearerToken(){return`Bearer ${this.token.access_token}`}interceptor(t,e){return new w(this,t,e)}}class w{#b;#v;#g;constructor(t,e,s){this.#b=t,this.#v=e||2e3,this.#g=s||3e4}async intercept(t,e,s){await this.#b.refreshIf(this.#v),e.headers.set("Authorization",this.#b.bearerToken());const r=await s.proceed(t,e);return await this.#b.refreshIf(this.#g),r}}class E{static async fireAsync(t,e){return t.dispatchEvent(e),await(e.async?.promise)}static asyncOn(t,e,s,r){const i=async t=>{let e,r;const i=new Promise((t,s)=>{e=t,r=s});t.async={promise:i};try{e(await s(t))}catch(t){r(t)}};return t.addEventListener(e,i,r),i}static asyncOff(t,e,s,r){t.removeEventListener(e,s,r)}static mixInto(...t){for(const e of t)Object.assign(e.prototype,{async fireAsync(t){return await E.fireAsync(this,t)},asyncOn(t,e,s){return E.asyncOn(this,t,e,s)},asyncOff(t,e,s){return E.asyncOff(this,t,e,s)}})}}class A{static sleep(t){return new Promise(e=>setTimeout(e,t))}static DEBOUNCE_DEFAULT=0;static DEBOUNCE_IMMEDIATE=1;static debounce(t,e,s){const r=s??A.DEBOUNCE_DEFAULT;let i=null,a=[],n=0;const l=()=>{const s=(new Date).getTime()-n;t>s?i=setTimeout(l,t-s):(i=null,r!==A.DEBOUNCE_IMMEDIATE&&e(...a),null===i&&(a=[]))};return[function(){a=[...arguments],n=(new Date).getTime(),null===i&&(i=setTimeout(l,t),r===A.DEBOUNCE_IMMEDIATE&&e(...a))},()=>clearTimeout(i)]}static THROTTLE_DEFAULT=0;static THROTTLE_NO_LEADING=1;static THROTTLE_NO_TRAILING=2;static throttle(t,e,s){const r=s??A.THROTTLE_DEFAULT;let i=null,a=[],n=0;const l=()=>{n=r&A.THROTTLE_NO_LEADING?0:(new Date).getTime(),i=null,e(...a),null===i&&(a=[])};return[function(){const s=(new Date).getTime();!n&&r&A.THROTTLE_NO_LEADING&&(n=s);const o=t-(s-n);a=[...arguments],o<=0||o>t?(null!==i&&(clearTimeout(i),i=null),n=s,e(...a),null===i&&(a=[])):null!==i||r&A.THROTTLE_NO_TRAILING||(i=setTimeout(l,o))},()=>clearTimeout(i)]}}class T{static fromAttributes(t,s,r){const i=e.registry.component("http-client"),a=t.hasAttribute("request-mapper")?e.registry.component(t.getAttribute("request-mapper")):t=>t,n=t.hasAttribute("response-mapper")?e.registry.component(t.getAttribute("response-mapper")):t=>t;return e.registry.component(t.getAttribute("loader")??s).create({el:t,http:i,requestMapper:a,responseMapper:n,options:r??{}})}}class S{static flatten(t,e,s){return Object.keys(t).reduce((r,i)=>{const a=e.length?e+"."+i:i;return s.has(a)||"object"!=typeof t[i]||null===t[i]?r[a]=t[i]:Object.assign(r,S.flatten(t[i],a,s)),r},{})}static providePath(t,e,s){const r=e.split(".").map(t=>/^[0-9]+$/.test(t)?+t:t);let i=t??{},a=null;for(let e=0;;++e){const n=r[e],l=r[e-1];if(Number.isInteger(n)&&!Array.isArray(i)&&(null!==a?a[l]=i=[]:t=i=[]),e===r.length-1)return i[n]=void 0!==s?s:n in i?i[n]:null,t;void 0===i[n]&&(i[n]={}),a=i,i=i[n]}}static extract(t){if("radio"===t.getAttribute("type")){if(!t.checked)return;return"boolean"===t.dataset.fulBindType?"true"===t.value:t.value}return"checkbox"===t.getAttribute("type")?t.checked:"boolean"===t.dataset.fulBindType?t.value?"true"===t.value:null:!("INPUT"!==t.tagName&&"SELECT"!==t.tagName||""!==t.value&&void 0!==t.value)?null:t.value}static extractFrom(t){let e={};for(const s of t.elements)s.hasAttribute("name")&&!s.matches(":disabled")&&(e=S.providePath(e,s.getAttribute("name"),S.extract(s)));return e}static mutate(t,e){"radio"!==t.getAttribute("type")?"checkbox"!==t.getAttribute("type")?t.value=e:t.checked=e:t.checked=t.getAttribute("value")===e}static mutateIn(t,e){const s=Array.from(t.elements).map(t=>t.getAttribute("name")).filter(t=>t);for(const[r,i]of Object.entries(S.flatten(e,"",new Set(s))))for(const e of t.querySelectorAll(`[name='${CSS.escape(r)}']`))S.mutate(e,i)}static errors(t,e,s){const r=e.filter(t=>"FIELD_ERROR"===t.type||"INVALID_FORMAT"===t.type),i=e.filter(t=>"FIELD_ERROR"!==t.type&&"INVALID_FORMAT"!==t.type);t.querySelectorAll("[name]").forEach(t=>t.setCustomValidity?.("")),t.querySelectorAll("ful-errors").forEach(t=>{t.replaceChildren(),t.setAttribute("hidden","")}),r.forEach(e=>{const s=e.context.replace("[",".").replace("].",".").replace("]","").split(".");for(let r=s.length;0!=r;--r){const i=s.slice(0,r).join("."),a=s.slice(r,s.length).join(".");t.querySelectorAll(`[name='${CSS.escape(i)}']`).forEach(t=>t.setCustomValidity?.(e.reason,a))}}),t.querySelectorAll("ful-errors").forEach(t=>{t.innerText=i.map(t=>t.reason).join("\n"),0!==i.length&&t.removeAttribute("hidden")}),0!=e.length&&s&&Array.from(t.querySelectorAll(":invalid")).sort((t,e)=>t.getBoundingClientRect().y-e.getBoundingClientRect().y)[0]?.focus()}}class x{#y;#w;#o;#E;#A;constructor(t,e,s,r,i){this.#y=t,this.#w=e,this.#o=s,this.#E=r,this.#A=i}prepare(t,e){return this.#E(t,e)}async submit(t,e){return await this.#y.request(this.#o,this.#w).json(t).fetch()}transform(t,e){return this.#A(t,e)}}class k{#E;#A;constructor(t,e){this.#E=t,this.#A=e}async prepare(t,e){return await this.#E(t,e)}async submit(t,e,s){return s}async transform(t,e){return await this.#A(t,e)}}class q{static create({el:t,http:e,requestMapper:s,responseMapper:r}){const i=t.getAttribute("action");if(!i)return new k(s,r);const a=t.getAttribute("method")??"POST";return new x(e,i,a,s,r)}}class L extends e.ParsedElement{form;render(){const t=this.form=document.createElement("form");t.setAttribute("novalidate",""),e.Attributes.forward("form-",this,t),t.replaceChildren(...this.childNodes),t.addEventListener("submit",async t=>{t.preventDefault(),t.stopPropagation(),await this.submit()}),this.hasAttribute("clear-invalid-on-change")&&this.addEventListener("change",t=>{t.target.setCustomValidity?.("")}),this.replaceChildren(t)}async submit(){this.spinner(!0);try{const t=T.fromAttributes(this,"loaders:form"),e=this.values;let s=await t.prepare(e,this);try{const r=new CustomEvent("submit",{bubbles:!0,cancelable:!0,detail:{values:e,request:s}});if(!this.dispatchEvent(r))return;const i=new CustomEvent("submit:requested",{bubbles:!0,cancelable:!1,detail:{values:r.detail.values,request:r.detail.request}});let a=await E.fireAsync(this,i);s=i.detail.request,a=await t.submit(s,this,a);const n=await t.transform(a,this);this.dispatchEvent(new CustomEvent("submit:success",{bubbles:!0,cancelable:!1,detail:{values:e,request:s,response:n}}))}catch(t){this.dispatchEvent(new CustomEvent("submit:failure",{bubbles:!0,cancelable:!1,detail:{values:e,request:s,exception:t}})),t instanceof r&&(this.errors=t.problems),console.warn("failed to submit form",this,"reason:",t)}}finally{this.spinner(!1)}}reset(){this.form.reset()}spinner(t){this.querySelectorAll("ful-spinner").forEach(e=>{e.hidden=!t}),this.querySelectorAll("[type=submit],[type=reset]").forEach(e=>{e.disabled=t})}set values(t){S.mutateIn(this.form,t)}get values(){return S.extractFrom(this.form)}set errors(t){S.errors(this.form,t,this.hasAttribute("scroll-on-error"))}}class _ extends e.ParsedElement{static observed=["value","readonly:presence"];static slots=!0;static template='\n <div class="form-label">\n <label>{{{{ slots.default }}}}</label>\n {{{{ slots.info }}}}\n </div>\n <div class="input-group">\n <span data-tpl-if="slots.ibefore" class="input-group-text">{{{{ slots.ibefore }}}}</span>\n {{{{ slots.before }}}}\n <input data-tpl-if="type != \'textarea\'" class="form-control" data-tpl-type="type" placeholder=" " form="">\n <textarea data-tpl-if="type == \'textarea\'" class="form-control" placeholder=" " form=""></textarea>\n {{{{ slots.after }}}}\n <span data-tpl-if="slots.iafter" class="input-group-text">{{{{ slots.iafter }}}}</span>\n </div>\n <ful-field-error></ful-field-error>\n ';static formAssociated=!0;_input;_fieldError;constructor(){super(),this.internals=this.attachInternals(),this.internals.role="presentation"}_type(){return this.getAttribute("type")??"text"}_fragment(t,e){return this.template().withOverlay({type:t,slots:e}).render()}render({slots:t,observed:s,disabled:r}){const i=this._type(),a=this._fragment(i,t);this._input=a.querySelector("input,textarea"),e.Attributes.forward("input-",this,this._input),this.disabled=r,this.readonly=s.readonly,this.value=s.value,this._input.addEventListener("change",t=>{t.stopPropagation(),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!1,detail:{value:this.value}}))});const n=a.querySelector("label");n.addEventListener("click",()=>this.focus()),this._fieldError=a.querySelector("ful-field-error"),this._input.ariaDescribedByElements=[this._fieldError],this._input.ariaLabelledByElements=[n],this.replaceChildren(a)}get value(){return""===this._input.value?null:this._input.value}set value(t){this._input.value=""===t?null:t}get readonly(){return this._input.readOnly}set readonly(t){this._input.readOnly=t,this.reflect(()=>{e.Attributes.toggle(this,"readonly",t)})}get disabled(){return this._input.hasAttribute("disabled")}set disabled(t){e.Attributes.toggle(this._input,"disabled",t)}focus(t){this._input.focus(t)}setCustomValidity(t){if(!t)return this.internals.setValidity({}),void(this._fieldError.innerText="");this.internals.setValidity({customError:!0}," "),this._fieldError.innerText=t}formResetCallback(){this.value=this.getAttribute("value")}}class C extends e.ParsedElement{render(){const t=this.innerHTML.trim();if(""===t)return void(this.innerHTML=this.getAttribute("default")??"");const e=this.getAttribute("locale")??Intl.DateTimeFormat().resolvedOptions().locale,s=new Intl.DateTimeFormat(e,{year:"numeric",month:"numeric",day:"numeric"}),[r,i,a]=t.split("-").map(Number);this.innerHTML=s.format(new Date(r,i-1,a))}}class O extends e.ParsedElement{render(){const t=this.innerHTML.trim();if(""===t)return void(this.innerHTML=this.getAttribute("default")??"");const e=this.getAttribute("locale")??Intl.DateTimeFormat().resolvedOptions().locale,s=new Intl.DateTimeFormat(e,{year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",hour12:!1});this.innerHTML=s.format(new Date(O.isoToLocal(t)))}static isoToLocal(t){const e=new Date(t),s=(t,e)=>String(e).padStart(t,"0");return`${`${e.getFullYear()}-${s(2,e.getMonth()+1)}-${s(2,e.getDate())}`}T${`${s(2,e.getHours())}:${s(2,e.getMinutes())}:${s(2,e.getSeconds())}.${s(3,e.getMilliseconds())}`}`}}class R extends _{static observed=["value","readonly:presence","min","max","step"];_type(){return"date"}render(t){const{observed:e}=t;super.render(t),this.min=e.min,this.max=e.max,this.step=e.step}get min(){const t=this._input.min;return""===t?null:t}set min(t){this._input.min=R.#T(t)}get max(){const t=this._input.max;return""===t?null:t}set max(t){this._input.max=R.#T(t)}get step(){const t=this._input.step;return""===t?null:t}set step(t){this._input.step=t??""}static#T(t){if(!t)return"";if("now"===t)return(new Date).toISOString().split("T")[0];const e=/^([+-])(\d+)([dmy])$/.exec(t);if(!e)return t;const s="-"===e[1]?-1:1,r=+e[2],i=new Date;switch(e[3]){case"d":i.setDate(i.getDate()+r*s);break;case"m":i.setMonth(i.getMonth()+r*s);break;case"y":i.setFullYear(i.getFullYear()+r*s)}return i.toISOString().split("T")[0]}}class I extends R{_type(){return"time"}}class N extends _{static observed=["value","readonly:presence","min","max","step"];_type(){return"datetime-local"}render(t){const{observed:e}=t;super.render(t),this.min=e.min,this.max=e.min,this.step=e.min}get value(){const t=this._input.value;return""===t?null:new Date(t).toISOString()}set value(t){this._input.value=t?O.isoToLocal(t):""}get min(){const t=this._input.min;return""===t?null:new Date(t).toISOString()}set min(t){this._input.min=t?O.isoToLocal(t):""}get max(){const t=this._input.max;return""===t?null:new Date(t).toISOString()}set max(t){this._input.max=t?O.isoToLocal(t):""}get step(){const t=this._input.step;return""===t?null:t}set step(t){this._input.step=t??""}}class P{#y;#w;#o;#A;#S;#x;#k;static create({el:t,http:e,responseMapper:s}){return new P({http:e,url:t.getAttribute("src"),method:t.getAttribute("method")??"POST",responseMapper:s,prefetch:t.hasAttribute("preload"),revision:t.getAttribute("revision")})}constructor({http:t,url:e,method:s,responseMapper:r,prefetch:i,revision:a}){this.#y=t,this.#w=e,this.#o=s,this.#A=r,this.#S=i,this.#x=a,this.#k=null}async prefetch(){this.#S&&await this.#q()}async exact(...t){return await this.#q(),this.#k.filter(([e,s])=>t.some(t=>t==e))}async load(t){return await this.#q(),this.#k.filter(([e,s])=>(s??"").toLowerCase().includes(t?.toLowerCase()))}async#q(){if(null!==this.#k)return;const t=`${this.#o}@${this.#w}`;if(null!==this.#x){const e=v.load(t,this.#x);if(void 0!==e)return void(this.#k=e)}const e=await this.#y.request(this.#o,this.#w).fetchJson();this.#k=this.#A(e),null!==this.#x&&v.save(t,this.#x,this.#k)}}class D{#y;#w;#o;#A;static create({el:t,http:e,responseMapper:s}){return new D({http:e,url:t.getAttribute("src"),method:t.getAttribute("method")??"POST",responseMapper:s})}constructor({http:t,url:e,method:s,responseMapper:r}){this.#y=t,this.#w=e,this.#o=s,this.#A=r}async exact(...t){const e=await this.#y.request(this.#o,this.#w).param("k",...t).fetchJson();return this.#A(e)}async load(t){const e=await this.#y.request(this.#o,this.#w).param("s",t).fetchJson();return this.#A(e)}}class M{#k;constructor(t){this.#k=t}update(t){this.#k=t}exact(...t){return this.#k.filter(([e,s])=>t.some(t=>t==e))}load(t){return this.#k.filter(([e,s])=>(s??"").toLowerCase().includes(t?.toLowerCase()))}}class B{static create(t){if(!t.el.hasAttribute("src")){const e=Array.from(t.options.options?.querySelectorAll("option")??[]).map(t=>[t.getAttribute("value")??t.innerText.trim(),t.innerText.trim()]);return new M(e)}return"chunked"==t.el.getAttribute("mode")?D.create(t):P.create(t)}}class F extends e.ParsedElement{static slots=!0;static template='\n <ful-spinner class="centered" hidden></ful-spinner>\n <menu tabindex="-1" hidden></menu>\n ';#L;#_;#p=new Map;render({slots:t}){const e=this.template().render();this.#L=e.querySelector("ful-spinner"),this.#_=e.querySelector("menu"),this.#_.addEventListener("click",t=>{t.stopPropagation(),t.target.matches("li")?this.#C(t.target):this.hide()}),this.replaceChildren(e)}acceptSelection(){const t=this.#_.querySelector("[selected]")??this.#_.firstElementChild;this.#C(t)}update(t){if(void 0===t)throw new Error("null data");if(this.#p=new Map(t.map((t,e)=>[String(e),t])),0===t.length){const t=document.createElement("div");return t.classList.add("text-center","py-2","bi","bi-database-slash"),void this.#_.replaceChildren(t)}this.#_.replaceChildren(...t.map(([t,e,s],r)=>{const i=document.createElement("li");return 0===r&&i.setAttribute("selected",""),i.setAttribute("value",r),i.innerText=e,i}))}#C(t){const e=t.getAttribute("value"),s=this.#p.get(e);this.hide(),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!1,detail:{index:e,data:s}}))}hide(){this.setAttribute("hidden","")}get shown(){return!this.hasAttribute("hidden")}async show(t){this.removeAttribute("hidden"),this.#_.setAttribute("hidden",""),this.#L.removeAttribute("hidden");try{const e=await t();this.update(e)}finally{this.#L.setAttribute("hidden",""),this.#_.removeAttribute("hidden")}}async moveOrShow(t,e){if(this.shown){const e=this.#_.querySelector("[selected]")??this.#_.firstElementChild,s=e[(t?"next":"previous")+"ElementSibling"];return void(s&&(e.removeAttribute("selected"),s.setAttribute("selected",""),s.scrollIntoView({block:"nearest",behavior:"smooth"})))}await this.show(e)}}class $ extends e.ParsedElement{static observed=["value:csvm","readonly:presence"];static slots=!0;static template='\n <div class="form-label">\n <label>{{{{ slots.default }}}}</label>\n {{{{ slots.info }}}}\n </div>\n <div class="input-group flex-nowrap" tabindex="-1">\n <span data-tpl-if="slots.ibefore" class="input-group-text">{{{{ slots.ibefore }}}}</span>\n {{{{ slots.before }}}}\n <div class="ful-select-input-container">\n <div class="ful-select-input">\n <badges></badges>\n <input type="text" form="">\n </div>\n <ful-dropdown hidden popover="manual"></ful-dropdown>\n </div>\n {{{{ slots.after }}}}\n <span data-tpl-if="slots.iafter" class="input-group-text">{{{{ slots.iafter }}}}</span>\n </div>\n <ful-field-error></ful-field-error>\n ';static mappers={csvm:(t,e,s)=>s.hasAttribute("multiple")?null===t?[]:t.split(",").map(t=>t.trim()).filter(t=>t):null===t||""===t?null:t};static formAssociated=!0;internals;#O;#R;#I;#N;#P;#D;#M=new Map;constructor(){super(),this.internals=this.attachInternals(),this.internals.role="presentation"}async render({slots:t,observed:s,disabled:r}){const i=this.getAttribute("name");this.#O=T.fromAttributes(this,"loaders:select",{options:t.options}),this.#P=this.hasAttribute("multiple"),await(this.#O.prefetch?.());const a=this.template().withOverlay({slots:t,name:i}).render();this.#N=a.querySelector("input"),e.Attributes.forward("input-",this,this.#N),this.#R=a.querySelector("badges"),this.value=s.value,this.disabled=r,this.readonly=s.readonly,this.#I=a.querySelector("ful-dropdown");const n=a.querySelector("label");n.addEventListener("click",()=>this.focus()),this.#D=a.querySelector("ful-field-error"),this.#N.ariaDescribedByElements=[this.#D],this.#N.ariaLabelledByElements=[n];const l=this,[o,u]=A.throttle(400,()=>l.#I.show(()=>l.#O.load(l.#N.value)));this.addEventListener("click",t=>{t.target.matches("input")||this.disabled||this.readonly||(this.#I.shown?this.#I.hide():(this.#N.focus(),o()))}),this.#R.addEventListener("click",t=>{if(t.stopPropagation(),this.disabled||this.readonly)return;-1!==[...this.#R.children].indexOf(t.target)&&(this.#M.delete(Array.from(this.#M.keys()).pop()),this.#B(),this.#F())}),this.#N.addEventListener("blur",t=>{t.stopPropagation(),t.relatedTarget&&this.contains(t.relatedTarget)||(u(),this.#I.hide(),this.#N.value="")}),this.#N.addEventListener("keydown",t=>{if(t.stopPropagation(),!this.disabled&&!this.readonly)switch(t.code){case"ArrowUp":this.#I.moveOrShow(!1,()=>l.#O.load(l.#N.value));break;case"ArrowDown":this.#I.moveOrShow(!0,()=>l.#O.load(l.#N.value));break;case"Escape":this.#I.hide();break;case"Enter":this.#I.acceptSelection(),this.#N.value="";break;case"Backspace":this.#M.size&&0===this.#N.selectionStart&&0===this.#N.selectionEnd&&(this.#M.delete(Array.from(this.#M.keys()).pop()),this.#B(),this.#F());break;case"Tab":this.#I.hide(),u()}}),this.#N.addEventListener("input",t=>{t.stopPropagation(),this.disabled||this.readonly||o()}),this.#I.addEventListener("change",t=>{t.stopPropagation(),this.#P||this.#M.clear(),this.#M.set(t.detail.data[0],t.detail.data.slice(1)),this.#B(),this.#F(),this.#N.focus(),this.#I.hide()}),this.replaceChildren(a)}withLoader(t){t(this.#O)}#B(){const t=[...this.#M.entries()].map(t=>({key:t[0],label:t[1][0],metadata:t[1].slice(1)})),e=this.#P?t:t[0]??null;this.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!1,detail:{value:e}}))}#F(){const t=Array.from(this.#M.entries()).map(([t,e])=>{const s=document.createElement("badge");return s.setAttribute("role","button"),s.setAttribute("value",t),s.innerText=e[0],s});this.#R.innerHTML="",this.#R.append(...t)}set value(t){if(null===t)return this.#M=new Map,void this.#F();(async()=>{const e=await(this.#P?this.#O.exact(...t):this.#O.exact(t));this.#M=new Map(e.map(t=>[t[0],t.slice(1)])),this.#F()})()}get value(){return this.#P?[...this.#M.keys()]:[...this.#M.keys()][0]??null}get entry(){return this.#P?[...this.#M.entries()]:[...this.#M.entries()][0]??null}get disabled(){return this.#N.hasAttribute("disabled")}set disabled(t){e.Attributes.toggle(this.#N,"disabled",t)}get readonly(){return this.#N.readOnly}set readonly(t){this.#N.readOnly=t,this.reflect(()=>{e.Attributes.toggle(this,"readonly",t)})}focus(t){this.#N.focus(t)}setCustomValidity(t){if(!t)return this.internals.setValidity({}),void(this.#D.innerText="");this.internals.setValidity({customError:!0}," "),this.#D.innerText=t}}class U extends e.ParsedElement{static observed=["value","readonly:presence"];static slots=!0;static template='\n <fieldset>\n <legend class="form-label">\n {{{{ slots.default }}}}\n </legend>\n <header data-tpl-if="slots.header">\n {{{{ slots.header }}}}\n </header>\n <section>\n <div class="label-wrapper" data-tpl-each="inputsAndLabels" data-tpl-var="ial">\n <label>\n {{{{ ial[0] }}}}\n <div>{{{{ ial[1] }}}}</div>\n </label>\n </div>\n </section>\n <ful-field-error></ful-field-error>\n <footer data-tpl-if="slots.footer">\n {{{{ slots.footer }}}}\n </footer>\n </fieldset>\n ';static formAssociated=!0;#$;#D;#U;#H;constructor(){super(),this.internals=this.attachInternals(),this.internals.role="radiogroup"}render({slots:t,observed:s,disabled:r}){const i=this.getAttribute("name")??e.Attributes.uid("ful-radiogroup"),a=Array.from(t.default.querySelectorAll("ful-radio")),n=a.map(t=>{const s=document.createElement("input");s.setAttribute("type","radio"),e.Attributes.forward("input-",this,s),e.Attributes.forward("",t,s),s.setAttribute("name",`${i}-ignore`),s.setAttribute("form",""),s.addEventListener("change",t=>{t.stopPropagation(),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!1,detail:{value:this.value}}))});return[s,e.Fragments.fromChildNodes(t)]});a.forEach(t=>t.remove()),this.template().withOverlay({name:i,slots:t,inputsAndLabels:n}).renderTo(this),this.#$=this.firstElementChild,this.disabled=r,this.readonly=s.readonly,this.value=s.value,this.#D=this.querySelector("ful-field-error"),this.ariaDescribedByElements=[this.#D],this.#U=this.querySelector("input[type=radio]"),this.#H="boolean"===this.getAttribute("type")}get value(){const t=this.querySelector("input[type=radio]:checked");return t?this.#H?"true"===t.value:t.value:null}set value(t){if(null===t)return void this.querySelectorAll("input[type=radio]").forEach(t=>{t.checked=!1});const e=this.querySelector(`input[type=radio][value=${CSS.escape(String(t))}]`);e&&(e.checked=!0)}get readonly(){return this.#$.inert}set readonly(t){this.#$.inert=t,this.reflect(()=>{e.Attributes.toggle(this,"readonly",t)})}get disabled(){return this.#$.hasAttribute("disabled")}set disabled(t){e.Attributes.toggle(this.#$,"disabled",t)}focus(t){this.#U.focus(t)}setCustomValidity(t){if(!t)return this.internals.setValidity({}),void(this.#D.innerText="");this.internals.setValidity({customError:!0}," "),this.#D.innerText=t}}class H extends e.ParsedElement{static observed=["value:bool","readonly:presence"];static slots=!0;static template='\n <div data-tpl-class="klass">\n <div class="input-container">\n <input class="form-check-input" type="checkbox" role="switch" form="" placeholder=" ">\n </div>\n <div class="form-check-label">\n <label>{{{{ slots.default }}}}</label>\n {{{{ slots.info }}}}\n </div>\n </div>\n <ful-field-error></ful-field-error>\n ';#V;#N;#D;static formAssociated=!0;constructor(){super(),this.internals=this.attachInternals(),this.internals.role="presentation"}render({slots:t,observed:s,disabled:r}){const i="switch"==this.getAttribute("type")?"form-check form-switch":"form-check",a=this.template().withOverlay({slots:t,klass:i}).render();this.#V=a.firstElementChild,this.#N=a.querySelector("input"),e.Attributes.forward("input-",this,this.#N),this.disabled=r,this.readonly=s.readonly,this.value=s.value,this.#N.addEventListener("change",t=>{t.stopPropagation(),this.dispatchEvent(new CustomEvent("change",{bubbles:!0,cancelable:!1,detail:{value:this.value}}))});const n=a.querySelector("label");n.addEventListener("click",()=>{this.focus(),this.disabled||this.readonly||(this.value=!this.value)}),this.#D=a.querySelector("ful-field-error"),this.#N.ariaDescribedByElements=[this.#D],this.#N.ariaLabelledByElements=[n],this.replaceChildren(a)}get value(){return this.#N.checked}set value(t){this.#N.checked=t}get readonly(){return this.#V.inert}set readonly(t){this.#V.inert=t,this.reflect(()=>{e.Attributes.toggle(this,"readonly",t)})}get disabled(){return this.#N.hasAttribute("disabled")}set disabled(t){e.Attributes.toggle(this.#N,"disabled",t)}focus(t){this.#N.focus(t)}setCustomValidity(t){if(!t)return this.internals.setValidity({}),void(this.#D.innerText="");this.internals.setValidity({customError:!0}," "),this.#D.innerText=t}}class V extends e.ParsedElement{static slots=!0;static template='\n <div class="ful-spinner-wrapper" role="status">\n <div class="ful-spinner-text">{{{{ slots.default }}}}</div>\n <div class="ful-spinner-icon"></div>\n </div>\n ';render({slots:t}){this.template().withOverlay({slots:t}).renderTo(this)}}class z extends e.ParsedElement{static observed=["order"];#z;render(){const t=this.getAttribute("sorter"),e=["asc","desc",null];this.addEventListener("click",()=>{const s=e[(e.indexOf(this.order)+1)%3];this.dispatchEvent(new CustomEvent("sort-requested",{bubbles:!0,cancelable:!0,detail:{value:{sorter:t,order:s}}}))})}get order(){return this.#z||null}set order(t){this.#z=t||null,this.reflect(()=>{this.#z?this.setAttribute("order",t):this.removeAttribute("order")})}}class j extends e.ParsedElement{static observed=["total:number","current:number"];static l10n={en:{showing:"Page {0} of {1}",navigation:"Page navigation",previous:"Previous",next:"Next"},it:{showing:"Pagina {0} di {1}",navigation:"Navigazione pagine",previous:"Precedente",next:"Successivo"}};static config={prevIcon:"bi bi-chevron-left",nextIcon:"bi bi-chevron-right",reloadIcon:"bi bi-arrow-clockwise"};static template='\n <nav data-tpl-aria-label="#l10n:t(\'navigation\')" class="user-select-none">\n <ul class="pagination">\n <li class="page-item ms-auto me-2 pagination-index"> {{ #l10n:t(\'showing\', curr.label, total) }}</li>\n <li class="page-item reload me-2"><a role="button"><i data-tpl-class="config.reloadIcon"></i></a></li> \n <li class="page-item prev">\n <a data-tpl-class="prev.enabled?\'page-link\':\'page-link disabled\'" data-tpl-aria-label="#l10n:t(\'previous\')" role="button" data-tpl-data-page="prev.index">\n <i aria-hidden="true" data-tpl-class="config.prevIcon"></i>\n </a>\n </li>\n <li class="page-item" data-tpl-each="pages" data-tpl-var="page">\n <a data-tpl-class="curr.index != page.index ? \'page-link\': \'page-link disabled\'" role="button" data-tpl-data-page="page.index" >\n {{ page.label }}\n </a>\n </li>\n <li class="page-item next">\n <a data-tpl-class="next.enabled?\'page-link\':\'page-link disabled\'" data-tpl-aria-label="#l10n:t(\'next\')" role="button" data-tpl-data-page="next.index">\n <i aria-hidden="true" data-tpl-class="config.nextIcon"></i>\n </a>\n </li>\n </ul>\n </nav>\n ';#j=0;#n=0;render({observed:t}){this.update(t.current??0,t.total??0),this.addEventListener("click",t=>{const e=t.target.closest("a");e&&this.dispatchEvent(new CustomEvent("page-requested",{bubbles:!0,cancelable:!0,detail:{value:Number(e.dataset.page??this.#n)}}))})}update(t,e){const s=Number(this.getAttribute("pages")??"5"),r={index:Math.max(0,t-1),enabled:t>0},i={index:t,label:t+1},a={index:Math.min(e,t+1),enabled:t+1<e},n=[{index:t,label:t+1}];for(let r=t,i=1;i!==s&&n.length!=s;++i){const t=r-i;t>=0&&n.unshift({index:t,label:t+1});const s=r+i;s<e&&n.push({index:s,label:s+1})}this.template().withOverlay({total:e,prev:r,curr:i,next:a,pages:n}).renderTo(this)}get total(){return this.#j}set total(t){this.#j=t,this.reflect(()=>{this.setAttribute("total",String(t)),this.update(this.#n??0,this.#j)})}get current(){return this.#n}set current(t){this.#n=t,this.reflect(()=>{this.setAttribute("current",String(t)),this.update(this.#n,this.#j??0)})}}class J{static parse(t,s){const r=e.Nodes.queryChildren(t,"schema");if(!r)throw new Error(`missing expected <schema> in ${t}`);return e.Nodes.queryChildrenAll(r,"column").map(t=>({sorter:t.getAttribute("sorter"),order:t.getAttribute("order"),title:J.#J(t,s),content:J.#G(t,s)}))}static#J(t,s){const r=e.Nodes.queryChildren(t,"title");r&&r.remove();const i=r?s.withFragment(e.Fragments.fromChildNodes(r)).render():document.createTextNode(t.getAttribute("title")??"");return{classes:t.getAttribute("th-class"),fragment:i}}static#G(t,s){return{classes:t.getAttribute("td-class"),template:s.withFragment(e.Fragments.fromChildNodes(t))}}}class G{#y;#w;#o;constructor(t,e,s){this.#y=t,this.#w=e,this.#o=s}async load(t,e,s){const r=Object.entries(s).filter(([t,e])=>e);return await this.#y.request(this.#o,this.#w).param("page",t.page).param("size",t.size).param("sort",e.order?`${e.sorter},${e.order}`:null).param("filters",r.length>0?JSON.stringify(Object.fromEntries(r)):null).fetchJson()}}class W{static create({el:t,http:e}){const s=t.getAttribute("src"),r=t.getAttribute("method")??"GET";return new G(e,s,r)}}class K extends e.ParsedElement{static slots=!0;static l10n={en:{notloaded:"Start searching to see results.",error:"Error while loading data:",nodata:"No elements found."},it:{notloaded:"Avvia la ricerca per visualizzare i risultati.",error:"Errore nel caricamento dei dati:",nodata:"Nessun elemento trovato."}};static conf={sortIcon:""};static template='\n <ful-form data-tpl-if="slots.filters">\n {{{{ slots.filters }}}}\n </ful-form>\n <div class="table-wrapper">\n <table class="table">\n <caption data-tpl-if="slots.caption">{{{{ slots.caption }}}}</caption>\n <thead>\n <tr>\n <th data-tpl-each="schema" scope="col" data-tpl-class="title.classes">\n {{{{ title.fragment }}}}\n <ful-sorter data-tpl-if="sorter || order" data-tpl-sorter="sorter" data-tpl-order="order"></ful-sorter>\n </th>\n </tr>\n </thead>\n <tbody></tbody>\n <tbody data-ref="no-autoload">\n <tr>\n <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">\n <i class="bi bi-search" style="font-size: 40px; color: #BDC3CA"></i>\n <p class="mt-3 mb-0" style="color: #BDC3CA">\n {{ #l10n:t(\'notloaded\') }}\n </p>\n </td>\n </tr>\n </tbody>\n <tbody data-ref="loading" hidden>\n <tr>\n <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">\n <ful-spinner class="big"></ful-spinner>\n </td>\n </tr>\n </tbody>\n <tbody data-ref="feedback" hidden>\n <tr>\n <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">\n <div class="alert alert-danger">\n <p>{{ #l10n:t(\'error\') }}</p>\n <p class="mb-0" data-ref="feedback-error"></p>\n </div>\n </td>\n </tr>\n </tbody>\n <tfoot data-tpl-if="slots.footer">\n {{{{ slots.footer }}}}\n </tfoot>\n </table>\n </div>\n <ful-pagination current="0" total="1"></ful-pagination>\n ';static templates={row:'\n <tr data-tpl-if="pageResponse.data.length == 0">\n <td data-tpl-colspan="schema.length" class="text-center align-middle p-4">\n {{ #l10n:t(\'nodata\') }}\n </td>\n </tr>\n <tr data-tpl-each="pageResponse.data" data-tpl-var="row">\n <td data-tpl-each="schema" data-tpl-class="content.classes">\n {{{{ content.template.withOverlay(row).render() }}}}\n </td>\n </tr>\n '};#W;#h;#K;#Y;#Q;#X;#Z;#tt;async render({slots:t,observed:s}){const r=this.template(),i=J.parse(t.default,r),a=r.withOverlay({slots:t,schema:i}).render(),n=e.Nodes.queryChildren(a,".table-wrapper").querySelector("table");e.Attributes.forward("table-",this,n),this.#W=i,this.#h=n.querySelector(":scope > tbody"),this.#K=n.querySelector(":scope > tbody[data-ref=loading]"),this.#Y=n.querySelector(":scope > tbody[data-ref=no-autoload]"),this.#Q=n.querySelector(":scope > tbody[data-ref=feedback]"),this.#X=e.Nodes.queryChildren(a,"ful-pagination"),this.#Z=n.querySelectorAll(":scope > thead ful-sorter")??[],this.replaceChildren(a),await e.Rendering.waitForChildren(this);const l=i.find(t=>t.order),o=e.Nodes.queryChildren(this,"ful-form");this.#tt={pageRequest:{page:0,size:this.getAttribute("page-size")?Number(this.getAttribute("page-size")):10},sortRequest:{order:l?.order,sorter:l?.sorter},filterRequest:o?.values??{}},o?.addEventListener("submit:success",async t=>{await this.load({page:0,size:this.#tt.pageRequest.size},this.#tt.sortRequest,t.detail.request)}),this.addEventListener("page-requested",async t=>{await this.load({page:t.detail.value,size:this.#tt.pageRequest.size},this.#tt.sortRequest,this.#tt.filterRequest)}),this.addEventListener("sort-requested",async t=>{await this.load(this.#tt.pageRequest,t.detail.value,this.#tt.filterRequest),this.#Z.forEach(t=>t.order=null),t.target.order=t.detail.value.order}),this.hasAttribute("autoload")&&await this.reload()}async reload(){return await this.load(this.#tt.pageRequest,this.#tt.sortRequest,this.#tt.filterRequest)}async load(t,e,s){this.#h.innerHTML="",this.#K.removeAttribute("hidden",""),this.#Q.setAttribute("hidden",""),this.#Y.setAttribute("hidden","");try{const r=T.fromAttributes(this,"loaders:table"),i=await r.load(t,e,s);this.#tt={pageRequest:t,sortRequest:e,filterRequest:s},this.#et(t,e,s,i)}catch(t){throw this.#K.setAttribute("hidden",""),this.#Q.removeAttribute("hidden",""),t.problems?this.#Q.querySelector("[data-ref=feedback-error]").textContent=t.problems.map(t=>`${t.reason}`):this.#Q.querySelector("[data-ref=feedback-error]").textContent=t,t}}async resetWithFilter(t){return await this.load({page:0,size:this.#tt.pageRequest.size},this.#tt.sortRequest,t)}#et(t,e,s,r){this.#K.setAttribute("hidden",""),this.#h.replaceChildren(this.template("row").withOverlay({schema:this.#W,pageRequest:t,filterRequest:s,pageResponse:r}).render()),this.#X.current=t.page,this.#X.total=Math.ceil(r.size/t.size)}}class Y extends e.ParsedElement{static observed=["value:json"];static slots=!0;static template='\n <div class="form-label" data-tpl-if="label">\n <label>{{{{ label }}}}</label>\n {{{{ slots.info }}}}\n </div>\n <div class="input-group">\n <button data-ref="operator" class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" value="LTE" form="">&PrecedesSlantEqual;</button>\n <ul class="dropdown-menu">\n <li><a class="dropdown-item" role="button" value="EQ">=</a></li>\n <li><a class="dropdown-item" role="button" value="NEQ">&ne;</a></li>\n <li><a class="dropdown-item" role="button" value="LT">&prec;</a></li>\n <li><a class="dropdown-item" role="button" value="GT">&succ;</a></li>\n <li><a class="dropdown-item" role="button" value="LTE">&PrecedesSlantEqual;</a></li>\n <li><a class="dropdown-item" role="button" value="GTE">&SucceedsSlantEqual;</a></li>\n <li><a class="dropdown-item" role="button" value="BETWEEN">&LeftRightArrow;</a></li>\n </ul>\n <input data-ref="value1" type="datetime-local" class="form-control" form="">\n <input data-ref="value2" type="datetime-local" class="form-control" form="" hidden>\n <span class="input-group-text"><i class="bi bi-search"></i></span>\n </div>\n <ful-field-error></ful-field-error>\n ';static formAssociated=!0;#st;#rt;#it;#D;constructor(){super(),this.internals=this.attachInternals()}render({slots:t}){const s=0===e.Fragments.toHtml(t.default.cloneNode(!0)).trim().length?null:t.default,r=this.getAttribute("name"),i=this.template().withOverlay({slots:t,label:s,name:r}).render();this.#st=i.querySelector("[data-ref=operator]"),this.#rt=i.querySelector("[data-ref=value1]"),this.#it=i.querySelector("[data-ref=value2]"),this.#D=i.querySelector("ful-field-error");const a=i.querySelector("label");a?.addEventListener("click",()=>this.focus()),this.#rt.ariaDescribedByElements=[this.#D],this.#rt.ariaLabelledByElements=a?[a]:[],this.replaceChildren(i),this.addEventListener("click",t=>{const s=t.target;if(!s.matches("ul > li > a"))return;const r=s.closest("ul")?.previousElementSibling,i=s.getAttribute("value");e.Attributes.toggle(this.#it,"hidden","BETWEEN"!==i),r.setAttribute("value",i),r.innerHTML=s.innerHTML})}get value(){const t=this.#st.getAttribute("value"),e="BETWEEN"===t?[this.#rt.value,this.#it.value]:[this.#rt.value];return e.some(t=>""===t)?void 0:[t,...e.map(t=>new Date(t).toISOString())]}set value(t){if(null==t)return this.#rt.value="",this.#it.value="",void this.reflect(()=>{this.removeAttribute("value")});const[e,...s]=t;this.#st.setAttribute("value",e),this.#rt.value=s[0]?O.isoToLocal(s[0]):s[0],this.#it.value=s[1]?O.isoToLocal(s[1]):s[1],this.reflect(()=>{this.setAttribute("value",JSON.stringify(t))})}focus(t){this.#rt.focus(t)}setCustomValidity(t){if(!t)return this.internals.setValidity({}),void(this.#D.innerText="");this.internals.setValidity({customError:!0}," "),this.#D.innerText=t}}class Q extends e.ParsedElement{static observed=["value:json"];static slots=!0;static template='\n <div class="form-label" data-tpl-if="label">\n <label>{{{{ label }}}}</label>\n {{{{ slots.info }}}}\n </div>\n <div class="input-group">\n <button data-ref="operator" class="btn btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" value="EQ" form="">=</button>\n <ul class="dropdown-menu">\n <li><a class="dropdown-item" role="button" value="EQ">=</a></li>\n <li><a class="dropdown-item" role="button" value="NEQ">&ne;</a></li>\n <li><a class="dropdown-item" role="button" value="LT">&prec;</a></li>\n <li><a class="dropdown-item" role="button" value="GT">&succ;</a></li>\n <li><a class="dropdown-item" role="button" value="LTE">&PrecedesSlantEqual;</a></li>\n <li><a class="dropdown-item" role="button" value="GTE">&SucceedsSlantEqual;</a></li>\n <li><a class="dropdown-item" role="button" value="BETWEEN">&LeftRightArrow;</a></li>\n </ul>\n <input data-ref="value1" type="date" class="form-control" form="">\n <input data-ref="value2" type="date" class="f