From 77da3ec94e1cfc53532aeb84ed7e92c203bb49ca Mon Sep 17 00:00:00 2001 From: Aggtaa Date: Wed, 23 Sep 2026 21:56:40 +0300 Subject: [PATCH] initial commit --- .gitignore | 2 + dist/assets/index-BLVwiv9z.css | 1 + dist/assets/index-C0OstMfa.js | 13 + dist/assets/model-viewer-FXu0v758.js | 4686 ++++++++++++++++++++++++++ dist/index.html | 13 + index.html | 12 + package-lock.json | 2018 +++++++++++ package.json | 25 + scripts/dev.ts | 22 + server/comfy.ts | 54 + server/config.ts | 11 + server/db.ts | 452 +++ server/glb.ts | 69 + server/index.ts | 411 +++ server/migrate.ts | 80 + server/tracker.ts | 118 + server/workflows.ts | 158 + shared/api.ts | 240 ++ src/App.tsx | 44 + src/components/BatchCard.tsx | 62 + src/components/ModelView.tsx | 113 + src/components/Nav.tsx | 57 + src/components/Text2ImgForm.tsx | 82 + src/components/Viewer.tsx | 22 + src/lib/api.ts | 35 + src/lib/batches.ts | 132 + src/lib/settings.ts | 34 + src/main.tsx | 17 + src/migrate.ts | 38 + src/pages/Batch.tsx | 142 + src/pages/Project.tsx | 191 ++ src/pages/Projects.tsx | 36 + src/pages/Sources.tsx | 62 + src/styles.css | 139 + start.bat | 11 + tsconfig.app.json | 22 + tsconfig.json | 7 + tsconfig.server.json | 20 + vite.config.ts | 16 + 39 files changed, 9667 insertions(+) create mode 100644 .gitignore create mode 100644 dist/assets/index-BLVwiv9z.css create mode 100644 dist/assets/index-C0OstMfa.js create mode 100644 dist/assets/model-viewer-FXu0v758.js create mode 100644 dist/index.html create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 scripts/dev.ts create mode 100644 server/comfy.ts create mode 100644 server/config.ts create mode 100644 server/db.ts create mode 100644 server/glb.ts create mode 100644 server/index.ts create mode 100644 server/migrate.ts create mode 100644 server/tracker.ts create mode 100644 server/workflows.ts create mode 100644 shared/api.ts create mode 100644 src/App.tsx create mode 100644 src/components/BatchCard.tsx create mode 100644 src/components/ModelView.tsx create mode 100644 src/components/Nav.tsx create mode 100644 src/components/Text2ImgForm.tsx create mode 100644 src/components/Viewer.tsx create mode 100644 src/lib/api.ts create mode 100644 src/lib/batches.ts create mode 100644 src/lib/settings.ts create mode 100644 src/main.tsx create mode 100644 src/migrate.ts create mode 100644 src/pages/Batch.tsx create mode 100644 src/pages/Project.tsx create mode 100644 src/pages/Projects.tsx create mode 100644 src/pages/Sources.tsx create mode 100644 src/styles.css create mode 100644 start.bat create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.server.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..902b281 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +data/ diff --git a/dist/assets/index-BLVwiv9z.css b/dist/assets/index-BLVwiv9z.css new file mode 100644 index 0000000..e1721dc --- /dev/null +++ b/dist/assets/index-BLVwiv9z.css @@ -0,0 +1 @@ +:root{--bg: #f5f5f4;--panel: #ffffff;--text: #1c1917;--muted: #78716c;--border: #e7e5e4;--accent: #2563eb;--accent-text: #ffffff;--error: #dc2626;--img-bg: #e7e5e4;--thumb: 2cm}@media(prefers-color-scheme:dark){:root{--bg: #161616;--panel: #1f1f1f;--text: #f5f5f4;--muted: #a8a29e;--border: #333;--accent: #3b82f6;--error: #f87171;--img-bg: #2a2a2a}}*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:15px/1.45 system-ui,-apple-system,Segoe UI,sans-serif}main{max-width:1100px;margin:0 auto;padding:24px 16px 64px}main.wide{max-width:none}h1{font-size:22px;margin:0 0 4px}.sub{color:var(--muted);margin:0 0 20px;font-size:13px}.sub a{color:var(--accent)}.err{color:var(--error)}.nav{display:flex;flex-wrap:wrap;align-items:center;gap:18px;font-size:13px;margin-bottom:14px}.nav a{color:var(--accent);text-decoration:none}.nav a.active{color:var(--text);font-weight:700}.queue{margin-left:auto;display:inline-flex;align-items:center;gap:6px;color:var(--muted);font-size:12px}.queue .dot{width:8px;height:8px;border-radius:50%;background:#a8a29e;flex:none}.queue.idle .dot{background:#16a34a}.queue.busy .dot{background:#f59e0b;animation:queue-pulse 1.2s ease-in-out infinite}.queue.down,.queue.down .dot{color:var(--error)}.queue.down .dot{background:var(--error)}.queue b{color:var(--text);font-weight:600}@keyframes queue-pulse{50%{opacity:.35}}form{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:18px;display:grid;gap:14px}label{display:grid;gap:6px;font-weight:600;font-size:13px}label small{font-weight:400;color:var(--muted)}textarea,input,select{width:100%;font:inherit;color:inherit;background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:9px 11px;resize:vertical}input[type=color]{padding:2px;height:40px}textarea:focus,input:focus,select:focus{outline:2px solid var(--accent);outline-offset:-1px}.row{display:grid;grid-template-columns:repeat(var(--cols, 2),1fr) auto;gap:14px;align-items:end}@media(max-width:760px){.row{grid-template-columns:1fr 1fr}.row button{grid-column:1 / -1}}button{font:inherit;font-weight:600;border:0;border-radius:8px;padding:10px 22px;cursor:pointer;background:var(--accent);color:var(--accent-text)}button:disabled{opacity:.55;cursor:not-allowed}details summary{cursor:pointer;font-weight:600;font-size:13px}details .sub-field{margin-top:12px}.preview{font-size:12px;color:var(--muted);background:var(--bg);border-radius:8px;padding:8px 10px}.stage{display:grid;grid-template-columns:1fr 1fr;gap:16px}.pane{display:grid;gap:6px;align-content:start;justify-items:start}.pane-title{font-weight:600;font-size:13px;display:flex;align-items:center;gap:10px}.pane .name{font-size:12px;color:var(--muted);word-break:break-all;min-height:18px}.box{position:relative;width:100%;max-width:420px;aspect-ratio:1;background:var(--img-bg);border-radius:10px;overflow:hidden;display:grid;place-items:center;color:var(--muted);font-size:13px;text-align:center;padding:0}.box img,.cell img{width:100%;height:100%;object-fit:contain;display:block;cursor:zoom-in}.box.err{color:var(--error);padding:12px}.links{position:absolute;right:6px;bottom:6px;display:flex;gap:4px}.links a{background:#0009;color:#fff;font-size:12px;text-decoration:none;padding:3px 8px;border-radius:6px}.links a.main{background:var(--accent)}.seg{display:inline-flex;border:1px solid var(--border);border-radius:7px;overflow:hidden;background:var(--panel)}.seg button{background:none;color:var(--muted);font-size:12px;font-weight:600;padding:3px 10px;border-radius:0}.seg button.on{background:var(--accent);color:var(--accent-text)}model-viewer{width:100%;height:100%;background:var(--img-bg);--poster-color: transparent}.mv-wrap{position:relative;width:100%;height:100%}.mv-wrap>model-viewer,.mv-wrap>.mv-layer{position:absolute;inset:0}.mv-layer{width:100%;height:100%;object-fit:contain}.mv-note{position:absolute;left:0;right:0;top:50%;text-align:center;font-size:12px;color:var(--muted)}.mv-note.err{top:auto;bottom:36px;color:var(--error)}.mv-seg{position:absolute;top:6px;left:6px}#status{min-height:22px;margin:16px 2px;color:var(--muted)}.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}.cell{position:relative;background:var(--img-bg);border-radius:8px;overflow:hidden;aspect-ratio:1}.cell>a.dl,.box>a.dl{position:absolute;right:6px;bottom:6px;background:#0009;color:#fff;font-size:12px;text-decoration:none;padding:3px 8px;border-radius:6px}.cell.pending{display:grid;place-items:center;color:var(--muted);font-size:13px}.viewer{position:fixed;inset:0;background:#000000e0;display:grid;place-items:center;z-index:10;cursor:zoom-out}.viewer img{max-width:96vw;max-height:90vh}.viewer .cap{position:fixed;bottom:12px;left:0;right:0;text-align:center;color:#ddd;font-size:13px}.empty{color:var(--muted)}.empty a{color:var(--accent)}.empty.err{color:var(--error);flex-basis:100%}.runs{display:flex;flex-wrap:wrap;gap:12px;align-items:flex-start}.run{background:var(--panel);border:1px solid var(--border);border-radius:10px;padding:8px;max-width:100%}.run .prompt+.prompt{margin-top:1px}.run .prompt{font-size:11px;color:var(--muted);margin-top:6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;width:0;min-width:100%}.strip{display:flex;gap:4px;overflow-x:auto}a.run-link{color:inherit;text-decoration:none;display:block;cursor:pointer}a.run-link:hover{border-color:var(--accent)}.actions{display:flex;gap:8px}.state-text{color:var(--text);font-weight:600}.batch-images{margin-top:16px}button.secondary{background:none;color:var(--muted);border:1px solid var(--border)}.toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:16px}.toolbar>a,.sub a{color:var(--accent);text-decoration:none;font-size:13px;font-weight:600}.upload-drop{border:2px dashed var(--border);border-radius:10px;padding:10px 16px;color:var(--muted);font-size:13px;cursor:pointer}.upload-drop.over{border-color:var(--accent);color:var(--accent)}.upload-drop b{color:var(--accent)}fieldset{border:0;padding:0;margin:0;display:grid;gap:14px;min-width:0}.col{display:grid;gap:4px;flex:none}.th{position:relative;width:var(--thumb);height:var(--thumb);border-radius:5px;overflow:hidden;background:var(--img-bg);display:grid;place-items:center;font-size:10px;color:var(--muted)}.th.none{background:none}.th.in-project,.run.in-project{outline:2px solid var(--accent);outline-offset:-2px}.project-image{margin-top:8px}.box.step-form{place-items:stretch;align-content:center;gap:8px;padding:16px;border:2px dashed var(--border);background:none;text-align:left;color:var(--text);border-radius:10px;overflow:visible}.step-form fieldset{gap:8px}.step-form-title{font-weight:700;font-size:14px}.step-form-hint{margin:0;font-size:12px;color:var(--muted)}.step-form label{gap:3px}.step-form input{padding:6px 9px}.step-form input[type=color]{height:32px}.stage.three{grid-template-columns:repeat(3,1fr)}@media(max-width:900px){.stage.three{grid-template-columns:1fr 1fr}}@media(max-width:600px){.stage.three{grid-template-columns:1fr}}.box-seg{position:absolute;top:6px;right:6px}.box-error{position:absolute;left:6px;bottom:34px;right:6px;color:var(--error);font-size:12px}.project-thumb{width:calc(var(--thumb) * 2);height:calc(var(--thumb) * 2);border-radius:6px;overflow:hidden;background:var(--img-bg)}.project-thumb img{width:100%;height:100%;object-fit:contain;display:block}.th.draft{width:auto;min-width:var(--thumb);padding:0 8px;text-align:center;font-size:11px;line-height:1.3}.th img{width:100%;height:100%;object-fit:contain;display:block;cursor:pointer}.th .more{position:absolute;right:2px;bottom:2px;background:#000000a6;color:#fff;font-size:10px;font-weight:600;padding:0 4px;border-radius:4px;line-height:15px;pointer-events:none} diff --git a/dist/assets/index-C0OstMfa.js b/dist/assets/index-C0OstMfa.js new file mode 100644 index 0000000..1400ed4 --- /dev/null +++ b/dist/assets/index-C0OstMfa.js @@ -0,0 +1,13 @@ +(function(){const f=document.createElement("link").relList;if(f&&f.supports&&f.supports("modulepreload"))return;for(const d of document.querySelectorAll('link[rel="modulepreload"]'))r(d);new MutationObserver(d=>{for(const m of d)if(m.type==="childList")for(const v of m.addedNodes)v.tagName==="LINK"&&v.rel==="modulepreload"&&r(v)}).observe(document,{childList:!0,subtree:!0});function s(d){const m={};return d.integrity&&(m.integrity=d.integrity),d.referrerPolicy&&(m.referrerPolicy=d.referrerPolicy),d.crossOrigin==="use-credentials"?m.credentials="include":d.crossOrigin==="anonymous"?m.credentials="omit":m.credentials="same-origin",m}function r(d){if(d.ep)return;d.ep=!0;const m=s(d);fetch(d.href,m)}})();var $r={exports:{}},Nu={};var $h;function Kg(){if($h)return Nu;$h=1;var i=Symbol.for("react.transitional.element"),f=Symbol.for("react.fragment");function s(r,d,m){var v=null;if(m!==void 0&&(v=""+m),d.key!==void 0&&(v=""+d.key),"key"in d){m={};for(var g in d)g!=="key"&&(m[g]=d[g])}else m=d;return d=m.ref,{$$typeof:i,type:r,key:v,ref:d!==void 0?d:null,props:m}}return Nu.Fragment=f,Nu.jsx=s,Nu.jsxs=s,Nu}var Fh;function Jg(){return Fh||(Fh=1,$r.exports=Kg()),$r.exports}var p=Jg(),Fr={exports:{}},tt={};var Wh;function $g(){if(Wh)return tt;Wh=1;var i=Symbol.for("react.transitional.element"),f=Symbol.for("react.portal"),s=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),d=Symbol.for("react.profiler"),m=Symbol.for("react.consumer"),v=Symbol.for("react.context"),g=Symbol.for("react.forward_ref"),T=Symbol.for("react.suspense"),C=Symbol.for("react.memo"),x=Symbol.for("react.lazy"),y=Symbol.for("react.activity"),D=Symbol.for("react.view_transition"),B=Symbol.iterator;function q(E){return E===null||typeof E!="object"?null:(E=B&&E[B]||E["@@iterator"],typeof E=="function"?E:null)}var Y={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},M=Object.assign,J={};function $(E,H,Z){this.props=E,this.context=H,this.refs=J,this.updater=Z||Y}$.prototype.isReactComponent={},$.prototype.setState=function(E,H){if(typeof E!="object"&&typeof E!="function"&&E!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,E,H,"setState")},$.prototype.forceUpdate=function(E){this.updater.enqueueForceUpdate(this,E,"forceUpdate")};function at(){}at.prototype=$.prototype;function At(E,H,Z){this.props=E,this.context=H,this.refs=J,this.updater=Z||Y}var Tt=At.prototype=new at;Tt.constructor=At,M(Tt,$.prototype),Tt.isPureReactComponent=!0;var Ut=Array.isArray;function I(){}var ut={H:null,A:null,T:null,S:null},ee=Object.prototype.hasOwnProperty;function le(E,H,Z){var K=Z.ref;return{$$typeof:i,type:E,key:H,ref:K!==void 0?K:null,props:Z}}function re(E,H){return le(E.type,H,E.props)}function ne(E){return typeof E=="object"&&E!==null&&E.$$typeof===i}function we(E){var H={"=":"=0",":":"=2"};return"$"+E.replace(/[=:]/g,function(Z){return H[Z]})}var We=/\/+/g;function Nt(E,H){return typeof E=="object"&&E!==null&&E.key!=null?we(""+E.key):H.toString(36)}function w(E){switch(E.status){case"fulfilled":return E.value;case"rejected":throw E.reason;default:switch(typeof E.status=="string"?E.then(I,I):(E.status="pending",E.then(function(H){E.status==="pending"&&(E.status="fulfilled",E.value=H)},function(H){E.status==="pending"&&(E.status="rejected",E.reason=H)})),E.status){case"fulfilled":return E.value;case"rejected":throw E.reason}}throw E}function W(E,H,Z,K,st){var dt=typeof E;(dt==="undefined"||dt==="boolean")&&(E=null);var ht=!1;if(E===null)ht=!0;else switch(dt){case"bigint":case"string":case"number":ht=!0;break;case"object":switch(E.$$typeof){case i:case f:ht=!0;break;case x:return ht=E._init,W(ht(E._payload),H,Z,K,st)}}if(ht)return st=st(E),ht=K===""?"."+Nt(E,0):K,Ut(st)?(Z="",ht!=null&&(Z=ht.replace(We,"$&/")+"/"),W(st,H,Z,"",function(sl){return sl})):st!=null&&(ne(st)&&(st=re(st,Z+(st.key==null||E&&E.key===st.key?"":(""+st.key).replace(We,"$&/")+"/")+ht)),H.push(st)),1;ht=0;var Q=K===""?".":K+":";if(Ut(E))for(var P=0;P>>1,yt=w[zt];if(0>>1;ztd(ia,k))Ed(H,ia)?(w[zt]=H,w[E]=k,zt=E):(w[zt]=ia,w[ol]=k,zt=ol);else if(Ed(H,k))w[zt]=H,w[E]=k,zt=E;else break t}}return W}function d(w,W){var k=w.sortIndex-W.sortIndex;return k!==0?k:w.id-W.id}if(i.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var m=performance;i.unstable_now=function(){return m.now()}}else{var v=Date,g=v.now();i.unstable_now=function(){return v.now()-g}}var T=[],C=[],x=1,y=null,D=3,B=!1,q=!1,Y=!1,M=!1,J=typeof setTimeout=="function"?setTimeout:null,$=typeof clearTimeout=="function"?clearTimeout:null,at=typeof setImmediate<"u"?setImmediate:null;function At(w){for(var W=s(C);W!==null;){if(W.callback===null)r(C);else if(W.startTime<=w)r(C),W.sortIndex=W.expirationTime,f(T,W);else break;W=s(C)}}function Tt(w){if(Y=!1,At(w),!q)if(s(T)!==null)q=!0,Ut||(Ut=!0,ne());else{var W=s(C);W!==null&&Nt(Tt,W.startTime-w)}}var Ut=!1,I=-1,ut=5,ee=-1;function le(){return M?!0:!(i.unstable_now()-eew&&le());){var zt=y.callback;if(typeof zt=="function"){y.callback=null,D=y.priorityLevel;var yt=zt(y.expirationTime<=w);if(w=i.unstable_now(),typeof yt=="function"){y.callback=yt,At(w),W=!0;break e}y===s(T)&&r(T),At(w)}else r(T);y=s(T)}if(y!==null)W=!0;else{var Ge=s(C);Ge!==null&&Nt(Tt,Ge.startTime-w),W=!1}}break t}finally{y=null,D=k,B=!1}W=void 0}}finally{W?ne():Ut=!1}}}var ne;if(typeof at=="function")ne=function(){at(re)};else if(typeof MessageChannel<"u"){var we=new MessageChannel,We=we.port2;we.port1.onmessage=re,ne=function(){We.postMessage(null)}}else ne=function(){J(re,0)};function Nt(w,W){I=J(function(){w(i.unstable_now())},W)}i.unstable_IdlePriority=5,i.unstable_ImmediatePriority=1,i.unstable_LowPriority=4,i.unstable_NormalPriority=3,i.unstable_Profiling=null,i.unstable_UserBlockingPriority=2,i.unstable_cancelCallback=function(w){w.callback=null},i.unstable_forceFrameRate=function(w){0>w||125zt?(w.sortIndex=k,f(C,w),s(T)===null&&w===s(C)&&(Y?($(I),I=-1):Y=!0,Nt(Tt,k-zt))):(w.sortIndex=yt,f(T,w),q||B||(q=!0,Ut||(Ut=!0,ne()))),w},i.unstable_shouldYield=le,i.unstable_wrapCallback=function(w){var W=D;return function(){var k=D;D=W;try{return w.apply(this,arguments)}finally{D=k}}}})(Ir)),Ir}var Ph;function Wg(){return Ph||(Ph=1,kr.exports=Fg()),kr.exports}var Pr={exports:{}},te={};var tv;function kg(){if(tv)return te;tv=1;var i=oo();function f(x){var y="https://react.dev/errors/"+x;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(f){console.error(f)}}return i(),Pr.exports=kg(),Pr.exports}var lv;function Pg(){if(lv)return zu;lv=1;var i=Wg(),f=oo(),s=Ig();function r(t){var e="https://react.dev/errors/"+t;if(1ja||(t.current=dc[ja],dc[ja]=null,ja--)}function xt(t,e){ja++,dc[ja]=t.current,t.current=e}var Ie=ke(null),An=ke(null),Dl=ke(null),Ou=ke(null);function Au(t,e){switch(xt(Dl,e),xt(An,t),xt(Ie,null),e.nodeType){case 9:case 11:t=(t=e.documentElement)&&(t=t.namespaceURI)?ah(t):0;break;default:if(t=e.tagName,e=e.namespaceURI)e=ah(e),t=nh(e,t);else switch(t){case"svg":t=1;break;case"math":t=2;break;default:t=0}}Jt(Ie),xt(Ie,t)}function Ua(){Jt(Ie),Jt(An),Jt(Dl)}function mc(t){var e=t.memoizedState;e!==null&&(bn._currentValue=e.memoizedState,xt(Ou,t)),e=Ie.current;var l=nh(e,t.type);e!==l&&(xt(An,t),xt(Ie,l))}function Cu(t){An.current===t&&(Jt(Ie),Jt(An)),Ou.current===t&&(Jt(Ou),bn._currentValue=sl)}var hc,zo;function jl(t){if(hc===void 0)try{throw Error()}catch(l){var e=l.stack.trim().match(/\n( *(at )?)/);hc=e&&e[1]||"",zo=-1)":-1n||h[a]!==z[n]){var A=` +`+h[a].replace(" at new "," at ");return t.displayName&&A.includes("")&&(A=A.replace("",t.displayName)),A}while(1<=a&&0<=n);break}}}finally{vc=!1,Error.prepareStackTrace=l}return(l=t?t.displayName||t.name:"")?jl(l):""}function Wv(t,e){switch(t.tag){case 26:case 27:case 5:return jl(t.type);case 16:return jl("Lazy");case 13:return t.child!==e&&e!==null?jl("Suspense Fallback"):jl("Suspense");case 19:return jl("SuspenseList");case 0:case 15:return yc(t.type,!1);case 11:return yc(t.type.render,!1);case 1:return yc(t.type,!0);case 31:return jl("Activity");case 30:return jl("ViewTransition");default:return""}}function Ro(t){try{var e="",l=null;do e+=Wv(t,l),l=t,t=t.return;while(t);return e}catch(a){return` +Error generating stack: `+a.message+` +`+a.stack}}var gc=Object.prototype.hasOwnProperty,pc=i.unstable_scheduleCallback,Sc=i.unstable_cancelCallback,kv=i.unstable_shouldYield,Iv=i.unstable_requestPaint,ye=i.unstable_now,Pv=i.unstable_getCurrentPriorityLevel,xo=i.unstable_ImmediatePriority,_o=i.unstable_UserBlockingPriority,Du=i.unstable_NormalPriority,ty=i.unstable_LowPriority,Oo=i.unstable_IdlePriority,ey=i.log,ly=i.unstable_setDisableYieldValue,Cn=null,ge=null;function Ul(t){if(typeof ey=="function"&&ly(t),ge&&typeof ge.setStrictMode=="function")try{ge.setStrictMode(Cn,t)}catch{}}var pe=Math.clz32?Math.clz32:uy,ay=Math.log,ny=Math.LN2;function uy(t){return t>>>=0,t===0?32:31-(ay(t)/ny|0)|0}var ju=256,Uu=262144,Mu=4194304;function ca(t){var e=t&42;if(e!==0)return e;switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return t&-t;case 262144:case 524288:case 1048576:case 2097152:return t&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return t&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return t}}function Hu(t,e,l){var a=t.pendingLanes;if(a===0)return 0;var n=0,u=t.suspendedLanes,c=t.pingedLanes;t=t.warmLanes;var o=a&134217727;return o!==0?(a=o&~u,a!==0?n=ca(a):(c&=o,c!==0?n=ca(c):l||(l=o&~t,l!==0&&(n=ca(l))))):(o=a&~u,o!==0?n=ca(o):c!==0?n=ca(c):l||(l=a&~t,l!==0&&(n=ca(l)))),n===0?0:e!==0&&e!==n&&(e&u)===0&&(u=n&-n,l=e&-e,u>=l||u===32&&(l&4194048)!==0)?e:n}function Dn(t,e){return(t.pendingLanes&~(t.suspendedLanes&~t.pingedLanes)&e)===0}function Ao(t,e){(e&8)!==0&&(e|=e&32);var l=t.entangledLanes;if(l!==0)for(t=t.entanglements,l&=e;0l;l++)e.push(t);return e}function jn(t,e){t.pendingLanes|=e,e!==268435456&&(t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0)}function cy(t,e,l,a,n,u){var c=t.pendingLanes;t.pendingLanes=l,t.suspendedLanes=0,t.pingedLanes=0,t.warmLanes=0,t.expiredLanes&=l,t.entangledLanes&=l,t.errorRecoveryDisabledLanes&=l,t.shellSuspendCounter=0;var o=t.entanglements,h=t.expirationTimes,z=t.hiddenUpdates;for(l=c&~l;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Cc=!1;if(hl)try{var Bn={};Object.defineProperty(Bn,"passive",{get:function(){Cc=!0}}),window.addEventListener("test",Bn,Bn),window.removeEventListener("test",Bn,Bn)}catch{Cc=!1}var Ml=null,Dc=null,Gu=null;function Po(){if(Gu)return Gu;var t,e=Dc,l=e.length,a,n="value"in Ml?Ml.value:Ml.textContent,u=n.length;for(t=0;t=Yn),us=" ",is=!1;function cs(t,e){switch(t){case"keyup":return Qy.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function fs(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var Xa=!1;function Zy(t,e){switch(t){case"compositionend":return fs(e);case"keypress":return e.which!==32?null:(is=!0,us);case"textInput":return t=e.data,t===us&&is?null:t;default:return null}}function Ky(t,e){if(Xa)return t==="compositionend"||!Bc&&cs(t,e)?(t=Po(),Gu=Dc=Ml=null,Xa=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function ys(t){for(;t&&t.firstChild;)t=t.firstChild;return t}function gs(t,e){var l=ys(t);t=0;for(var a;l;){if(l.nodeType===3){if(a=t+l.textContent.length,t<=e&&a>=e)return{node:l,offset:e-t};t=a}t:{for(;l;){if(l.nextSibling){l=l.nextSibling;break t}l=l.parentNode}l=void 0}l=ys(l)}}function ps(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?ps(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function Ss(t){t=t!=null&&t.ownerDocument!=null&&t.ownerDocument.defaultView!=null?t.ownerDocument.defaultView:window;for(var e=Yc(t.document);e instanceof t.HTMLIFrameElement;){try{var l=typeof e.contentWindow.location.href=="string"}catch{l=!1}if(l)t=e.contentWindow;else break;e=Yc(t.document)}return e}function wc(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}var t0=hl&&"documentMode"in document&&11>=document.documentMode,Qa=null,Gc=null,Qn=null,Xc=!1;function Es(t,e,l){var a=l.window===l?l.document:l.nodeType===9?l:l.ownerDocument;Xc||Qa==null||Qa!==Yc(a)||(a=Qa,"selectionStart"in a&&wc(a)?a={start:a.selectionStart,end:a.selectionEnd}:(a=(a.ownerDocument&&a.ownerDocument.defaultView||window).getSelection(),a={anchorNode:a.anchorNode,anchorOffset:a.anchorOffset,focusNode:a.focusNode,focusOffset:a.focusOffset}),Qn&&Xn(Qn,a)||(Qn=a,a=Ki(Gc,"onSelect"),0>=c,n-=c,tl=1<<32-pe(e)+n|l<F?(wt=V,V=null):wt=V.sibling;var ot=b(N,V,_[F],j);if(ot===null){V===null&&(V=wt);break}t&&V&&ot.alternate===null&&e(N,V),S=u(ot,S,F),rt===null?G=ot:rt.sibling=ot,rt=ot,V=wt}if(F===_.length)return l(N,V),nt&&pl(N,F),G;if(V===null){for(;F<_.length;F++)V=U(N,_[F],j),V!==null&&(S=u(V,S,F),rt===null?G=V:rt.sibling=V,rt=V);return nt&&pl(N,F),G}for(V=a(V);F<_.length;F++)wt=O(V,N,F,_[F],j),wt!==null&&(t&&(ot=wt.alternate,ot!==null&&V.delete(ot.key===null?F:ot.key)),S=u(wt,S,F),rt===null?G=wt:rt.sibling=wt,rt=wt);return t&&V.forEach(function(ua){return e(N,ua)}),nt&&pl(N,F),G}function X(N,S,_,j){if(_==null)throw Error(r(151));for(var G=null,rt=null,V=S,F=S=0,wt=null,ot=_.next();V!==null&&!ot.done;F++,ot=_.next()){V.index>F?(wt=V,V=null):wt=V.sibling;var ua=b(N,V,ot.value,j);if(ua===null){V===null&&(V=wt);break}t&&V&&ua.alternate===null&&e(N,V),S=u(ua,S,F),rt===null?G=ua:rt.sibling=ua,rt=ua,V=wt}if(ot.done)return l(N,V),nt&&pl(N,F),G;if(V===null){for(;!ot.done;F++,ot=_.next())ot=U(N,ot.value,j),ot!==null&&(S=u(ot,S,F),rt===null?G=ot:rt.sibling=ot,rt=ot);return nt&&pl(N,F),G}for(V=a(V);!ot.done;F++,ot=_.next())ot=O(V,N,F,ot.value,j),ot!==null&&(t&&(wt=ot.alternate,wt!==null&&V.delete(wt.key===null?F:wt.key)),S=u(ot,S,F),rt===null?G=ot:rt.sibling=ot,rt=ot);return t&&V.forEach(function(Zg){return e(N,Zg)}),nt&&pl(N,F),G}function lt(N,S,_,j){if(typeof _=="object"&&_!==null&&_.type===re&&_.key===null&&_.props.ref===void 0&&(_=_.props.children),typeof _=="object"&&_!==null){switch(_.$$typeof){case ee:t:{for(var G=_.key;S!==null;){if(S.key===G){if(G=_.type,G===re){if(S.tag===7){l(N,S.sibling),j=n(S,_.props.children),wl(j,_),j.return=N,N=j;break t}}else if(S.elementType===G||typeof G=="object"&&G!==null&&G.$$typeof===yt&&Ea(G)===S.type){l(N,S.sibling),j=n(S,_.props),wl(j,_),j.return=N,N=j;break t}l(N,S);break}else e(N,S);S=S.sibling}_.type===re?(j=ma(_.props.children,N.mode,j,_.key),wl(j,_),j.return=N,N=j):(j=ku(_.type,_.key,_.props,null,N.mode,j),wl(j,_),j.return=N,N=j)}return c(N);case le:t:{for(G=_.key;S!==null;){if(S.key===G)if(S.tag===4&&S.stateNode.containerInfo===_.containerInfo&&S.stateNode.implementation===_.implementation){l(N,S.sibling),j=n(S,_.children||[]),j.return=N,N=j;break t}else{l(N,S);break}else e(N,S);S=S.sibling}j=Fc(_,N.mode,j),j.return=N,N=j}return c(N);case yt:return _=Ea(_),lt(N,S,_,j)}if(ht(_))return L(N,S,_,j);if(K(_)){if(G=K(_),typeof G!="function")throw Error(r(150));return _=G.call(_),X(N,S,_,j)}if(typeof _.then=="function")return lt(N,S,ci(_),j);if(_.$$typeof===Nt)return lt(N,S,ai(N,_),j);fi(N,_)}return typeof _=="string"&&_!==""||typeof _=="number"||typeof _=="bigint"?(_=""+_,S!==null&&S.tag===6?(l(N,S.sibling),j=n(S,_),j.return=N,N=j):(l(N,S),j=$c(_,N.mode,j),j.return=N,N=j),c(N)):l(N,S)}return function(N,S,_,j){try{Fn=0;var G=lt(N,S,_,j);return Ia=null,G}catch(V){if(V===ka||V===ui)throw V;var rt=se(29,V,null,N.mode);return rt.lanes=j,rt.return=N,rt}}}var Ta=Vs(!0),Zs=Vs(!1),Gl=!1;function uf(t){t.updateQueue={baseState:t.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function cf(t,e){t=t.updateQueue,e.updateQueue===t&&(e.updateQueue={baseState:t.baseState,firstBaseUpdate:t.firstBaseUpdate,lastBaseUpdate:t.lastBaseUpdate,shared:t.shared,callbacks:null})}function Xl(t){return{lane:t,tag:0,payload:null,callback:null,next:null}}function Ql(t,e,l){var a=t.updateQueue;if(a===null)return null;if(a=a.shared,(vt&2)!==0){var n=a.pending;return n===null?e.next=e:(e.next=n.next,n.next=e),a.pending=e,e=Wu(t),Os(t,null,l),e}return Fu(t,a,e,l),Wu(t)}function Wn(t,e,l){if(e=e.updateQueue,e!==null&&(e=e.shared,(l&4194048)!==0)){var a=e.lanes;a&=t.pendingLanes,l|=a,e.lanes=l,jo(t,l)}}function ff(t,e){var l=t.updateQueue,a=t.alternate;if(a!==null&&(a=a.updateQueue,l===a)){var n=null,u=null;if(l=l.firstBaseUpdate,l!==null){do{var c={lane:l.lane,tag:l.tag,payload:l.payload,callback:null,next:null};u===null?n=u=c:u=u.next=c,l=l.next}while(l!==null);u===null?n=u=e:u=u.next=e}else n=u=e;l={baseState:a.baseState,firstBaseUpdate:n,lastBaseUpdate:u,shared:a.shared,callbacks:a.callbacks},t.updateQueue=l;return}t=l.lastBaseUpdate,t===null?l.firstBaseUpdate=e:t.next=e,l.lastBaseUpdate=e}var rf=!1;function kn(){if(rf){var t=Wa;if(t!==null)throw t}}function In(t,e,l,a){rf=!1;var n=t.updateQueue;Gl=!1;var u=n.firstBaseUpdate,c=n.lastBaseUpdate,o=n.shared.pending;if(o!==null){n.shared.pending=null;var h=o,z=h.next;h.next=null,c===null?u=z:c.next=z,c=h;var A=t.alternate;A!==null&&(A=A.updateQueue,o=A.lastBaseUpdate,o!==c&&(o===null?A.firstBaseUpdate=z:o.next=z,A.lastBaseUpdate=h))}if(u!==null){var U=n.baseState;c=0,A=z=h=null,o=u;do{var b=o.lane&-536870913,O=b!==o.lane;if(O?(ft&b)===b:(a&b)===b){b!==0&&b===pa&&(rf=!0),A!==null&&(A=A.next={lane:0,tag:o.tag,payload:o.payload,callback:null,next:null});t:{var L=t,X=o;b=e;var lt=l;switch(X.tag){case 1:if(L=X.payload,typeof L=="function"){U=L.call(lt,U,b);break t}U=L;break t;case 3:L.flags=L.flags&-65537|128;case 0:if(L=X.payload,b=typeof L=="function"?L.call(lt,U,b):L,b==null)break t;U=I({},U,b);break t;case 2:Gl=!0}}b=o.callback,b!==null&&(t.flags|=64,O&&(t.flags|=8192),O=n.callbacks,O===null?n.callbacks=[b]:O.push(b))}else O={lane:b,tag:o.tag,payload:o.payload,callback:o.callback,next:null},A===null?(z=A=O,h=U):A=A.next=O,c|=b;if(o=o.next,o===null){if(o=n.shared.pending,o===null)break;O=o,o=O.next,O.next=null,n.lastBaseUpdate=O,n.shared.pending=null}}while(!0);A===null&&(h=U),n.baseState=h,n.firstBaseUpdate=z,n.lastBaseUpdate=A,u===null&&(n.shared.lanes=0),Wl|=c,t.lanes=c,t.memoizedState=U}}function Ks(t,e){if(typeof t!="function")throw Error(r(191,t));t.call(e)}function Js(t,e){var l=t.callbacks;if(l!==null)for(t.callbacks=null,t=0;tu?u:8;var c=Q.T,o={};o.types=c!==null?c.types:null,Q.T=o,Af(t,!1,e,l);try{var h=n(),z=Q.S;if(z!==null&&z(o,h),h!==null&&typeof h=="object"&&typeof h.then=="function"){var A=s0(h,a);lu(t,e,A,Re(t))}else lu(t,e,a,Re(t))}catch(U){lu(t,e,{then:function(){},status:"rejected",reason:U},Re())}finally{P.p=u,c!==null&&o.types!==null&&(c.types=o.types),Q.T=c}}function g0(){}function _f(t,e,l,a){if(t.tag!==5)throw Error(r(476));var n=Rd(t).queue;zd(t,n,e,sl,l===null?g0:function(){return xd(t),l(a)})}function Rd(t){var e=t.memoizedState;if(e!==null)return e;e={memoizedState:sl,baseState:sl,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Tl,lastRenderedState:sl},next:null};var l={};return e.next={memoizedState:l,baseState:l,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Tl,lastRenderedState:l},next:null},t.memoizedState=e,t=t.alternate,t!==null&&(t.memoizedState=e),e}function xd(t){var e=Rd(t);e.next===null&&(e=t.alternate.memoizedState),lu(t,e.next.queue,{},Re())}function Of(){return Ft(bn)}function _d(){return Bt().memoizedState}function Od(){return Bt().memoizedState}function p0(t){for(var e=t.return;e!==null;){switch(e.tag){case 24:case 3:var l=Re();t=Xl(l);var a=Ql(e,t,l);a!==null&&(ve(a,e,l),Wn(a,e,l)),e={cache:ef()},t.payload=e;return}e=e.return}}function S0(t,e,l){var a=Re();l={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null},pi(t)?Cd(e,l):(l=Kc(t,e,l,a),l!==null&&(ve(l,t,a),Dd(l,e,a)))}function Ad(t,e,l){var a=Re();lu(t,e,l,a)}function lu(t,e,l,a){var n={lane:a,revertLane:0,gesture:null,action:l,hasEagerState:!1,eagerState:null,next:null};if(pi(t))Cd(e,n);else{var u=t.alternate;if(t.lanes===0&&(u===null||u.lanes===0)&&(u=e.lastRenderedReducer,u!==null))try{var c=e.lastRenderedState,o=u(c,l);if(n.hasEagerState=!0,n.eagerState=o,Ee(o,c))return Fu(t,e,n,0),Rt===null&&$u(),!1}catch{}if(l=Kc(t,e,n,a),l!==null)return ve(l,t,a),Dd(l,e,a),!0}return!1}function Af(t,e,l,a){if(a={lane:2,revertLane:Sr(),gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},pi(t)){if(e)throw Error(r(479))}else e=Kc(t,l,a,2),e!==null&&ve(e,t,2)}function pi(t){var e=t.alternate;return t===et||e!==null&&e===et}function Cd(t,e){Pa=si=!0;var l=t.pending;l===null?e.next=e:(e.next=l.next,l.next=e),t.pending=e}function Dd(t,e,l){if((l&4194048)!==0){var a=e.lanes;a&=t.pendingLanes,l|=a,e.lanes=l,jo(t,l)}}var Si={readContext:Ft,use:hi,useCallback:Mt,useContext:Mt,useEffect:Mt,useImperativeHandle:Mt,useLayoutEffect:Mt,useInsertionEffect:Mt,useMemo:Mt,useReducer:Mt,useRef:Mt,useState:Mt,useDebugValue:Mt,useDeferredValue:Mt,useTransition:Mt,useSyncExternalStore:Mt,useId:Mt,useHostTransitionStatus:Mt,useFormState:Mt,useActionState:Mt,useOptimistic:Mt,useMemoCache:Mt,useCacheRefresh:Mt,useEffectEvent:Mt},jd={readContext:Ft,use:hi,useCallback:function(t,e){return ie().memoizedState=[t,e===void 0?null:e],t},useContext:Ft,useEffect:vd,useImperativeHandle:function(t,e,l){l=l!=null?l.concat([t]):null,yi(4194308,4,Sd.bind(null,e,t),l)},useLayoutEffect:function(t,e){return yi(4194308,4,t,e)},useInsertionEffect:function(t,e){yi(4,2,t,e)},useMemo:function(t,e){var l=ie();e=e===void 0?null:e;var a=t();if(Na){Ul(!0);try{t()}finally{Ul(!1)}}return l.memoizedState=[a,e],a},useReducer:function(t,e,l){var a=ie();if(l!==void 0){var n=l(e);if(Na){Ul(!0);try{l(e)}finally{Ul(!1)}}}else n=e;return a.memoizedState=a.baseState=n,t={pending:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:n},a.queue=t,t=t.dispatch=S0.bind(null,et,t),[a.memoizedState,t]},useRef:function(t){var e=ie();return t={current:t},e.memoizedState=t},useState:function(t){t=Tf(t);var e=t.queue,l=Ad.bind(null,et,e);return e.dispatch=l,[t.memoizedState,l]},useDebugValue:Rf,useDeferredValue:function(t,e){var l=ie();return xf(l,t,e)},useTransition:function(){var t=Tf(!1);return t=zd.bind(null,et,t.queue,!0,!1),ie().memoizedState=t,[!1,t]},useSyncExternalStore:function(t,e,l){var a=et,n=ie();if(nt){if(l===void 0)throw Error(r(407));l=l()}else{if(l=e(),Rt===null)throw Error(r(349));(ft&127)!==0||Ps(a,e,l)}n.memoizedState=l;var u={value:l,getSnapshot:e};return n.queue=u,vd(ed.bind(null,a,u,t),[t]),a.flags|=2048,en(9,{destroy:void 0},td.bind(null,a,u,l,e),null),l},useId:function(){var t=ie(),e=Rt.identifierPrefix;if(nt){var l=el,a=tl;l=(a&~(1<<32-pe(a)-1)).toString(32)+l,e="_"+e+"R_"+l,l=di++,0<\/script>",u=u.removeChild(u.firstChild);break;case"select":u=typeof a.is=="string"?c.createElement("select",{is:a.is}):c.createElement("select"),a.multiple?u.multiple=!0:a.size&&(u.size=a.size);break;default:u=typeof a.is=="string"?c.createElement(n,{is:a.is}):c.createElement(n)}}u[$t]=e,u[oe]=a;t:for(c=e.child;c!==null;){if(c.tag===5||c.tag===6)u.appendChild(c.stateNode);else if(c.tag!==4&&c.tag!==27&&c.child!==null){c.child.return=c,c=c.child;continue}if(c===e)break t;for(;c.sibling===null;){if(c.return===null||c.return===e)break t;c=c.return}c.sibling.return=c.return,c=c.sibling}e.stateNode=u;t:switch(Pt(u,n,a),n){case"button":case"input":case"select":case"textarea":a=!!a.autoFocus;break t;case"img":a=!0;break t;default:a=!1}a&&zl(e)}}return Ot(e),e.subtreeFlags&=-33554433,Xf(e,e.type,t===null?null:t.memoizedProps,e.pendingProps,l),null;case 6:if(t&&e.stateNode!=null)t.memoizedProps!==a&&zl(e);else{if(typeof a!="string"&&e.stateNode===null)throw Error(r(166));if(t=Dl.current,Fa(e)){if(t=e.stateNode,l=e.memoizedProps,a=null,n=Vt,n!==null)switch(n.tag){case 27:case 5:a=n.memoizedProps}t[$t]=e,t=!!(t.nodeValue===l||a!==null&&a.suppressHydrationWarning===!0||eh(t.nodeValue,l)),t||ql(e,!0)}else t=vu(t).createTextNode(a),t[$t]=e,e.stateNode=t}return Ot(e),null;case 31:if(l=e.memoizedState,t===null||t.memoizedState!==null){if(a=Fa(e),l!==null){if(t===null){if(!a)throw Error(r(318));if(t=e.memoizedState,t=t!==null?t.dehydrated:null,!t)throw Error(r(557));t[$t]=e}else ha(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Ot(e),t=!1}else l=Ic(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=l),t=!0;if(!t)return e.flags&256?(be(e),e):(be(e),null);if((e.flags&128)!==0)throw Error(r(558))}return Ot(e),null;case 13:if(a=e.memoizedState,t===null||t.memoizedState!==null&&t.memoizedState.dehydrated!==null){if(n=Fa(e),a!==null&&a.dehydrated!==null){if(t===null){if(!n)throw Error(r(318));if(n=e.memoizedState,n=n!==null?n.dehydrated:null,!n)throw Error(r(317));n[$t]=e}else ha(),(e.flags&128)===0&&(e.memoizedState=null),e.flags|=4;Ot(e),n=!1}else n=Ic(),t!==null&&t.memoizedState!==null&&(t.memoizedState.hydrationErrors=n),n=!0;if(!n)return e.flags&256?(be(e),e):(be(e),null)}return be(e),(e.flags&128)!==0?(e.lanes=l,e):(l=a!==null,t=t!==null&&t.memoizedState!==null,l&&(a=e.child,n=null,a.alternate!==null&&a.alternate.memoizedState!==null&&a.alternate.memoizedState.cachePool!==null&&(n=a.alternate.memoizedState.cachePool.pool),u=null,a.memoizedState!==null&&a.memoizedState.cachePool!==null&&(u=a.memoizedState.cachePool.pool),u!==n&&(a.flags|=2048)),l!==t&&l&&(e.child.flags|=8192),Ri(e,e.updateQueue),Ot(e),null);case 4:return Ua(),t===null&&Nr(e.stateNode.containerInfo),e.flags|=67108864,Ot(e),null;case 10:return El(e.type),Ot(e),null;case 19:if(mf(e),a=e.memoizedState,a===null)return Ot(e),null;if(n=(e.flags&128)!==0,u=a.rendering,u===null)if(n)nu(a,!1);else{if(Ht!==0||t!==null&&(t.flags&128)!==0)for(t=e.child;t!==null;){if(u=oi(t),u!==null){for(e.flags|=128,nu(a,!1),t=u.updateQueue,e.updateQueue=t,Ri(e,t),e.subtreeFlags=0,t=l,l=e.child;l!==null;)As(l,t),l=l.sibling;return Pn(e,kt.current&1|2),nt&&pl(e,a.treeForkCount),e.child}t=t.sibling}a.tail!==null&&ye()>Li&&(e.flags|=128,n=!0,nu(a,!1),e.lanes=4194304)}else{if(!n)if(t=oi(u),t!==null){if(e.flags|=128,n=!0,t=t.updateQueue,e.updateQueue=t,Ri(e,t),nu(a,!0),a.tail===null&&a.tailMode!=="collapsed"&&a.tailMode!=="visible"&&!u.alternate&&!nt)return Ot(e),null}else 2*ye()-a.renderingStartTime>Li&&l!==536870912&&(e.flags|=128,n=!0,nu(a,!1),e.lanes=4194304);a.isBackwards?(u.sibling=e.child,e.child=u):(t=a.last,t!==null?t.sibling=u:e.child=u,a.last=u)}if(a.tail!==null){t=a.tail;t:{for(l=t;l!==null;){if(l.alternate!==null){l=!1;break t}l=l.sibling}l=!0}return a.rendering=t,a.tail=t.sibling,a.renderingStartTime=ye(),t.sibling=null,u=kt.current,u=n?u&1|2:u&1,a.tailMode==="visible"||a.tailMode==="collapsed"||!l||nt?Pn(e,u):(l=u,xt(Wt,e),xt(kt,l),ae===null&&(ae=e)),nt&&pl(e,a.treeForkCount),t}return Ot(e),null;case 22:case 23:return be(e),sf(),a=e.memoizedState!==null,t!==null?t.memoizedState!==null!==a&&(e.flags|=8192):a&&(e.flags|=8192),a?(l&536870912)!==0&&(e.flags&128)===0&&(Ot(e),e.subtreeFlags&6&&(e.flags|=8192)):Ot(e),l=e.updateQueue,l!==null&&Ri(e,l.retryQueue),l=null,t!==null&&t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(l=t.memoizedState.cachePool.pool),a=null,e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(a=e.memoizedState.cachePool.pool),a!==l&&(e.flags|=2048),t!==null&&Jt(Sa),null;case 24:return l=null,t!==null&&(l=t.memoizedState.cache),e.memoizedState.cache!==l&&(e.flags|=2048),El(Lt),Ot(e),null;case 25:return null;case 30:return e.flags|=33554432,Ot(e),null}throw Error(r(156,e.tag))}function x0(t,e){switch(Wc(e),e.tag){case 1:return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return El(Lt),Ua(),t=e.flags,(t&65536)!==0&&(t&128)===0?(e.flags=t&-65537|128,e):null;case 26:case 27:case 5:return Cu(e),null;case 31:if(e.memoizedState!==null){if(be(e),e.alternate===null)throw Error(r(340));ha()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 13:if(be(e),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(r(340));ha()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return mf(e),t=e.flags,t&65536?(e.flags=t&-65537|128,t=e.memoizedState,t!==null&&(t.rendering=null,t.tail=null),e.flags|=4,e):null;case 4:return Ua(),null;case 10:return El(e.type),null;case 22:case 23:return be(e),sf(),t!==null&&Jt(Sa),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 24:return El(Lt),null;case 25:return null;default:return null}}function am(t,e){switch(Wc(e),e.tag){case 3:El(Lt),Ua();break;case 26:case 27:case 5:Cu(e);break;case 4:Ua();break;case 31:e.memoizedState!==null&&be(e);break;case 13:be(e);break;case 19:mf(e);break;case 10:El(e.type);break;case 22:case 23:be(e),sf(),t!==null&&Jt(Sa);break;case 24:El(Lt)}}function uu(t,e){try{var l=e.updateQueue,a=l!==null?l.lastEffect:null;if(a!==null){var n=a.next;l=n;do{if((l.tag&t)===t){a=void 0;var u=l.create,c=l.inst;a=u(),c.destroy=a}l=l.next}while(l!==n)}}catch(o){St(e,e.return,o)}}function Jl(t,e,l){try{var a=e.updateQueue,n=a!==null?a.lastEffect:null;if(n!==null){var u=n.next;a=u;do{if((a.tag&t)===t){var c=a.inst,o=c.destroy;if(o!==void 0){c.destroy=void 0,n=e;var h=l,z=o;try{z()}catch(A){St(n,h,A)}}}a=a.next}while(a!==u)}}catch(A){St(e,e.return,A)}}function nm(t){var e=t.updateQueue;if(e!==null){var l=t.stateNode;try{Js(e,l)}catch(a){St(t,t.return,a)}}}function um(t,e,l){l.props=za(t.type,t.memoizedProps),l.state=t.memoizedState;try{l.componentWillUnmount()}catch(a){St(t,e,a)}}function ll(t,e){try{var l=t.ref;if(l!==null){switch(t.tag){case 26:case 27:case 5:var a=t.stateNode;break;case 30:var n=t.stateNode,u=vl(t.memoizedProps,n);(n.ref===null||n.ref.name!==u)&&(n.ref=dh(u)),a=n.ref;break;case 7:if(t.stateNode===null){var c=new xe(t);y(t.child,!1,yg,c,void 0,void 0),t.stateNode=c}a=t.stateNode;break;default:a=t.stateNode}typeof l=="function"?t.refCleanup=l(a):l.current=a}}catch(o){St(t,e,o)}}function It(t,e){var l=t.ref,a=t.refCleanup;if(l!==null)if(typeof a=="function")try{a()}catch(n){St(t,e,n)}finally{t.refCleanup=null,t=t.alternate,t!=null&&(t.refCleanup=null)}else if(typeof l=="function")try{l(null)}catch(n){St(t,e,n)}else l.current=null}function xi(t,e){if((t.tag===5||t.tag===27||t.tag===6)&&t.alternate===null&&e!==null)for(var l=0;l title"))),Pt(a,e,l),a[$t]=t,Qt(a),e=a;break t;case"link":if(u=Ah("link","href",n).get(e+(l.href||""))){for(c=0;clt&&(c=lt,lt=X,X=c);var N=gs(o,X),S=gs(o,lt);if(N&&S&&(O.rangeCount!==1||O.anchorNode!==N.node||O.anchorOffset!==N.offset||O.focusNode!==S.node||O.focusOffset!==S.offset)){var _=U.createRange();_.setStart(N.node,N.offset),O.removeAllRanges(),X>lt?(O.addRange(_),O.extend(S.node,S.offset)):(_.setEnd(S.node,S.offset),O.addRange(_))}}}}for(U=[],O=o;O=O.parentNode;)O.nodeType===1&&U.push({element:O,left:O.scrollLeft,top:O.scrollTop});for(typeof o.focus=="function"&&o.focus(),o=0;ol?32:l,Q.T=null,l=rr,rr=null;var u=Ke,c=fl;if(jt=0,Oa=Ke=null,fl=0,(vt&6)!==0)throw Error(r(331));var o=vt;if(vt|=4,Om(u.current),Rm(u,u.current,c,l),vt=o,du(0,!1),ge&&typeof ge.onPostCommitFiberRoot=="function")try{ge.onPostCommitFiberRoot(Cn,u)}catch{}return!0}finally{P.p=n,Q.T=a,Qm(t,e)}}function Vm(t,e,l){e=De(l,e),e=jf(t.stateNode,e,2),t=Ql(t,e,2),t!==null&&(jn(t,2),rl(t))}function St(t,e,l){if(t.tag===3)Vm(t,t,l);else for(;e!==null;){if(e.tag===3){Vm(e,t,l);break}else if(e.tag===1){var a=e.stateNode;if(typeof e.type.getDerivedStateFromError=="function"||typeof a.componentDidCatch=="function"&&(kl===null||!kl.has(a))){t=De(l,t),l=wd(2),a=Ql(e,l,2),a!==null&&(Gd(l,a,e,t),jn(a,2),rl(a));break}}e=e.return}}function yr(t,e,l){var a=t.pingCache;if(a===null){a=t.pingCache=new C0;var n=new Set;a.set(e,n)}else n=a.get(e),n===void 0&&(n=new Set,a.set(e,n));n.has(l)||(ir=!0,n.add(l),t=q0.bind(null,t,e,l),e.then(t,t))}function q0(t,e,l){var a=t.pingCache;a!==null&&a.delete(e),t.pingedLanes|=t.suspendedLanes&l,t.warmLanes&=~l,Rt===t&&(ft&l)===l&&((Ht===4||Ht===3&&(ft&62914560)===ft&&300>ye()-Bi)&&(vt&2)===0?mn(t,0):Hi|=l,fn===ft&&(fn=0)),rl(t)}function Zm(t,e){e===0&&(e=Co()),t=da(t,e),t!==null&&(jn(t,e),rl(t))}function Y0(t){var e=t.memoizedState,l=0;e!==null&&(l=e.retryLane),Zm(t,l)}function w0(t,e){var l=0;switch(t.tag){case 31:case 13:var a=t.stateNode,n=t.memoizedState;n!==null&&(l=n.retryLane);break;case 19:a=t.stateNode;break;case 22:a=t.stateNode._retryCache;break;default:throw Error(r(314))}a!==null&&a.delete(e),Zm(t,l)}function G0(t,e){return pc(t,e)}var vn=null,yn=null,gr=!1,Vi=!1,pr=!1,Pl=0;function rl(t){t!==yn&&t.next===null&&(yn===null?vn=yn=t:yn=yn.next=t),Vi=!0,gr||(gr=!0,Q0())}function du(t,e){if(!pr&&Vi){pr=!0;do for(var l=!1,a=vn;a!==null;){if(t!==0){var n=a.pendingLanes;if(n===0)var u=0;else{var c=a.suspendedLanes,o=a.pingedLanes;u=(1<<31-pe(42|t)+1)-1,u&=n&~(c&~o),u=u&201326741?u&201326741|1:u?u|2:0}u!==0&&(l=!0,Fm(a,u))}else u=ft,u=Hu(a,a===Rt?u:0,a.cancelPendingCommit!==null||a.timeoutHandle!==-1),(u&3)===0||Dn(a,u)||(l=!0,Fm(a,u));a=a.next}while(l);pr=!1}}function X0(){Km()}function Km(){Vi=gr=!1;var t=0;Pl!==0&&tg()&&(t=Pl);for(var e=ye(),l=null,a=vn;a!==null;){var n=a.next,u=Jm(a,e);u===0?(a.next=null,l===null?vn=n:l.next=n,n===null&&(yn=l)):(l=a,(t!==0||(u&3)!==0)&&(Vi=!0)),a=n}jt!==0&&jt!==5||du(t),Pl!==0&&(Pl=0)}function Jm(t,e){for(var l=t.suspendedLanes,a=t.pingedLanes,n=t.expirationTimes,u=t.pendingLanes&-62914561;0o)break;var A=h.transferSize,U=h.initiatorType;A&&lh(U)&&(h=h.responseEnd,c+=A*(hFi){X.length=L;break}_=new Promise(ig.bind(_)),X.push(_)}}}if(0"u"?null:document;function Rh(t,e,l){var a=pn;if(a&&typeof e=="string"&&e){var n=Ae(e);n='link[rel="'+t+'"][href="'+n+'"]',typeof l=="string"&&(n+='[crossorigin="'+l+'"]'),zh.has(n)||(zh.add(n),t={rel:t,crossOrigin:l,href:e},a.querySelector(n)===null&&(e=a.createElement("link"),Pt(e,"link",t),Qt(e),a.head.appendChild(e)))}}function Rg(t){xl.D(t),Rh("dns-prefetch",t,null)}function xg(t,e){xl.C(t,e),Rh("preconnect",t,e)}function _g(t,e,l){xl.L(t,e,l);var a=pn;if(a&&t&&e){var n='link[rel="preload"][as="'+Ae(e)+'"]';e==="image"&&l&&l.imageSrcSet?(n+='[imagesrcset="'+Ae(l.imageSrcSet)+'"]',typeof l.imageSizes=="string"&&(n+='[imagesizes="'+Ae(l.imageSizes)+'"]')):n+='[href="'+Ae(t)+'"]';var u=n;switch(e){case"style":u=Sn(t);break;case"script":u=En(t)}if(!(Le.has(u)||(t=I({rel:"preload",href:e==="image"&&l&&l.imageSrcSet?void 0:t,as:e},l),Le.set(u,t),a.querySelector(n)!==null||e==="style"&&a.querySelector(gu(u))||e==="script"&&a.querySelector(pu(u))))){var c=a.createElement("link");Pt(c,"link",t),e==="style"&&(c[Bu]=!0,c.onload=c.onerror=function(){qo(c)}),Qt(c),a.head.appendChild(c)}}}function Og(t,e){xl.m(t,e);var l=pn;if(l&&t){var a=e&&typeof e.as=="string"?e.as:"script",n='link[rel="modulepreload"][as="'+Ae(a)+'"][href="'+Ae(t)+'"]',u=n;switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":u=En(t)}if(!Le.has(u)&&(t=I({rel:"modulepreload",href:t},e),Le.set(u,t),l.querySelector(n)===null)){switch(a){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(l.querySelector(pu(u)))return}a=l.createElement("link"),Pt(a,"link",t),Qt(a),l.head.appendChild(a)}}}function Ag(t,e,l){xl.S(t,e,l);var a=pn;if(a&&t){var n=Ba(a).hoistableStyles,u=Sn(t);e=e||"default";var c=n.get(u);if(!c){var o={loading:0,preload:null};if(c=a.querySelector(gu(u)))o.loading=5;else{t=I({rel:"stylesheet",href:t,"data-precedence":e},l),(l=Le.get(u))&&Yr(t,l);var h=c=a.createElement("link");Qt(h),Pt(h,"link",t),h._p=new Promise(function(z,A){h.onload=z,h.onerror=A}),h.addEventListener("load",function(){o.loading|=1}),h.addEventListener("error",function(){o.loading|=2}),o.loading|=4,Ji(c,e,a)}c={type:"stylesheet",instance:c,count:1,state:o},n.set(u,c)}}}function Cg(t,e){xl.X(t,e);var l=pn;if(l&&t){var a=Ba(l).hoistableScripts,n=En(t),u=a.get(n);u||(u=l.querySelector(pu(n)),u||(t=I({src:t,async:!0},e),(e=Le.get(n))&&wr(t,e),u=l.createElement("script"),Qt(u),Pt(u,"link",t),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function Dg(t,e){xl.M(t,e);var l=pn;if(l&&t){var a=Ba(l).hoistableScripts,n=En(t),u=a.get(n);u||(u=l.querySelector(pu(n)),u||(t=I({src:t,async:!0,type:"module"},e),(e=Le.get(n))&&wr(t,e),u=l.createElement("script"),Qt(u),Pt(u,"link",t),l.head.appendChild(u)),u={type:"script",instance:u,count:1,state:null},a.set(n,u))}}function xh(t,e,l,a){var n=(n=Dl.current)?yu(n):null;if(!n)throw Error(r(446));switch(t){case"meta":case"title":return null;case"style":return typeof l.precedence=="string"&&typeof l.href=="string"?(l=Sn(l.href),e=Ba(n).hoistableStyles,a=e.get(l),a||(a={type:"style",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};case"link":if(l.rel==="stylesheet"&&typeof l.href=="string"&&typeof l.precedence=="string"){t=Sn(l.href);var u=Ba(n).hoistableStyles,c=u.get(t);if(c||(n=n.ownerDocument||n,c={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},u.set(t,c),(u=n.querySelector(gu(t)))?u._p||(c.instance=u,c.state.loading=5):(u=Le.get(t),u||(u={rel:"preload",as:"style",href:l.href,crossOrigin:l.crossOrigin,integrity:l.integrity,media:l.media,hrefLang:l.hrefLang,referrerPolicy:l.referrerPolicy},Le.set(t,u)),jg(n,t,u,c.state))),e&&a===null)throw Error(r(528,""));return c}if(e&&a!==null)throw Error(r(529,""));return null;case"script":return e=l.async,l=l.src,typeof l=="string"&&e&&typeof e!="function"&&typeof e!="symbol"?(l=En(l),e=Ba(n).hoistableScripts,a=e.get(l),a||(a={type:"script",instance:null,count:0,state:null},e.set(l,a)),a):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,t))}}function Sn(t){return'href="'+Ae(t)+'"'}function gu(t){return'link[rel="stylesheet"]['+t+"]"}function _h(t){return I({},t,{"data-precedence":t.precedence,precedence:null})}function jg(t,e,l,a){if(e=t.querySelector('link[rel="preload"][as="style"]['+e+"]")){if(e[Bu]!==!0){a.loading=1;return}}else e=t.createElement("link"),e[Bu]=!0,e.onload=e.onerror=qo.bind(null,e),Pt(e,"link",l),Qt(e),t.head.appendChild(e);a.preload=e,e.addEventListener("load",function(){return a.loading|=1}),e.addEventListener("error",function(){return a.loading|=2})}function En(t){return'[src="'+Ae(t)+'"]'}function pu(t){return"script[async]"+t}function Oh(t,e,l){if(e.count++,e.instance===null)switch(e.type){case"style":var a=t.querySelector('style[data-href~="'+Ae(l.href)+'"]');if(a)return e.instance=a,Qt(a),a;var n=I({},l,{"data-href":l.href,"data-precedence":l.precedence,href:null,precedence:null});return a=(t.ownerDocument||t).createElement("style"),Qt(a),Pt(a,"style",n),Ji(a,l.precedence,t),e.instance=a;case"stylesheet":n=Sn(l.href);var u=t.querySelector(gu(n));if(u)return e.state.loading|=4,e.instance=u,Qt(u),u;a=_h(l),(n=Le.get(n))&&Yr(a,n),u=(t.ownerDocument||t).createElement("link"),Qt(u);var c=u;return c._p=new Promise(function(o,h){c.onload=o,c.onerror=h}),Pt(u,"link",a),e.state.loading|=4,Ji(u,l.precedence,t),e.instance=u;case"script":return u=En(l.src),(n=t.querySelector(pu(u)))?(e.instance=n,Qt(n),n):(a=l,(n=Le.get(u))&&(a=I({},l),wr(a,n)),t=t.ownerDocument||t,n=t.createElement("script"),Qt(n),Pt(n,"link",a),t.head.appendChild(n),e.instance=n);case"void":return null;default:throw Error(r(443,e.type))}else e.type==="stylesheet"&&(e.state.loading&4)===0&&(a=e.instance,e.state.loading|=4,Ji(a,l.precedence,t));return e.instance}function Ji(t,e,l){for(var a=l.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),n=a.length?a[a.length-1]:null,u=n,c=0;c title"):null)}function Ug(t,e,l){if(l===1||e.itemProp!=null)return!1;switch(t){case"meta":case"title":return!0;case"style":if(typeof e.precedence!="string"||typeof e.href!="string"||e.href==="")break;return!0;case"link":if(typeof e.rel!="string"||typeof e.href!="string"||e.href===""||e.onLoad||e.onError)break;return e.rel==="stylesheet"?(t=e.disabled,typeof e.precedence=="string"&&t==null):!0;case"script":if(e.async&&typeof e.async!="function"&&typeof e.async!="symbol"&&!e.onLoad&&!e.onError&&e.src&&typeof e.src=="string")return!0}return!1}function Ch(t,e){return t==="img"&&e.src!=null&&e.src!==""&&e.onLoad==null&&e.loading!=="lazy"}function Dh(t){return!(t.type==="stylesheet"&&(t.state.loading&3)===0)}function jh(t){return(t.width||100)*(t.height||100)*(typeof devicePixelRatio=="number"?devicePixelRatio:1)*.25}function Uh(t,e){typeof e.decode=="function"&&(t.imgCount++,e.complete||(t.imgBytes+=jh(e),t.suspenseyImages.push(e)),t=Bg.bind(t),e.decode().then(t,t))}function Mg(t,e,l,a){if(l.type==="stylesheet"&&(typeof a.media!="string"||matchMedia(a.media).matches!==!1)&&(l.state.loading&4)===0){if(l.instance===null){var n=Sn(a.href),u=e.querySelector(gu(n));if(u){e=u._p,e!==null&&typeof e=="object"&&typeof e.then=="function"&&(t.count++,t=Su.bind(t),e.then(t,t)),l.state.loading|=4,l.instance=u,Qt(u);return}u=e.ownerDocument||e,a=_h(a),(n=Le.get(n))&&Yr(a,n),u=u.createElement("link"),Qt(u);var c=u;c._p=new Promise(function(o,h){c.onload=o,c.onerror=h}),Pt(u,"link",a),l.instance=u}t.stylesheets===null&&(t.stylesheets=new Map),t.stylesheets.set(l,e),(e=l.state.preload)&&(l.state.loading&3)===0&&(t.count++,l=Su.bind(t),e.addEventListener("load",l),e.addEventListener("error",l))}}var Fi=0;function Hg(t,e){return t.stylesheets&&t.count===0&&ki(t,t.stylesheets),0Fi?50:800)+e);return t.unsuspend=l,function(){t.unsuspend=null,clearTimeout(a),clearTimeout(n)}}:null}function Mh(t){if(t.count===0&&(t.imgCount===0||!t.waitingForImages)){if(t.stylesheets)ki(t,t.stylesheets);else if(t.unsuspend){var e=t.unsuspend;t.unsuspend=null,e()}}}function Su(){this.count--,Mh(this)}function Bg(){this.imgCount--,Mh(this)}var Wi=null;function ki(t,e){t.stylesheets=null,t.unsuspend!==null&&(t.count++,Wi=new Map,e.forEach(Lg,t),Wi=null,Su.call(t))}function Lg(t,e){if(!(e.state.loading&4)){var l=Wi.get(t);if(l)var a=l.get(null);else{l=new Map,Wi.set(t,l);for(var n=t.querySelectorAll("link[data-precedence],style[data-precedence]"),u=0;u"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(i)}catch(f){console.error(f)}}return i(),Wr.exports=Pg(),Wr.exports}var e1=t1();var so=/^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i,yv=/^[\\/]{2}/;function l1(i,f){return f+i.replace(/\\/g,"/")}var nv="popstate";function uv(i){return typeof i=="object"&&i!=null&&"pathname"in i&&"search"in i&&"hash"in i&&"state"in i&&"key"in i}function a1(i={}){function f(r,d){let m=d.state?.masked,{pathname:v,search:g,hash:T}=m||r.location;return uo("",{pathname:v,search:g,hash:T},d.state&&d.state.usr||null,d.state&&d.state.key||"default",m?{pathname:r.location.pathname,search:r.location.search,hash:r.location.hash}:void 0)}function s(r,d){return typeof d=="string"?d:Ca(d)}return u1(f,s,null,i)}function Dt(i,f){if(i===!1||i===null||typeof i>"u")throw new Error(f)}function qe(i,f){if(!i){typeof console<"u"&&console.warn(f);try{throw new Error(f)}catch{}}}function n1(){return Math.random().toString(36).substring(2,10)}function iv(i,f){return{usr:i.state,key:i.key,idx:f,masked:i.mask?{pathname:i.pathname,search:i.search,hash:i.hash}:void 0}}function uo(i,f,s=null,r,d){return{pathname:typeof i=="string"?i:i.pathname,search:"",hash:"",...typeof f=="string"?Rn(f):f,state:s,key:f&&f.key||r||n1(),mask:d}}function Ca({pathname:i="/",search:f="",hash:s=""}){return f&&f!=="?"&&(i+=f.charAt(0)==="?"?f:"?"+f),s&&s!=="#"&&(i+=s.charAt(0)==="#"?s:"#"+s),i}function Rn(i){let f={};if(i){let s=i.indexOf("#");s>=0&&(f.hash=i.substring(s),i=i.substring(0,s));let r=i.indexOf("?");r>=0&&(f.search=i.substring(r),i=i.substring(0,r)),i&&(f.pathname=i)}return f}function u1(i,f,s,r={}){let{window:d=document.defaultView,v5Compat:m=!1}=r,v=d.history,g="POP",T=null,C=x();C==null&&(C=0,v.replaceState({...v.state,idx:C},""));function x(){return(v.state||{idx:null}).idx}function y(){g="POP";let M=x(),J=M==null?null:M-C;C=M,T&&T({action:g,location:Y.location,delta:J})}function D(M,J){g="PUSH";let $=uv(M)?M:uo(Y.location,M,J);C=x()+1;let at=iv($,C),At=Y.createHref($.mask||$);try{v.pushState(at,"",At)}catch(Tt){if(Tt instanceof DOMException&&Tt.name==="DataCloneError")throw Tt;d.location.assign(At)}m&&T&&T({action:g,location:Y.location,delta:1})}function B(M,J){g="REPLACE";let $=uv(M)?M:uo(Y.location,M,J);C=x();let at=iv($,C),At=Y.createHref($.mask||$);v.replaceState(at,"",At),m&&T&&T({action:g,location:Y.location,delta:0})}function q(M){return i1(d,M)}let Y={get action(){return g},get location(){return i(d,v)},listen(M){if(T)throw new Error("A history only accepts one active listener");return d.addEventListener(nv,y),T=M,()=>{d.removeEventListener(nv,y),T=null}},createHref(M){return f(d,M)},createURL:q,encodeLocation(M){let J=q(M);return{pathname:J.pathname,search:J.search,hash:J.hash}},push:D,replace:B,go(M){return v.go(M)}};return Y}function i1(i,f,s=!1){let r="http://localhost";i&&(r=i.location.origin!=="null"?i.location.origin:i.location.href),Dt(r,"No window.location.(origin|href) available to create URL");let d=typeof f=="string"?f:Ca(f);return d=d.replace(/ $/,"%20"),!s&&yv.test(d)&&(d=r+d),new URL(d,r)}function gv(i,f,s="/"){return c1(i,f,s,!1)}function c1(i,f,s,r,d){let m=typeof f=="string"?Rn(f):f,v=Al(m.pathname||"/",s);if(v==null)return null;let g=f1(i),T=null,C=S1(v);for(let x=0;T==null&&x{let x={relativePath:C===void 0?v.path||"":C,caseSensitive:v.caseSensitive===!0,childrenIndex:g,route:v};if(x.relativePath.startsWith("/")){if(!x.relativePath.startsWith(r)&&T)return;Dt(x.relativePath.startsWith(r),`Absolute route path "${x.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),x.relativePath=x.relativePath.slice(r.length)}let y=$e([r,x.relativePath]),D=s.concat(x);v.children&&v.children.length>0&&(Dt(v.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${y}".`),pv(v.children,f,D,y,T)),!(v.path==null&&!v.index)&&f.push({path:y,score:y1(y,v.index),routesMeta:D.map((B,q)=>{let[Y,M]=bv(B.relativePath,B.caseSensitive,q===D.length-1);return{...B,matcher:Y,compiledParams:M}})})};return i.forEach((v,g)=>{if(v.path===""||!v.path?.includes("?"))m(v,g);else for(let T of Sv(v.path))m(v,g,!0,T)}),f}function Sv(i){let f=i.split("/");if(f.length===0)return[];let[s,...r]=f,d=s.endsWith("?"),m=s.replace(/\?$/,"");if(r.length===0)return d?[m,""]:[m];let v=Sv(r.join("/")),g=[];return g.push(...v.map(T=>T===""?m:[m,T].join("/"))),d&&g.push(...v),g.map(T=>i.startsWith("/")&&T===""?"/":T)}function r1(i){i.sort((f,s)=>f.score!==s.score?s.score-f.score:g1(f.routesMeta.map(r=>r.childrenIndex),s.routesMeta.map(r=>r.childrenIndex)))}var o1=/^:[\w-]+$/,s1=3,d1=2,m1=1,h1=10,v1=-2,cv=i=>i==="*";function y1(i,f){let s=i.split("/"),r=s.length;return s.some(cv)&&(r+=v1),f&&(r+=d1),s.filter(d=>!cv(d)).reduce((d,m)=>d+(o1.test(m)?s1:m===""?m1:h1),r)}function g1(i,f){return i.length===f.length&&i.slice(0,-1).every((r,d)=>r===f[d])?i[i.length-1]-f[f.length-1]:0}function p1(i,f,s=!1){let{routesMeta:r}=i,d={},m="/",v=[];for(let g=0;g{if(x==="*"){let q=g[D]||"";v=zn(m.slice(0,m.length-q.length),1)}const B=g[D];return y&&!B?C[x]=void 0:C[x]=(B||"").replace(/%2F/g,"/"),C},{}),pathname:m,pathnameBase:v,pattern:i}}function bv(i,f=!1,s=!0){qe(i==="*"||!i.endsWith("*")||i.endsWith("/*"),`Route path "${i}" will be treated as if it were "${i.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${i.replace(/\*$/,"/*")}".`);let r=[],d="^"+i.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(v,g,T,C,x)=>{if(r.push({paramName:g,isOptional:T!=null}),T){let y=x.charAt(C+v.length);return y&&y!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return i.endsWith("*")?(r.push({paramName:"*"}),d+=i==="*"||i==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):s?d+="\\/*$":i!==""&&i!=="/"&&(d+="(?:(?=\\/|$))"),[new RegExp(d,f?void 0:"i"),r]}function S1(i){try{return i.split("/").map(f=>decodeURIComponent(f).replace(/\//g,"%2F")).join("/")}catch(f){return qe(!1,`The URL path "${i}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${f}).`),i}}function Al(i,f){if(f==="/")return i;if(!i.toLowerCase().startsWith(f.toLowerCase()))return null;let s=f.endsWith("/")?f.length-1:f.length,r=i.charAt(s);return r&&r!=="/"?null:i.slice(s)||"/"}function E1(i,f="/"){let{pathname:s,search:r="",hash:d=""}=typeof i=="string"?Rn(i):i,m;return s?(s=Tv(s),s.startsWith("/")||s.startsWith("\\")?m=fv(s.substring(1),"/"):m=fv(s,f)):m=f,{pathname:m,search:N1(r),hash:z1(d)}}function fv(i,f){let s=zn(f).split("/");return i.split("/").forEach(d=>{d===".."?s.length>1&&s.pop():d!=="."&&s.push(d)}),s.length>1?s.join("/"):"/"}function to(i,f,s,r){return`Cannot include a '${i}' character in a manually specified \`to.${f}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${s}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function b1(i){return i.filter((f,s)=>s===0||f.route.path&&f.route.path.length>0)}function mo(i){let f=b1(i);return f.map((s,r)=>r===f.length-1?s.pathname:s.pathnameBase)}function fc(i,f,s,r=!1){let d;typeof i=="string"?d=Rn(i):(d={...i},Dt(!d.pathname||!d.pathname.includes("?"),to("?","pathname","search",d)),Dt(!d.pathname||!d.pathname.includes("#"),to("#","pathname","hash",d)),Dt(!d.search||!d.search.includes("#"),to("#","search","hash",d)));let m=i===""||d.pathname==="",v=m?"/":d.pathname,g;if(v==null)g=s;else{let y=f.length-1;if(!r&&v.startsWith("..")){let D=v.split("/");for(;D[0]==="..";)D.shift(),y-=1;d.pathname=D.join("/")}g=y>=0?f[y]:"/"}let T=E1(d,g),C=v&&v!=="/"&&v.endsWith("/"),x=(m||v===".")&&s.endsWith("/");return!T.pathname.endsWith("/")&&(C||x)&&(T.pathname+="/"),T}var Tv=i=>i.replace(/[\\/]{2,}/g,"/"),$e=i=>Tv(i.join("/"));function zn(i,f=0){let s=i.length;for(;s>f&&i.charCodeAt(s-1)===47;)s--;return s===i.length?i:i.slice(0,s)}var T1=i=>zn(i).replace(/^\/*/,"/"),N1=i=>!i||i==="?"?"":i.startsWith("?")?i:"?"+i,z1=i=>!i||i==="#"?"":i.startsWith("#")?i:"#"+i,R1=class{constructor(i,f,s,r=!1){this.status=i,this.statusText=f||"",this.internal=r,s instanceof Error?(this.data=s.toString(),this.error=s):this.data=s}};function x1(i){return i!=null&&typeof i.status=="number"&&typeof i.statusText=="string"&&typeof i.internal=="boolean"&&"data"in i}function _1(i){let f=i.map(s=>s.route.path).filter(Boolean);return $e(f)||"/"}var Nv=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function zv(i,f){let s=i;if(typeof s!="string"||!so.test(s))return{absoluteURL:void 0,isExternal:!1,to:s};let r=s,d=!1;if(Nv)try{let m=new URL(window.location.href),v=yv.test(s)?new URL(l1(s,m.protocol)):new URL(s),g=Al(v.pathname,f);v.origin===m.origin&&g!=null?s=g+v.search+v.hash:d=!0}catch{qe(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:d,to:s}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var rv=new URL("http://localhost");function ho(i){if(i.createURL)return i.createURL("/");try{return new URL(i.createHref("/"),rv)}catch{return rv}}function eo(i,f){return i.origin===f.origin&&(i.origin!=="null"||i.protocol===f.protocol&&i.host===f.host)}function O1(i,f){if(i.startsWith("//"))return!0;let s=f.protocol.toLowerCase();return i.toLowerCase().startsWith(s)?f.host===""||i.slice(s.length).startsWith("//"):!1}function vo(i,f,s,r){let d=null;try{d=i==null?null:new URL(i,s)}catch{}let m=new URL(f,s),v=d!=null&&!eo(d,s),g=!eo(m,s);if(r==="reject"){if(v||g)throw new Error("External navigation is not allowed")}else if(g&&(d==null||!O1(i,d)||!eo(d,m)))throw new Error("External navigation is not allowed")}var Rv=["POST","PUT","PATCH","DELETE"];new Set(Rv);var A1=["GET",...Rv];new Set(A1);var C1=["about:","blob:","chrome:","chrome-untrusted:","content:","data:","devtools:","file:","filesystem:","javascript:"];function D1(i){try{return C1.includes(new URL(i).protocol)}catch{return!1}}var xn=R.createContext(null);xn.displayName="DataRouter";var rc=R.createContext(null);rc.displayName="DataRouterState";var xv=R.createContext(!1);function j1(){return R.useContext(xv)}var _v=R.createContext({isTransitioning:!1});_v.displayName="ViewTransition";var U1=R.createContext(new Map);U1.displayName="Fetchers";var M1=R.createContext(null);M1.displayName="Await";var Oe=R.createContext(null);Oe.displayName="Navigation";var xu=R.createContext(null);xu.displayName="Location";var Fe=R.createContext({outlet:null,matches:[],isDataRoute:!1});Fe.displayName="Route";var yo=R.createContext(null);yo.displayName="RouteError";var Ov="REACT_ROUTER_ERROR",H1="REDIRECT",B1="ROUTE_ERROR_RESPONSE";function L1(i){if(i.startsWith(`${Ov}:${H1}:{`))try{let f=JSON.parse(i.slice(28));if(typeof f=="object"&&f&&typeof f.status=="number"&&typeof f.statusText=="string"&&typeof f.location=="string"&&typeof f.reloadDocument=="boolean"&&typeof f.replace=="boolean")return f}catch{}}function q1(i){if(i.startsWith(`${Ov}:${B1}:{`))try{let f=JSON.parse(i.slice(40));if(typeof f=="object"&&f&&typeof f.status=="number"&&typeof f.statusText=="string")return new R1(f.status,f.statusText,f.data)}catch{}}function Y1(i,{relative:f}={}){Dt(_n(),"useHref() may be used only in the context of a component.");let{basename:s,navigator:r}=R.useContext(Oe),{hash:d,pathname:m,search:v}=_u(i,{relative:f}),g=m;return s!=="/"&&(g=m==="/"?s:$e([s,m])),r.createHref({pathname:g,search:v,hash:d})}function _n(){return R.useContext(xu)!=null}function Ye(){return Dt(_n(),"useLocation() may be used only in the context of a component."),R.useContext(xu).location}var Av="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Cv(i){R.useContext(Oe).static||R.useLayoutEffect(i)}function On(){let{isDataRoute:i}=R.useContext(Fe);return i?I1():w1()}function w1(){Dt(_n(),"useNavigate() may be used only in the context of a component.");let i=R.useContext(xn),{basename:f,navigator:s}=R.useContext(Oe),{matches:r}=R.useContext(Fe),{pathname:d}=Ye(),m=JSON.stringify(mo(r)),v=R.useRef(!1);return Cv(()=>{v.current=!0}),R.useCallback((T,C={})=>{if(qe(v.current,Av),!v.current)return;if(typeof T=="number"){s.go(T);return}let x=fc(T,JSON.parse(m),d,C.relative==="path");i==null&&f!=="/"&&(x.pathname=x.pathname==="/"?f:$e([f,x.pathname])),vo(typeof T=="string"?T:Ca(T),s.createHref(x),ho(s),"reject"),(C.replace?s.replace:s.push)(x,C.state,C)},[f,s,m,d,i])}R.createContext(null);function Dv(){let{matches:i}=R.useContext(Fe);return i[i.length-1]?.params??{}}function _u(i,{relative:f}={}){let{matches:s}=R.useContext(Fe),{pathname:r}=Ye(),d=JSON.stringify(mo(s));return R.useMemo(()=>fc(i,JSON.parse(d),r,f==="path"),[i,d,r,f])}function G1(i,f){return jv(i,f)}function jv(i,f,s){Dt(_n(),"useRoutes() may be used only in the context of a component.");let{navigator:r}=R.useContext(Oe),{matches:d}=R.useContext(Fe),m=d[d.length-1],v=m?m.params:{},g=m?m.pathname:"/",T=m?m.pathnameBase:"/",C=m&&m.route;{let M=C&&C.path||"";Mv(g,!C||M.endsWith("*")||M.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${g}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let x=Ye(),y;if(f){let M=typeof f=="string"?Rn(f):f;Dt(T==="/"||M.pathname?.startsWith(T),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${T}" but pathname "${M.pathname}" was given in the \`location\` prop.`),y=M}else y=x;let D=y.pathname||"/",B=D;if(T!=="/"){let M=T.replace(/^\//,"").split("/");B="/"+D.replace(/^\//,"").split("/").slice(M.length).join("/")}let q=s&&s.state.matches.length?s.state.matches.map(M=>Object.assign(M,{route:s.manifest[M.route.id]||M.route})):gv(i,{pathname:B});qe(C||q!=null,`No routes matched location "${y.pathname}${y.search}${y.hash}" `),qe(q==null||q[q.length-1].route.element!==void 0||q[q.length-1].route.Component!==void 0||q[q.length-1].route.lazy!==void 0,`Matched leaf route at location "${y.pathname}${y.search}${y.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let Y=K1(q&&q.map(M=>Object.assign({},M,{params:Object.assign({},v,M.params),pathname:$e([T,r.encodeLocation?r.encodeLocation(M.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathname]),pathnameBase:M.pathnameBase==="/"?T:$e([T,r.encodeLocation?r.encodeLocation(M.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathnameBase])})),d,s);return f&&Y?R.createElement(xu.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...y},navigationType:"POP"}},Y):Y}function X1(){let i=k1(),f=x1(i)?`${i.status} ${i.statusText}`:i instanceof Error?i.message:JSON.stringify(i),s=i instanceof Error?i.stack:null,r="rgba(200,200,200, 0.5)",d={padding:"0.5rem",backgroundColor:r},m={padding:"2px 4px",backgroundColor:r},v=null;return console.error("Error handled by React Router default ErrorBoundary:",i),v=R.createElement(R.Fragment,null,R.createElement("p",null,"💿 Hey developer 👋"),R.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",R.createElement("code",{style:m},"ErrorBoundary")," or"," ",R.createElement("code",{style:m},"errorElement")," prop on your route.")),R.createElement(R.Fragment,null,R.createElement("h2",null,"Unexpected Application Error!"),R.createElement("h3",{style:{fontStyle:"italic"}},f),s?R.createElement("pre",{style:d},s):null,v)}var Q1=R.createElement(X1,null),Uv=class extends R.Component{constructor(i){super(i),this.state={location:i.location,revalidation:i.revalidation,error:i.error}}static getDerivedStateFromError(i){return{error:i}}static getDerivedStateFromProps(i,f){return f.location!==i.location||f.revalidation!=="idle"&&i.revalidation==="idle"?{error:i.error,location:i.location,revalidation:i.revalidation}:{error:i.error!==void 0?i.error:f.error,location:f.location,revalidation:i.revalidation||f.revalidation}}componentDidCatch(i,f){this.props.onError?this.props.onError(i,f):console.error("React Router caught the following error during render",i)}render(){let i=this.state.error;if(this.context&&typeof i=="object"&&i&&"digest"in i&&typeof i.digest=="string"){const s=q1(i.digest);s&&(i=s)}let f=i!==void 0?R.createElement(Fe.Provider,{value:this.props.routeContext},R.createElement(yo.Provider,{value:i,children:this.props.component})):this.props.children;return this.context?R.createElement(V1,{error:i},f):f}};Uv.contextType=xv;var lo=new WeakMap;function V1({children:i,error:f}){let{basename:s,navigator:r}=R.useContext(Oe);if(typeof f=="object"&&f&&"digest"in f&&typeof f.digest=="string"){let d=L1(f.digest);if(d){let m=lo.get(f);if(m)throw m;let v=zv(d.location,s),g=v.absoluteURL||v.to;if(vo(d.location,g,ho(r),"allow-explicit"),D1(g))throw new Error("Invalid redirect location");if(Nv&&!lo.get(f))if(v.isExternal||d.reloadDocument)window.location.href=g;else{const T=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(v.to,{replace:d.replace}));throw lo.set(f,T),T}return R.createElement("meta",{httpEquiv:"refresh",content:`0;url=${g}`})}}return i}function Z1({routeContext:i,match:f,children:s}){let r=R.useContext(xn);return r&&r.static&&r.staticContext&&(f.route.errorElement||f.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=f.route.id),R.createElement(Fe.Provider,{value:i},s)}function K1(i,f=[],s){let r=s?.state;if(i==null){if(!r)return null;if(r.errors)i=r.matches;else if(f.length===0&&!r.initialized&&r.matches.length>0)i=r.matches;else return null}let d=i,m=r?.errors;if(m!=null){let x=d.findIndex(y=>y.route.id&&m?.[y.route.id]!==void 0);Dt(x>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(m).join(",")}`),d=d.slice(0,Math.min(d.length,x+1))}let v=!1,g=-1;if(s&&r){v=r.renderFallback;for(let x=0;x=0?d=d.slice(0,g+1):d=[d[0]];break}}}}let T=s?.onError,C=r&&T?(x,y)=>{T(x,{location:r.location,params:r.matches?.[0]?.params??{},pattern:_1(r.matches),errorInfo:y})}:void 0;return d.reduceRight((x,y,D)=>{let B,q=!1,Y=null,M=null;r&&(B=m&&y.route.id?m[y.route.id]:void 0,Y=y.route.errorElement||Q1,v&&(g<0&&D===0?(Mv("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),q=!0,M=null):g===D&&(q=!0,M=y.route.hydrateFallbackElement||null)));let J=f.concat(d.slice(0,D+1)),$=()=>{let at;return B?at=Y:q?at=M:y.route.Component?at=R.createElement(y.route.Component,null):y.route.element?at=y.route.element:at=x,R.createElement(Z1,{match:y,routeContext:{outlet:x,matches:J,isDataRoute:r!=null},children:at})};return r&&(y.route.ErrorBoundary||y.route.errorElement||D===0)?R.createElement(Uv,{location:r.location,revalidation:r.revalidation,component:Y,error:B,children:$(),routeContext:{outlet:null,matches:J,isDataRoute:!0},onError:C}):$()},null)}function go(i){return`${i} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function J1(i){let f=R.useContext(xn);return Dt(f,go(i)),f}function $1(i){let f=R.useContext(rc);return Dt(f,go(i)),f}function F1(i){let f=R.useContext(Fe);return Dt(f,go(i)),f}function po(i){let f=F1(i),s=f.matches[f.matches.length-1];return Dt(s.route.id,`${i} can only be used on routes that contain a unique "id"`),s.route.id}function W1(){return po("useRouteId")}function k1(){let i=R.useContext(yo),f=$1("useRouteError"),s=po("useRouteError");return i!==void 0?i:f.errors?.[s]}function I1(){let{router:i}=J1("useNavigate"),f=po("useNavigate"),s=R.useRef(!1);return Cv(()=>{s.current=!0}),R.useCallback(async(d,m={})=>{qe(s.current,Av),s.current&&(typeof d=="number"?await i.navigate(d):await i.navigate(d,{fromRouteId:f,...m}))},[i,f])}var ov={};function Mv(i,f,s){!f&&!ov[i]&&(ov[i]=!0,qe(!1,s))}R.memo(P1);function P1({routes:i,manifest:f,future:s,state:r,isStatic:d,onError:m}){return jv(i,void 0,{manifest:f,state:r,isStatic:d,onError:m})}function So({to:i,replace:f,state:s,relative:r}){Dt(_n()," may be used only in the context of a component.");let{static:d,navigator:m}=R.useContext(Oe);qe(!d," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:v}=R.useContext(Fe),{pathname:g}=Ye(),T=On(),C=fc(i,mo(v),g,r==="path");vo(typeof i=="string"?i:Ca(i),m.createHref(C),ho(m),"reject");let x=JSON.stringify(C);return R.useEffect(()=>{T(JSON.parse(x),{replace:f,state:s,relative:r})},[T,x,r,f,s]),null}function _l(i){Dt(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function tp({basename:i="/",children:f=null,location:s,navigationType:r="POP",navigator:d,static:m=!1,useTransitions:v}){Dt(!_n(),"You cannot render a inside another . You should never have more than one in your app.");let g=i.replace(/^\/*/,"/"),T=R.useMemo(()=>({basename:g,navigator:d,static:m,useTransitions:v,future:{}}),[g,d,m,v]);typeof s=="string"&&(s=Rn(s));let{pathname:C="/",search:x="",hash:y="",state:D=null,key:B="default",mask:q}=s,Y=R.useMemo(()=>{let M=Al(C,g);return M==null?null:{location:{pathname:M,search:x,hash:y,state:D,key:B,mask:q},navigationType:r}},[g,C,x,y,D,B,r,q]);return qe(Y!=null,` is not able to match the URL "${C}${x}${y}" because it does not start with the basename, so the won't render anything.`),Y==null?null:R.createElement(Oe.Provider,{value:T},R.createElement(xu.Provider,{children:f,value:Y}))}function ep({children:i,location:f}){return G1(io(i),f)}function io(i,f=[]){let s=[];return R.Children.forEach(i,(r,d)=>{if(!R.isValidElement(r))return;let m=[...f,d];if(r.type===R.Fragment){s.push.apply(s,io(r.props.children,m));return}Dt(r.type===_l,`[${typeof r.type=="string"?r.type:r.type.name}] is not a component. All component children of must be a or `),Dt(!r.props.index||!r.props.children,"An index route cannot have child routes.");let v={id:r.props.id||m.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(v.children=io(r.props.children,m)),s.push(v)}),s}var uc="get",ic="application/x-www-form-urlencoded";function oc(i){return typeof HTMLElement<"u"&&i instanceof HTMLElement}function lp(i){return oc(i)&&i.tagName.toLowerCase()==="button"}function ap(i){return oc(i)&&i.tagName.toLowerCase()==="form"}function np(i){return oc(i)&&i.tagName.toLowerCase()==="input"}function up(i){return!!(i.metaKey||i.altKey||i.ctrlKey||i.shiftKey)}function ip(i,f){return i.button===0&&(!f||f==="_self")&&!up(i)}function co(i=""){return new URLSearchParams(typeof i=="string"||Array.isArray(i)||i instanceof URLSearchParams?i:Object.keys(i).reduce((f,s)=>{let r=i[s];return f.concat(Array.isArray(r)?r.map(d=>[s,d]):[[s,r]])},[]))}function cp(i,f){let s=co(i);return f&&f.forEach((r,d)=>{s.has(d)||f.getAll(d).forEach(m=>{s.append(d,m)})}),s}var nc=null;function fp(){if(nc===null)try{new FormData(document.createElement("form"),0),nc=!1}catch{nc=!0}return nc}var rp=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function ao(i){return i!=null&&!rp.has(i)?(qe(!1,`"${i}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${ic}"`),null):i}function op(i,f){let s,r,d,m,v;if(ap(i)){let g=i.getAttribute("action");r=g?Al(g,f):null,s=i.getAttribute("method")||uc,d=ao(i.getAttribute("enctype"))||ic,m=new FormData(i)}else if(lp(i)||np(i)&&(i.type==="submit"||i.type==="image")){let g=i.form;if(g==null)throw new Error('Cannot submit a + + + +
+ + + ${tT} + + +
+ +
+ +
+
+
+
+ +
+
+ +
+
+ +
+ +
+
+ +
+ +
+ + +
+ + + +
+ +
+ + + +
+
+ +
+ +
`,iT=r=>{z0(nT,r)};var KA=(function(){var r="b9H79Tebbbe8Fv9Gbb9Gvuuuuueu9Giuuub9Geueu9Giuuueuixkbeeeddddillviebeoweuec:W:Odkr;Neqo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbeY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVbdE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbiL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtblK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949WboY9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVJ9V29VVbrl79IV9Rbwq;lZkdbk;jYi5ud9:du8Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnalTmbcuhoaiRbbgrc;WeGc:Ge9hmbarcsGgwce0mbc9:hoalcufadcd4cbawEgDadfgrcKcaawEgqaraq0Egk6mbaicefhxcj;abad9Uc;WFbGcjdadca0EhmaialfgPar9Rgoadfhsavaoadz:jjjjbgzceVhHcbhOdndninaeaO9nmeaPax9RaD6mdamaeaO9RaOamfgoae6EgAcsfglc9WGhCabaOad2fhXaAcethQaxaDfhiaOaeaoaeao6E9RhLalcl4cifcd4hKazcj;cbfaAfhYcbh8AazcjdfhEaHh3incbhodnawTmbaxa8Acd4fRbbhokaocFeGh5cbh8Eazcj;cbfhqinaih8Fdndndndna5a8Ecet4ciGgoc9:fPdebdkaPa8F9RaA6mrazcj;cbfa8EaA2fa8FaAz:jjjjb8Aa8FaAfhixdkazcj;cbfa8EaA2fcbaAz:kjjjb8Aa8FhixekaPa8F9RaK6mva8FaKfhidnaCTmbaPai9RcK6mbaocdtc:q1jjbfcj1jjbawEhaczhrcbhlinargoc9Wfghaqfhrdndndndndndnaaa8Fahco4fRbbalcoG4ciGcdtfydbPDbedvivvvlvkar9cb83bbarcwf9cb83bbxlkarcbaiRbdai8Xbb9c:c:qj:bw9:9c:q;c1:I1e:d9c:b:c:e1z9:gg9cjjjjjz:dg8J9qE86bbaqaofgrcGfag9c8F1:NghcKtc8F91aicdfa8J9c8N1:Nfg8KRbbG86bbarcVfcba8KahcjeGcr4fghRbbag9cjjjjjl:dg8J9qE86bbarc7fcbaha8J9c8L1:NfghRbbag9cjjjjjd:dg8J9qE86bbarctfcbaha8J9c8K1:NfghRbbag9cjjjjje:dg8J9qE86bbarc91fcbaha8J9c8J1:NfghRbbag9cjjjj;ab:dg8J9qE86bbarc4fcbaha8J9cg1:NfghRbbag9cjjjja:dg8J9qE86bbarc93fcbaha8J9ch1:NfghRbbag9cjjjjz:dgg9qE86bbarc94fcbahag9ca1:NfghRbbai8Xbe9c:c:qj:bw9:9c:q;c1:I1e:d9c:b:c:e1z9:gg9cjjjjjz:dg8J9qE86bbarc95fag9c8F1:NgicKtc8F91aha8J9c8N1:NfghRbbG86bbarc96fcbahaicjeGcr4fgiRbbag9cjjjjjl:dg8J9qE86bbarc97fcbaia8J9c8L1:NfgiRbbag9cjjjjjd:dg8J9qE86bbarc98fcbaia8J9c8K1:NfgiRbbag9cjjjjje:dg8J9qE86bbarc99fcbaia8J9c8J1:NfgiRbbag9cjjjj;ab:dg8J9qE86bbarc9:fcbaia8J9cg1:NfgiRbbag9cjjjja:dg8J9qE86bbarcufcbaia8J9ch1:NfgiRbbag9cjjjjz:dgg9qE86bbaiag9ca1:NfhixikaraiRblaiRbbghco4g8Ka8KciSg8KE86bbaqaofgrcGfaiclfa8Kfg8KRbbahcl4ciGg8La8LciSg8LE86bbarcVfa8Ka8Lfg8KRbbahcd4ciGg8La8LciSg8LE86bbarc7fa8Ka8Lfg8KRbbahciGghahciSghE86bbarctfa8Kahfg8KRbbaiRbeghco4g8La8LciSg8LE86bbarc91fa8Ka8Lfg8KRbbahcl4ciGg8La8LciSg8LE86bbarc4fa8Ka8Lfg8KRbbahcd4ciGg8La8LciSg8LE86bbarc93fa8Ka8Lfg8KRbbahciGghahciSghE86bbarc94fa8Kahfg8KRbbaiRbdghco4g8La8LciSg8LE86bbarc95fa8Ka8Lfg8KRbbahcl4ciGg8La8LciSg8LE86bbarc96fa8Ka8Lfg8KRbbahcd4ciGg8La8LciSg8LE86bbarc97fa8Ka8Lfg8KRbbahciGghahciSghE86bbarc98fa8KahfghRbbaiRbigico4g8Ka8KciSg8KE86bbarc99faha8KfghRbbaicl4ciGg8Ka8KciSg8KE86bbarc9:faha8KfghRbbaicd4ciGg8Ka8KciSg8KE86bbarcufaha8KfgrRbbaiciGgiaiciSgiE86bbaraifhixdkaraiRbwaiRbbghcl4g8Ka8KcsSg8KE86bbaqaofgrcGfaicwfa8Kfg8KRbbahcsGghahcsSghE86bbarcVfa8KahfghRbbaiRbeg8Kcl4g8La8LcsSg8LE86bbarc7faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarctfaha8KfghRbbaiRbdg8Kcl4g8La8LcsSg8LE86bbarc91faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc4faha8KfghRbbaiRbig8Kcl4g8La8LcsSg8LE86bbarc93faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc94faha8KfghRbbaiRblg8Kcl4g8La8LcsSg8LE86bbarc95faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc96faha8KfghRbbaiRbvg8Kcl4g8La8LcsSg8LE86bbarc97faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc98faha8KfghRbbaiRbog8Kcl4g8La8LcsSg8LE86bbarc99faha8LfghRbba8KcsGg8Ka8KcsSg8KE86bbarc9:faha8KfghRbbaiRbrgicl4g8Ka8KcsSg8KE86bbarcufaha8KfgrRbbaicsGgiaicsSgiE86bbaraifhixekarai8Pbb83bbarcwfaicwf8Pbb83bbaiczfhikdnaoaC9pmbalcdfhlaoczfhraPai9RcL0mekkaoaC6moaimexokaCmva8FTmvkaqaAfhqa8Ecefg8Ecl9hmbkdndndndnawTmbasa8Acd4fRbbgociGPlbedrbkaATmdaza8Afh8Fazcj;cbfhhcbh8EaEhaina8FRbbhraahocbhlinaoahalfRbbgqce4cbaqceG9R7arfgr86bbaoadfhoaAalcefgl9hmbkaacefhaa8Fcefh8FahaAfhha8Ecefg8Ecl9hmbxikkaATmeaza8Afhaazcj;cbfhhcbhoceh8EaYh8FinaEaofhlaa8Vbbhrcbhoinala8FaofRbbcwtahaofRbbgqVc;:FiGce4cbaqceG9R7arfgr87bbaladfhlaLaocefgofmbka8FaQfh8FcdhoaacdfhaahaQfhha8EceGhlcbh8EalmbxdkkaATmbcbaocl49Rh8Eaza8AfRbbhqcwhoa3hlinalRbbaotaqVhqalcefhlaocwfgoca9hmbkcbhhaEh8FaYhainazcj;cbfahfRbbhrcwhoaahlinalRbbaotarVhralaAfhlaocwfgoca9hmbkara8E93aq7hqcbhoa8Fhlinalaqao486bbalcefhlaocwfgoca9hmbka8Fadfh8FaacefhaahcefghaA9hmbkkaEclfhEa3clfh3a8Aclfg8Aad6mbkaXazcjdfaAad2z:jjjjb8AazazcjdfaAcufad2fadz:jjjjb8AaAaOfhOaihxaimbkc9:hoxdkcbc99aPax9RakSEhoxekc9:hokavcj;kbf8Kjjjjbaok:XseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecjez:kjjjb8AavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhldnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhoindnalaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfaoaDcu7gPcl4fcsGcitfgsydlhzasydbhHdndnaDcsGgsak9pmbavaiaPfcsGcdtfydbaxasEhDaxasTgOfhxxekdndnascsSmbcehOasc987asamffcefhDxekalcefhDal8SbbgscFeGhPdndnascu9mmbaDhlxekalcvfhlaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhlkcehOaPce4cbaPceG9R7amfhDkaDhmkavc;abfaocitfgsaDBdbasazBdlavaicdtfaDBdbavc;abfaocefcsGcitfgsaHBdbasaDBdlaocdfhoaOaifhidnadcd9hmbabarcetfgsaH87ebasclfaD87ebascdfaz87ebxdkabarcdtfgsaHBdbascwfaDBdbasclfazBdbxekdnaDcpe0mbaxcefgOavaiaqaDcsGfRbbgscl49RcsGcdtfydbascz6gPEhDavaias9RcsGcdtfydbaOaPfgzascsGgOEhsaOThOdndnadcd9hmbabarcetfgHax87ebaHclfas87ebaHcdfaD87ebxekabarcdtfgHaxBdbaHcwfasBdbaHclfaDBdbkavaicdtfaxBdbavc;abfaocitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfaocefcsGcitfgHasBdbaHaDBdlavaiaPfgicsGcdtfasBdbavc;abfaocdfcsGcitfgDaxBdbaDasBdlaocifhoaiaOfhiazaOfhxxekaxcbalRbbgHEgAaDc;:eSgDfhzaHcsGhCaHcl4hXdndnaHcs0mbazcefhOxekazhOavaiaX9RcsGcdtfydbhzkdndnaCmbaOcefhxxekaOhxavaiaH9RcsGcdtfydbhOkdndnaDTmbalcefhDxekalcdfhDal8SbegPcFeGhsdnaPcu9kmbalcofhAascFbGhscrhldninaD8SbbgPcFbGaltasVhsaPcu9kmeaDcefhDalcrfglc8J9hmbkaAhDxekaDcefhDkasce4cbasceG9R7amfgmhAkdndnaXcsSmbaDhsxekaDcefhsaD8SbbglcFeGhPdnalcu9kmbaDcvfhzaPcFbGhPcrhldninas8SbbgDcFbGaltaPVhPaDcu9kmeascefhsalcrfglc8J9hmbkazhsxekascefhskaPce4cbaPceG9R7amfgmhzkdndnaCcsSmbashlxekascefhlas8SbbgDcFeGhPdnaDcu9kmbascvfhOaPcFbGhPcrhDdninal8SbbgscFbGaDtaPVhPascu9kmealcefhlaDcrfgDc8J9hmbkaOhlxekalcefhlkaPce4cbaPceG9R7amfgmhOkdndnadcd9hmbabarcetfgDaA87ebaDclfaO87ebaDcdfaz87ebxekabarcdtfgDaABdbaDcwfaOBdbaDclfazBdbkavc;abfaocitfgDazBdbaDaABdlavaicdtfaABdbavc;abfaocefcsGcitfgDaOBdbaDazBdlavaicefgicsGcdtfazBdbavc;abfaocdfcsGcitfgDaABdbaDaOBdlavaiaHcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhiaocifhokawcefhwaocsGhoaicsGhiarcifgrae6mbkkcbc99alaqSEhokavc;aef8Kjjjjbaok:clevu8Jjjjjbcz9Rhvdnaecvfal9nmbc9:skdnaiRbbc;:eGc;qeSmbcuskav9cb83iwaicefhoaialfc98fhrdnaeTmbdnadcdSmbcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcdtfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgiBdbalaiBdbawcefgwae9hmbxdkkcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcetfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgi87ebalaiBdbawcefgwae9hmbkkcbc99aoarSEk:Lvoeue99dud99eud99dndnadcl9hmbaeTmeindndnabcdfgd8Sbb:Yab8Sbbgi:Ygl:l:tabcefgv8Sbbgo:Ygr:l:tgwJbb;:9cawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai86bbdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad86bbdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad86bbabclfhbaecufgembxdkkaeTmbindndnabclfgd8Ueb:Yab8Uebgi:Ygl:l:tabcdfgv8Uebgo:Ygr:l:tgwJb;:FSawawNJbbbbawawJbbbb9GgDEgq:mgkaqaicb9iEalMgwawNakaqaocb9iEarMgqaqNMM:r:vglNJbbbZJbbb:;aDEMgr:lJbbb9p9DTmbar:Ohixekcjjjj94hikadai87ebdndnaqalNJbbbZJbbb:;aqJbbbb9GEMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkavad87ebdndnawalNJbbbZJbbb:;awJbbbb9GEMgw:lJbbb9p9DTmbaw:Ohdxekcjjjj94hdkabad87ebabcwfhbaecufgembkkk::ioiue99dud99dud99dnaeTmbcbhiabhlindndnal8Uebgv:YgoJ:ji:1Salcof8UebgrciVgw:Y:vgDNJbbbZJbbb:;avcu9kEMgq:lJbbb9p9DTmbaq:Ohkxekcjjjj94hkkalclf8Uebhvalcdf8UebhxabaiarcefciGfcetfak87ebdndnax:YgqaDNJbbbZJbbb:;axcu9kEMgm:lJbbb9p9DTmbam:Ohxxekcjjjj94hxkabaiarciGfgkcd7cetfax87ebdndnav:YgmaDNJbbbZJbbb:;avcu9kEMgP:lJbbb9p9DTmbaP:Ohvxekcjjjj94hvkabaiarcufciGfcetfav87ebdndnawaw2:ZgPaPMaoaoN:taqaqN:tamamN:tgoJbbbbaoJbbbb9GE:raDNJbbbZMgD:lJbbb9p9DTmbaD:Ohrxekcjjjj94hrkabakcetfar87ebalcwfhlaiclfhiaecufgembkkk9mbdnadcd4ae2gdTmbinababydbgecwtcw91:Yaece91cjjj98Gcjjj;8if::NUdbabclfhbadcufgdmbkkk:Tvirud99eudndnadcl9hmbaeTmeindndnabRbbgiabcefgl8Sbbgvabcdfgo8Sbbgrf9R:YJbbuJabcifgwRbbgdce4adVgDcd4aDVgDcl4aDVgD:Z:vgqNJbbbZMgk:lJbbb9p9DTmbak:Ohxxekcjjjj94hxkaoax86bbdndnaraif:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohoxekcjjjj94hokalao86bbdndnavaifar9R:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikabai86bbdndnaDadcetGadceGV:ZaqNJbbbZMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkawad86bbabclfhbaecufgembxdkkaeTmbindndnab8Vebgiabcdfgl8Uebgvabclfgo8Uebgrf9R:YJbFu9habcofgw8Vebgdce4adVgDcd4aDVgDcl4aDVgDcw4aDVgD:Z:vgqNJbbbZMgk:lJbbb9p9DTmbak:Ohxxekcjjjj94hxkaoax87ebdndnaraif:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohoxekcjjjj94hokalao87ebdndnavaifar9R:YaqNJbbbZMgk:lJbbb9p9DTmbak:Ohixekcjjjj94hikabai87ebdndnaDadcetGadceGV:ZaqNJbbbZMgq:lJbbb9p9DTmbaq:Ohdxekcjjjj94hdkawad87ebabcwfhbaecufgembkkk9teiucbcbyd:K1jjbgeabcifc98GfgbBd:K1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;teeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiaeydlBdlaiaeydwBdwaiaeydxBdxaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk:3eedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdxaialBdwaialBdlaialBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabkk81dbcjwk8Kbbbbdbbblbbbwbbbbbbbebbbdbbblbbbwbbbbc:Kwkl8WNbb",e="b9H79TebbbeKl9Gbb9Gvuuuuueu9Giuuub9Geueuixkbbebeeddddilve9Weeeviebeoweuec:q:6dkr;Neqo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9KW9J9V9KW9wWVtW949c919M9MWVbdY9TW79O9V9Wt9F9KW9J9V9KW69U9KW949c919M9MWVblE9TW79O9V9Wt9F9KW9J9V9KW69U9KW949tWG91W9U9JWbvL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9p9JtboK9TW79O9V9Wt9F9KW9J9V9KWS9P2tWV9r919HtbrL9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVT949WbwY9TW79O9V9Wt9F9KW9J9V9KWS9P2tWVJ9V29VVbDl79IV9Rbqq:Ctklbzik9:evu8Jjjjjbcz9Rhbcbheincbhdcbhiinabcwfadfaicjuaead4ceGglE86bbaialfhiadcefgdcw9hmbkaec:q:yjjbfai86bbaecitc:q1jjbfab8Piw83ibaecefgecjd9hmbkk:183lYud97dur978Jjjjjbcj;kb9Rgv8Kjjjjbc9:hodnalTmbcuhoaiRbbgrc;WeGc:Ge9hmbarcsGgwce0mbc9:hoalcufadcd4cbawEgDadfgrcKcaawEgqaraq0Egk6mbaicefhxavaialfgmar9Rgoad;8qbbcj;abad9Uc;WFbGcjdadca0EhPdndndnadTmbaoadfhscbhzinaeaz9nmdamax9RaD6miabazad2fhHaxaDfhOaPaeaz9RazaPfae6EgAcsfgocl4cifcd4hCavcj;cbfaoc9WGgXcetfhQavcj;cbfaXci2fhLavcj;cbfaXfhKcbhYaoc;ab6h8AincbhodnawTmbaxaYcd4fRbbhokaocFeGhEcbh3avcj;cbfh5indndndndnaEa3cet4ciGgoc9:fPdebdkamaO9RaX6mwavcj;cbfa3aX2faOaX;8qbbaOaAfhOxdkavcj;cbfa3aX2fcbaX;8kbxekamaO9RaC6moaoclVcbawEhraOaCfhocbhidna8Ambamao9Rc;Gb6mbcbhlina5alfhidndndndndndnaOalco4fRbbgqciGarfPDbedibledibkaipxbbbbbbbbbbbbbbbbpklbxlkaiaopbblaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLg8Ecdp:mea8EpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9og8Fpxiiiiiiiiiiiiiiiip8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaaaoclffahc:q:yjjbfRbbfhoxikaiaopbbwaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9og8Fpxssssssssssssssssp8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaaaocwffahc:q:yjjbfRbbfhoxdkaiaopbbbpklbaoczfhoxekaiaopbbdaoRbbgacitc:q1jjbfpbibaac:q:yjjbfRbbgapsaoRbeghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPpklbaaaocdffahc:q:yjjbfRbbfhokdndndndndndnaqcd4ciGarfPDbedibledibkaiczfpxbbbbbbbbbbbbbbbbpklbxlkaiczfaopbblaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLg8Ecdp:mea8EpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9og8Fpxiiiiiiiiiiiiiiiip8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaaaoclffahc:q:yjjbfRbbfhoxikaiczfaopbbwaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9og8Fpxssssssssssssssssp8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaaaocwffahc:q:yjjbfRbbfhoxdkaiczfaopbbbpklbaoczfhoxekaiczfaopbbdaoRbbgacitc:q1jjbfpbibaac:q:yjjbfRbbgapsaoRbeghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPpklbaaaocdffahc:q:yjjbfRbbfhokdndndndndndnaqcl4ciGarfPDbedibledibkaicafpxbbbbbbbbbbbbbbbbpklbxlkaicafaopbblaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLg8Ecdp:mea8EpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9og8Fpxiiiiiiiiiiiiiiiip8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaaaoclffahc:q:yjjbfRbbfhoxikaicafaopbbwaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9og8Fpxssssssssssssssssp8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaaaocwffahc:q:yjjbfRbbfhoxdkaicafaopbbbpklbaoczfhoxekaicafaopbbdaoRbbgacitc:q1jjbfpbibaac:q:yjjbfRbbgapsaoRbeghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPpklbaaaocdffahc:q:yjjbfRbbfhokdndndndndndnaqco4arfPDbedibledibkaic8Wfpxbbbbbbbbbbbbbbbbpklbxlkaic8Wfaopbblaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLg8Ecdp:mea8EpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9og8Fpxiiiiiiiiiiiiiiiip8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngicitc:q1jjbfpbibaic:q:yjjbfRbbgipsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Ngqcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaiaoclffaqc:q:yjjbfRbbfhoxikaic8Wfaopbbwaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9og8Fpxssssssssssssssssp8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngicitc:q1jjbfpbibaic:q:yjjbfRbbgipsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Ngqcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spklbaiaocwffaqc:q:yjjbfRbbfhoxdkaic8Wfaopbbbpklbaoczfhoxekaic8WfaopbbdaoRbbgicitc:q1jjbfpbibaic:q:yjjbfRbbgipsaoRbegqcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPpklbaiaocdffaqc:q:yjjbfRbbfhokalc;abfhialcjefaX0meaihlamao9Rc;Fb0mbkkdnaiaX9pmbaici4hlinamao9RcK6mwa5aifhqdndndndndndnaOaico4fRbbalcoG4ciGarfPDbedibledibkaqpxbbbbbbbbbbbbbbbbpkbbxlkaqaopbblaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLg8Ecdp:mea8EpmbzeHdOiAlCvXoQrLpxiiiiiiiiiiiiiiiip9og8Fpxiiiiiiiiiiiiiiiip8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spkbbaaaoclffahc:q:yjjbfRbbfhoxikaqaopbbwaopbbbg8Eclp:mea8EpmbzeHdOiAlCvXoQrLpxssssssssssssssssp9og8Fpxssssssssssssssssp8Jg8Ep5b9cjF;8;4;W;G;ab9:9cU1:Ngacitc:q1jjbfpbibaac:q:yjjbfRbbgapsa8Ep5e9cjF;8;4;W;G;ab9:9cU1:Nghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPa8Fa8Ep9spkbbaaaocwffahc:q:yjjbfRbbfhoxdkaqaopbbbpkbbaoczfhoxekaqaopbbdaoRbbgacitc:q1jjbfpbibaac:q:yjjbfRbbgapsaoRbeghcitc:q1jjbfpbibp9UpmbedilvorzHOACXQLpPpkbbaaaocdffahc:q:yjjbfRbbfhokalcdfhlaiczfgiaX6mbkkaohOaoTmoka5aXfh5a3cefg3cl9hmbkdndndndnawTmbasaYcd4fRbbglciGPlbedwbkaXTmdavcjdfaYfhlavaYfpbdbhgcbhoinalavcj;cbfaofpblbg8JaKaofpblbg8KpmbzeHdOiAlCvXoQrLg8LaQaofpblbg8MaLaofpblbg8NpmbzeHdOiAlCvXoQrLgypmbezHdiOAlvCXorQLg8Ecep9Ta8Epxeeeeeeeeeeeeeeeeg8Fp9op9Hp9rg8Eagp9Uggp9Abbbaladfglaga8Ea8Epmlvorlvorlvorlvorp9Uggp9Abbbaladfglaga8Ea8EpmwDqkwDqkwDqkwDqkp9Uggp9Abbbaladfglaga8Ea8EpmxmPsxmPsxmPsxmPsp9Uggp9Abbbaladfglaga8LaypmwDKYqk8AExm35Ps8E8Fg8Ecep9Ta8Ea8Fp9op9Hp9rg8Ep9Uggp9Abbbaladfglaga8Ea8Epmlvorlvorlvorlvorp9Uggp9Abbbaladfglaga8Ea8EpmwDqkwDqkwDqkwDqkp9Uggp9Abbbaladfglaga8Ea8EpmxmPsxmPsxmPsxmPsp9Uggp9Abbbaladfglaga8Ja8KpmwKDYq8AkEx3m5P8Es8Fg8Ja8Ma8NpmwKDYq8AkEx3m5P8Es8Fg8KpmbezHdiOAlvCXorQLg8Ecep9Ta8Ea8Fp9op9Hp9rg8Ep9Uggp9Abbbaladfglaga8Ea8Epmlvorlvorlvorlvorp9Uggp9Abbbaladfglaga8Ea8EpmwDqkwDqkwDqkwDqkp9Uggp9Abbbaladfglaga8Ea8EpmxmPsxmPsxmPsxmPsp9Uggp9Abbbaladfglaga8Ja8KpmwDKYqk8AExm35Ps8E8Fg8Ecep9Ta8Ea8Fp9op9Hp9rg8Ep9Ug8Fp9Abbbaladfgla8Fa8Ea8Epmlvorlvorlvorlvorp9Ug8Fp9Abbbaladfgla8Fa8Ea8EpmwDqkwDqkwDqkwDqkp9Ug8Fp9Abbbaladfgla8Fa8Ea8EpmxmPsxmPsxmPsxmPsp9Uggp9AbbbaladfhlaoczfgoaX6mbxikkaXTmeavcjdfaYfhlavaYfpbdbhgcbhoinalavcj;cbfaofpblbg8JaKaofpblbg8KpmbzeHdOiAlCvXoQrLg8LaQaofpblbg8MaLaofpblbg8NpmbzeHdOiAlCvXoQrLgypmbezHdiOAlvCXorQLg8Ecep:nea8Epxebebebebebebebebg8Fp9op:bep9rg8Eagp:oeggp9Abbbaladfglaga8Ea8Epmlvorlvorlvorlvorp:oeggp9Abbbaladfglaga8Ea8EpmwDqkwDqkwDqkwDqkp:oeggp9Abbbaladfglaga8Ea8EpmxmPsxmPsxmPsxmPsp:oeggp9Abbbaladfglaga8LaypmwDKYqk8AExm35Ps8E8Fg8Ecep:nea8Ea8Fp9op:bep9rg8Ep:oeggp9Abbbaladfglaga8Ea8Epmlvorlvorlvorlvorp:oeggp9Abbbaladfglaga8Ea8EpmwDqkwDqkwDqkwDqkp:oeggp9Abbbaladfglaga8Ea8EpmxmPsxmPsxmPsxmPsp:oeggp9Abbbaladfglaga8Ja8KpmwKDYq8AkEx3m5P8Es8Fg8Ja8Ma8NpmwKDYq8AkEx3m5P8Es8Fg8KpmbezHdiOAlvCXorQLg8Ecep:nea8Ea8Fp9op:bep9rg8Ep:oeggp9Abbbaladfglaga8Ea8Epmlvorlvorlvorlvorp:oeggp9Abbbaladfglaga8Ea8EpmwDqkwDqkwDqkwDqkp:oeggp9Abbbaladfglaga8Ea8EpmxmPsxmPsxmPsxmPsp:oeggp9Abbbaladfglaga8Ja8KpmwDKYqk8AExm35Ps8E8Fg8Ecep:nea8Ea8Fp9op:bep9rg8Ep:oeg8Fp9Abbbaladfgla8Fa8Ea8Epmlvorlvorlvorlvorp:oeg8Fp9Abbbaladfgla8Fa8Ea8EpmwDqkwDqkwDqkwDqkp:oeg8Fp9Abbbaladfgla8Fa8Ea8EpmxmPsxmPsxmPsxmPsp:oeggp9AbbbaladfhlaoczfgoaX6mbxdkkaXTmbcbhocbalcl4gl9Rc8FGhiavcjdfaYfhravaYfpbdbh8Finaravcj;cbfaofpblbggaKaofpblbg8JpmbzeHdOiAlCvXoQrLg8KaQaofpblbg8LaLaofpblbg8MpmbzeHdOiAlCvXoQrLg8NpmbezHdiOAlvCXorQLg8Eaip:Rea8Ealp:Sep9qg8Ea8Fp9rg8Fp9Abbbaradfgra8Fa8Ea8Epmlvorlvorlvorlvorp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmwDqkwDqkwDqkwDqkp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmxmPsxmPsxmPsxmPsp9rg8Fp9Abbbaradfgra8Fa8Ka8NpmwDKYqk8AExm35Ps8E8Fg8Eaip:Rea8Ealp:Sep9qg8Ep9rg8Fp9Abbbaradfgra8Fa8Ea8Epmlvorlvorlvorlvorp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmwDqkwDqkwDqkwDqkp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmxmPsxmPsxmPsxmPsp9rg8Fp9Abbbaradfgra8Faga8JpmwKDYq8AkEx3m5P8Es8Fgga8La8MpmwKDYq8AkEx3m5P8Es8Fg8JpmbezHdiOAlvCXorQLg8Eaip:Rea8Ealp:Sep9qg8Ep9rg8Fp9Abbbaradfgra8Fa8Ea8Epmlvorlvorlvorlvorp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmwDqkwDqkwDqkwDqkp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmxmPsxmPsxmPsxmPsp9rg8Fp9Abbbaradfgra8Faga8JpmwDKYqk8AExm35Ps8E8Fg8Eaip:Rea8Ealp:Sep9qg8Ep9rg8Fp9Abbbaradfgra8Fa8Ea8Epmlvorlvorlvorlvorp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmwDqkwDqkwDqkwDqkp9rg8Fp9Abbbaradfgra8Fa8Ea8EpmxmPsxmPsxmPsxmPsp9rg8Fp9AbbbaradfhraoczfgoaX6mbkkaYclfgYad6mbkaHavcjdfaAad2;8qbbavavcjdfaAcufad2fad;8qbbaAazfhzc9:hoaOhxaOmbxlkkaeTmbaDalfhrcbhocuhlinaralaD9RglfaD6mdaPaeao9RaoaPfae6Eaofgoae6mbkaial9Rhxkcbc99amax9RakSEhoxekc9:hokavcj;kbf8Kjjjjbaokwbz:bjjjbk:TseHu8Jjjjjbc;ae9Rgv8Kjjjjbc9:hodnaeci9UgrcHfal0mbcuhoaiRbbgwc;WeGc;Ge9hmbawcsGgDce0mbavc;abfcFecje;8kbavcUf9cu83ibavc8Wf9cu83ibavcyf9cu83ibavcaf9cu83ibavcKf9cu83ibavczf9cu83ibav9cu83iwav9cu83ibaialfc9WfhqaicefgwarfhldnaeTmbcmcsaDceSEhkcbhxcbhmcbhrcbhicbhoindnalaq9nmbc9:hoxikdndnawRbbgDc;Ve0mbavc;abfaoaDcu7gPcl4fcsGcitfgsydlhzasydbhHdndnaDcsGgsak9pmbavaiaPfcsGcdtfydbaxasEhDaxasTgOfhxxekdndnascsSmbcehOasc987asamffcefhDxekalcefhDal8SbbgscFeGhPdndnascu9mmbaDhlxekalcvfhlaPcFbGhPcrhsdninaD8SbbgOcFbGastaPVhPaOcu9kmeaDcefhDascrfgsc8J9hmbxdkkaDcefhlkcehOaPce4cbaPceG9R7amfhDkaDhmkavc;abfaocitfgsaDBdbasazBdlavaicdtfaDBdbavc;abfaocefcsGcitfgsaHBdbasaDBdlaocdfhoaOaifhidnadcd9hmbabarcetfgsaH87ebasclfaD87ebascdfaz87ebxdkabarcdtfgsaHBdbascwfaDBdbasclfazBdbxekdnaDcpe0mbaxcefgOavaiaqaDcsGfRbbgscl49RcsGcdtfydbascz6gPEhDavaias9RcsGcdtfydbaOaPfgzascsGgOEhsaOThOdndnadcd9hmbabarcetfgHax87ebaHclfas87ebaHcdfaD87ebxekabarcdtfgHaxBdbaHcwfasBdbaHclfaDBdbkavaicdtfaxBdbavc;abfaocitfgHaDBdbaHaxBdlavaicefgicsGcdtfaDBdbavc;abfaocefcsGcitfgHasBdbaHaDBdlavaiaPfgicsGcdtfasBdbavc;abfaocdfcsGcitfgDaxBdbaDasBdlaocifhoaiaOfhiazaOfhxxekaxcbalRbbgHEgAaDc;:eSgDfhzaHcsGhCaHcl4hXdndnaHcs0mbazcefhOxekazhOavaiaX9RcsGcdtfydbhzkdndnaCmbaOcefhxxekaOhxavaiaH9RcsGcdtfydbhOkdndnaDTmbalcefhDxekalcdfhDal8SbegPcFeGhsdnaPcu9kmbalcofhAascFbGhscrhldninaD8SbbgPcFbGaltasVhsaPcu9kmeaDcefhDalcrfglc8J9hmbkaAhDxekaDcefhDkasce4cbasceG9R7amfgmhAkdndnaXcsSmbaDhsxekaDcefhsaD8SbbglcFeGhPdnalcu9kmbaDcvfhzaPcFbGhPcrhldninas8SbbgDcFbGaltaPVhPaDcu9kmeascefhsalcrfglc8J9hmbkazhsxekascefhskaPce4cbaPceG9R7amfgmhzkdndnaCcsSmbashlxekascefhlas8SbbgDcFeGhPdnaDcu9kmbascvfhOaPcFbGhPcrhDdninal8SbbgscFbGaDtaPVhPascu9kmealcefhlaDcrfgDc8J9hmbkaOhlxekalcefhlkaPce4cbaPceG9R7amfgmhOkdndnadcd9hmbabarcetfgDaA87ebaDclfaO87ebaDcdfaz87ebxekabarcdtfgDaABdbaDcwfaOBdbaDclfazBdbkavc;abfaocitfgDazBdbaDaABdlavaicdtfaABdbavc;abfaocefcsGcitfgDaOBdbaDazBdlavaicefgicsGcdtfazBdbavc;abfaocdfcsGcitfgDaABdbaDaOBdlavaiaHcz6aXcsSVfgicsGcdtfaOBdbaiaCTaCcsSVfhiaocifhokawcefhwaocsGhoaicsGhiarcifgrae6mbkkcbc99alaqSEhokavc;aef8Kjjjjbaok:clevu8Jjjjjbcz9Rhvdnaecvfal9nmbc9:skdnaiRbbc;:eGc;qeSmbcuskav9cb83iwaicefhoaialfc98fhrdnaeTmbdnadcdSmbcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcdtfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgiBdbalaiBdbawcefgwae9hmbxdkkcbhwindnaoar6mbc9:skaocefhlao8SbbgicFeGhddndnaicu9mmbalhoxekaocvfhoadcFbGhdcrhidninal8SbbgDcFbGaitadVhdaDcu9kmealcefhlaicrfgic8J9hmbxdkkalcefhokabawcetfadc8Etc8F91adcd47avcwfadceGcdtVglydbfgi87ebalaiBdbawcefgwae9hmbkkcbc99aoarSEk:2Pliur97eue978Jjjjjbc8W9Rhiaec98Ghldndnadcl9hmbdnalTmbcbhvabhdinadadpbbbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDpxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpkbbadczfhdavclfgval6mbkkalaeSmeaipxbbbbbbbbbbbbbbbbgqpklbaiabalcdtfgdaeciGglcdtgv;8qbbdnalTmbaiaipblbgocKp:RecKp:Sep;6egraocwp:RecKp:Sep;6earp;Geaoczp:RecKp:Sep;6egwp;Gep;Kep;LegDaqp:2egqarpxbbbjbbbjbbbjbbbjgkp9op9rp;Kegrpxbb;:9cbb;:9cbb;:9cbb;:9cararp;MeaDaDp;Meawaqawakp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFbbbFbbbFbbbFbbbp9oaopxbbbFbbbFbbbFbbbFp9op9qarawp;Meaqp;Kecwp:RepxbFbbbFbbbFbbbFbbp9op9qaDawp;Meaqp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qpklbkadaiav;8qbbskaipxFubbFubbFubbFubbgxpklbdnalTmbcbhvabhdinadczfgmampbbbgopxbbbbbbFFbbbbbbFFgkp9oadpbbbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraipblbaDaopmlvorxmPsCXQL358E8Fp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgPp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;MeawaqawaPp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpkbbadaDakp9oaoarpmbezHdiOAlvCXorQLp9qpkbbadcafhdavclfgval6mbkkalaeSmbaiczfpxbbbbbbbbbbbbbbbbgopklbaiaopklbaiabalcitfgdaeciGglcitgv;8qbbaiaxpkladnalTmbaiaipblzgopxbbbbbbFFbbbbbbFFgkp9oaipblbgDaopmbediwDqkzHOAKY8AEgwczp:Reczp:Sep;6egraipblaaDaopmlvorxmPsCXQL358E8Fp9op;6eawczp:Sep;6egwp;Gearp;Gep;Kep;Legopxbbbbbbbbbbbbbbbbp:2egqarpxbbbjbbbjbbbjbbbjgPp9op9rp;Kegrpxb;:FSb;:FSb;:FSb;:FSararp;Meaoaop;MeawaqawaPp9op9rp;Kegrarp;Mep;Kep;Kep;Jep;Negwp;Mepxbbn0bbn0bbn0bbn0gqp;KepxFFbbFFbbFFbbFFbbp9oaoawp;Meaqp;Keczp:Rep9qgoarawp;Meaqp;KepxFFbbFFbbFFbbFFbbp9ogrpmwDKYqk8AExm35Ps8E8Fp9qpklzaiaDakp9oaoarpmbezHdiOAlvCXorQLp9qpklbkadaiav;8qbbkk:Iwllue97euo978Jjjjjbca9Rhidnaec98GglTmbcbhvabhoinaocKfpx:ji:1S:ji:1S:ji:1S:ji:1SaopbbbgraoczfgwpbbbgDpmlvorxmPsCXQL358E8Fgqczp:Segkpxibbbibbbibbbibbbp9qgxp;6ep;Negmaxaxp:1ep;7egxaxp;KearaDpmbediwDqkzHOAKY8AEgxczp:Reczp:Sep;6egrarp;Meaxczp:Sep;6egDaDp;Meaqczp:Reczp:Sep;6egqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jep;Mepxbbn0bbn0bbn0bbn0gxp;KepxFFbbFFbbFFbbFFbbgPp9oamaDp;Meaxp;Keczp:Rep9qgDamarp;Meaxp;KeaPp9oamaqp;Meaxp;Keczp:Rep9qgxpmwDKYqk8AExm35Ps8E8Fgrp5eakclp:RegmpEi:T:j83ibawarp5bampEd:T:j83ibaocwfaDaxpmbezHdiOAlvCXorQLgxp5eampEe:T:j83ibaoaxp5bampEb:T:j83ibaocafhoavclfgval6mbkkdnalaeSmbaiczfpxbbbbbbbbbbbbbbbbgmpklbaiampklbaiabalcitfgoaeciGgvcitgw;8qbbdnavTmbaipx:ji:1S:ji:1S:ji:1S:ji:1SaipblbgraipblzgDpmlvorxmPsCXQL358E8Fgqczp:Segkpxibbbibbbibbbibbbp9qgxp;6ep;Negmaxaxp:1ep;7egxaxp;KearaDpmbediwDqkzHOAKY8AEgxczp:Reczp:Sep;6egrarp;Meaxczp:Sep;6egDaDp;Meaqczp:Reczp:Sep;6egqaqp;Mep;Kep;Kep;Lepxbbbbbbbbbbbbbbbbp:4ep;Jep;Mepxbbn0bbn0bbn0bbn0gxp;KepxFFbbFFbbFFbbFFbbgPp9oamaDp;Meaxp;Keczp:Rep9qgDamarp;Meaxp;KeaPp9oamaqp;Meaxp;Keczp:Rep9qgxpmwDKYqk8AExm35Ps8E8Fgrp5eakclp:RegmpEi:T:j83iKaiarp5bampEd:T:j83izaiaDaxpmbezHdiOAlvCXorQLgxp5eampEe:T:j83iwaiaxp5bampEb:T:j83ibkaoaiaw;8qbbkk;uddiue978Jjjjjbc;ab9Rhidnadcd4ae2glc98GgvTmbcbheabhdinadadpbbbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepkbbadczfhdaeclfgeav6mbkkdnavalSmbaic8WfpxbbbbbbbbbbbbbbbbgopklbaicafaopklbaiczfaopklbaiaopklbaiabavcdtfgdalciGgecdtgv;8qbbdnaeTmbaiaipblbgocwp:Recwp:Sep;6eaocep:SepxbbjFbbjFbbjFbbjFp9opxbbjZbbjZbbjZbbjZp:Uep;Mepklbkadaiav;8qbbkk:CPvdue97euw97eu8Jjjjjbc8W9Rhiaec98Ghldndnadcl9hmbaipxbbbbbbbbbbbbbbbbgvpklbdnalTmbcbhoabhdinadpbbbhradpxbbuJbbuJbbuJbbuJaipblbarcKp:Tep9qgwcep:Seawp9qgDcdp:SeaDp9qgDclp:SeaDp9qgqp;6ep;NegDarcwp:RecKp:SegkarpxFbbbFbbbFbbbFbbbgxp9ogmp:Uep;6ep;Mepxbbn0bbn0bbn0bbn0gPp;Kecwp:RepxbFbbbFbbbFbbbFbbp9oaDamakp:Xearczp:RecKp:Segrp:Uep;6ep;MeaPp;Keaxp9op9qaDamakarp:Uep:Xep;6ep;MeaPp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qaDaqawcep:Rep9oawpxebbbebbbebbbebbbp9op9qp;6ep;MeaPp;KecKp:Rep9qpkbbadczfhdaoclfgoal6mbkkalaeSmeaiavpklaaicafabalcdtfgdaeciGglcdtgo;8qbbaiavpklbdnalTmbaipblahraipxbbuJbbuJbbuJbbuJaipblbarcKp:Tep9qgwcep:Seawp9qgDcdp:SeaDp9qgDclp:SeaDp9qgqp;6ep;NegDarcwp:RecKp:SegkarpxFbbbFbbbFbbbFbbbgxp9ogmp:Uep;6ep;Mepxbbn0bbn0bbn0bbn0gPp;Kecwp:RepxbFbbbFbbbFbbbFbbp9oaDamakp:Xearczp:RecKp:Segrp:Uep;6ep;MeaPp;Keaxp9op9qaDamakarp:Uep:Xep;6ep;MeaPp;Keczp:RepxbbFbbbFbbbFbbbFbp9op9qaDaqawcep:Rep9oawpxebbbebbbebbbebbbp9op9qp;6ep;MeaPp;KecKp:Rep9qpklakadaicafao;8qbbskaipxbbbbbbbbbbbbbbbbgvpklbdnalTmbcbhoabhdinadczfgspxbFu9hbFu9hbFu9hbFu9hadpbbbgDaspbbbgPpmlvorxmPsCXQL358E8Fgmczp:Teaipblbp9qgrcep:Searp9qgwcdp:Seawp9qgwclp:Seawp9qgwcwp:Seawp9qgqp;6ep;NegwaDaPpmbediwDqkzHOAKY8AEgDpxFFbbFFbbFFbbFFbbgPp9ogkaDczp:Segxp:Ueamczp:Reczp:Segmp:Xep;6ep;Mepxbbn0bbn0bbn0bbn0gDp;KeaPp9oawakaxamp:Uep:Xep;6ep;MeaDp;Keczp:Rep9qgxawaqarcep:Rep9oarpxebbbebbbebbbebbbp9op9qp;6ep;MeaDp;Keczp:Reawamakp:Uep;6ep;MeaDp;KeaPp9op9qgrpmwDKYqk8AExm35Ps8E8FpkbbadaxarpmbezHdiOAlvCXorQLpkbbadcafhdaoclfgoal6mbkkalaeSmbaiczfpxbbbbbbbbbbbbbbbbgrpklbaiarpklbaiabalcitfgdaeciGglcitgo;8qbbaiavpkladnalTmbaipxbFu9hbFu9hbFu9hbFu9haipblbgDaipblzgPpmlvorxmPsCXQL358E8Fgmczp:Teaipblap9qgrcep:Searp9qgwcdp:Seawp9qgwclp:Seawp9qgwcwp:Seawp9qgqp;6ep;NegwaDaPpmbediwDqkzHOAKY8AEgDpxFFbbFFbbFFbbFFbbgPp9ogkaDczp:Segxp:Ueamczp:Reczp:Segmp:Xep;6ep;Mepxbbn0bbn0bbn0bbn0gDp;KeaPp9oawakaxamp:Uep:Xep;6ep;MeaDp;Keczp:Rep9qgxawaqarcep:Rep9oarpxebbbebbbebbbebbbp9op9qp;6ep;MeaDp;Keczp:Reawamakp:Uep;6ep;MeaDp;KeaPp9op9qgrpmwDKYqk8AExm35Ps8E8FpklzaiaxarpmbezHdiOAlvCXorQLpklbkadaiao;8qbbkk9teiucbcbydj1jjbgeabcifc98GfgbBdj1jjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikkkebcjwklz:Dbb",t=new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,3,2,0,0,5,3,1,0,1,12,1,0,10,22,2,12,0,65,0,65,0,65,0,252,10,0,0,11,7,0,65,0,253,15,26,11]),n=new Uint8Array([32,0,65,2,1,106,34,33,3,128,11,4,13,64,6,253,10,7,15,116,127,5,8,12,40,16,19,54,20,9,27,255,113,17,42,67,24,23,146,148,18,14,22,45,70,69,56,114,101,21,25,63,75,136,108,28,118,29,73,115]);if(typeof WebAssembly!="object")return{supported:!1};var i=WebAssembly.validate(t)?o(e):o(r),s,a=WebAssembly.instantiate(i,{}).then(function(g){s=g.instance,s.exports.__wasm_call_ctors()});function o(g){for(var b=new Uint8Array(g.length),x=0;x96?_-97:_>64?_-39:_+4}for(var v=0,x=0;x0?m(g,b,x,h[_],l[v]):a.then(function(){var S=new Uint8Array(g*b);return c(s,s.exports[h[_]],S,g,b,x,s.exports[l[v]]),S})}}})();const Yh=new WeakMap;class sT extends Ei{constructor(e){super(e),this.decoderPath="",this.decoderConfig={},this.decoderBinary=null,this.decoderPending=null,this.workerLimit=4,this.workerPool=[],this.workerNextTaskID=1,this.workerSourceURL="",this.defaultAttributeIDs={position:"POSITION",normal:"NORMAL",color:"COLOR",uv:"TEX_COORD"},this.defaultAttributeTypes={position:"Float32Array",normal:"Float32Array",color:"Float32Array",uv:"Float32Array"}}setDecoderPath(e){return this.decoderPath=e,this}setDecoderConfig(e){return this.decoderConfig=e,this}setWorkerLimit(e){return this.workerLimit=e,this}load(e,t,n,i){const s=new Vi(this.manager);s.setPath(this.path),s.setResponseType("arraybuffer"),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(e,a=>{this.parse(a,t,i)},n,i)}parse(e,t,n=()=>{}){this.decodeDracoFile(e,t,null,null,mt,n).catch(n)}decodeDracoFile(e,t,n,i,s=Ct,a=()=>{}){const o={attributeIDs:n||this.defaultAttributeIDs,attributeTypes:i||this.defaultAttributeTypes,useUniqueIDs:!!n,vertexColorSpace:s};return this.decodeGeometry(e,o).then(t).catch(a)}decodeGeometry(e,t){const n=JSON.stringify(t);if(Yh.has(e)){const c=Yh.get(e);if(c.key===n)return c.promise;if(e.byteLength===0)throw new Error("THREE.DRACOLoader: Unable to re-decode a buffer with different settings. Buffer has already been transferred.")}let i;const s=this.workerNextTaskID++,a=e.byteLength,o=this._getWorker(s,a).then(c=>(i=c,new Promise((l,h)=>{i._callbacks[s]={resolve:l,reject:h},i.postMessage({type:"decode",id:s,taskConfig:t,buffer:e},[e])}))).then(c=>this._createGeometry(c.geometry));return o.catch(()=>!0).then(()=>{i&&s&&this._releaseTask(i,s)}),Yh.set(e,{key:n,promise:o}),o}_createGeometry(e){const t=new on;e.index&&t.setIndex(new Lt(e.index.array,1));for(let n=0;n{n.load(e,i,void 0,s)})}preload(){return this._initDecoder(),this}_initDecoder(){if(this.decoderPending)return this.decoderPending;const e=typeof WebAssembly!="object"||this.decoderConfig.type==="js",t=[];return e?t.push(this._loadLibrary("draco_decoder.js","text")):(t.push(this._loadLibrary("draco_wasm_wrapper.js","text")),t.push(this._loadLibrary("draco_decoder.wasm","arraybuffer"))),this.decoderPending=Promise.all(t).then(n=>{const i=n[0];e||(this.decoderConfig.wasmBinary=n[1]);const s=rT.toString(),a=["/* draco decoder */",i,"","/* worker */",s.substring(s.indexOf("{")+1,s.lastIndexOf("}"))].join(` +`);this.workerSourceURL=URL.createObjectURL(new Blob([a]))}),this.decoderPending}_getWorker(e,t){return this._initDecoder().then(()=>{if(this.workerPool.lengths._taskLoad?-1:1});const n=this.workerPool[this.workerPool.length-1];return n._taskCosts[e]=t,n._taskLoad+=t,n})}_releaseTask(e,t){e._taskLoad-=e._taskCosts[t],delete e._callbacks[t],delete e._taskCosts[t]}debug(){console.log("Task load: ",this.workerPool.map(e=>e._taskLoad))}dispose(){for(let e=0;e{const u=h.draco,d=new u.Decoder;try{const f=t(u,d,new Int8Array(c),l),p=f.attributes.map(m=>m.array.buffer);f.index&&p.push(f.index.array.buffer),self.postMessage({type:"decode",id:o.id,geometry:f},p)}catch(f){console.error(f),self.postMessage({type:"error",id:o.id,error:f.message})}finally{u.destroy(d)}});break}};function t(a,o,c,l){const h=l.attributeIDs,u=l.attributeTypes;let d,f;const p=o.GetEncodedGeometryType(c);if(p===a.TRIANGULAR_MESH)d=new a.Mesh,f=o.DecodeArrayToMesh(c,c.byteLength,d);else if(p===a.POINT_CLOUD)d=new a.PointCloud,f=o.DecodeArrayToPointCloud(c,c.byteLength,d);else throw new Error("THREE.DRACOLoader: Unexpected geometry type.");if(!f.ok()||d.ptr===0)throw new Error("THREE.DRACOLoader: Decoding failed: "+f.error_msg());const m={index:null,attributes:[]};for(const A in h){const g=self[u[A]];let b,x;if(l.useUniqueIDs)x=h[A],b=o.GetAttributeByUniqueId(d,x);else{if(x=o.GetAttributeId(d,a[h[A]]),x===-1)continue;b=o.GetAttribute(d,x)}const _=i(a,o,d,A,g,b);A==="color"&&(_.vertexColorSpace=l.vertexColorSpace),m.attributes.push(_)}return p===a.TRIANGULAR_MESH&&(m.index=n(a,o,d)),a.destroy(d),m}function n(a,o,c){const h=c.num_faces()*3,u=h*4,d=a._malloc(u);o.GetTrianglesUInt32Array(c,u,d);const f=new Uint32Array(a.HEAPF32.buffer,d,h).slice();return a._free(d),{array:f,itemSize:1}}function i(a,o,c,l,h,u){const d=c.num_points(),f=u.num_components(),p=s(a,h),m=f*h.BYTES_PER_ELEMENT,A=Math.ceil(m/4)*4,g=A/h.BYTES_PER_ELEMENT,b=d*m,x=d*A,_=a._malloc(b);o.GetAttributeDataArrayForAllPoints(c,u,p,b,_);const v=new h(a.HEAPF32.buffer,_,b/h.BYTES_PER_ELEMENT);let S;if(m===A)S=v.slice();else{S=new h(x/h.BYTES_PER_ELEMENT);let I=0;for(let E=0,C=v.length;E=2.0 are supported."));return}const l=new OT(s,{path:t||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});l.fileLoader.setRequestHeader(this.requestHeader);for(let h=0;h=0&&o[u]===void 0&&console.warn('THREE.GLTFLoader: Unknown extension "'+u+'".')}}l.setExtensions(a),l.setPlugins(o),l.parse(n,i)}parseAsync(e,t){const n=this;return new Promise(function(i,s){n.parse(e,t,i,s)})}}function oT(){let r={};return{get:function(e){return r[e]},add:function(e,t){r[e]=t},remove:function(e){delete r[e]},removeAll:function(){r={}}}}function Gt(r,e,t){const n=r.json.materials[e];return n.extensions&&n.extensions[t]?n.extensions[t]:null}const Je={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_DISPERSION:"KHR_materials_dispersion",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_MATERIALS_BUMP:"EXT_materials_bump",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",KHR_MESHOPT_COMPRESSION:"KHR_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class cT{constructor(e){this.parser=e,this.name=Je.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const e=this.parser,t=this.parser.json.nodes||[];for(let n=0,i=t.length;n=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return t.loadTextureImage(e,s.source,a)}}class vT{constructor(e){this.parser=e,this.name=Je.EXT_TEXTURE_WEBP}loadTexture(e){const t=this.name,n=this.parser,i=n.json,s=i.textures[e];if(!s.extensions||!s.extensions[t])return null;const a=s.extensions[t],o=i.images[a.source];let c=n.textureLoader;if(o.uri){const l=n.options.manager.getHandler(o.uri);l!==null&&(c=l)}return n.loadTextureImage(e,a.source,c)}}class yT{constructor(e){this.parser=e,this.name=Je.EXT_TEXTURE_AVIF}loadTexture(e){const t=this.name,n=this.parser,i=n.json,s=i.textures[e];if(!s.extensions||!s.extensions[t])return null;const a=s.extensions[t],o=i.images[a.source];let c=n.textureLoader;if(o.uri){const l=n.options.manager.getHandler(o.uri);l!==null&&(c=l)}return n.loadTextureImage(e,a.source,c)}}class YA{constructor(e,t){this.name=t,this.parser=e}loadBufferView(e){const t=this.parser.json,n=t.bufferViews[e];if(n.extensions&&n.extensions[this.name]){const i=n.extensions[this.name],s=this.parser.getDependency("buffer",i.buffer),a=this.parser.options.meshoptDecoder;if(!a||!a.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return s.then(function(o){const c=i.byteOffset||0,l=i.byteLength||0,h=i.count,u=i.byteStride,d=new Uint8Array(o,c,l);return a.decodeGltfBufferAsync?a.decodeGltfBufferAsync(h,u,d,i.mode,i.filter).then(function(f){return f.buffer}):a.ready.then(function(){const f=new ArrayBuffer(h*u);return a.decodeGltfBuffer(new Uint8Array(f),h,u,d,i.mode,i.filter),f})})}else return null}}let ST=class{constructor(e){this.name=Je.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){const t=this.parser.json,n=t.nodes[e];if(!n.extensions||!n.extensions[this.name]||n.mesh===void 0)return null;const i=t.meshes[n.mesh];for(const l of i.primitives)if(l.mode!==Fn.TRIANGLES&&l.mode!==Fn.TRIANGLE_STRIP&&l.mode!==Fn.TRIANGLE_FAN&&l.mode!==void 0)return null;const a=n.extensions[this.name].attributes,o=[],c={};for(const l in a)o.push(this.parser.getDependency("accessor",a[l]).then(h=>(c[l]=h,c[l])));return o.length<1?null:(o.push(this.parser.createNodeMesh(e)),Promise.all(o).then(l=>{const h=l.pop(),u=h.isGroup?h.children:[h],d=l[0].count,f=[];for(const p of u){const m=new Oe,A=new R,g=new pn,b=new R(1,1,1),x=new Ev(p.geometry,p.material,d);for(let _=0;_0||r.search(/^data\:image\/jpeg/)===0?"image/jpeg":r.search(/\.webp($|\?)/i)>0||r.search(/^data\:image\/webp/)===0?"image/webp":r.search(/\.ktx2($|\?)/i)>0||r.search(/^data\:image\/ktx2/)===0?"image/ktx2":"image/png"}const UT=new Oe;class OT{constructor(e={},t={}){this.json=e,this.extensions={},this.plugins={},this.options=t,this.cache=new oT,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let n=!1,i=-1,s=!1,a=-1;if(typeof navigator<"u"&&typeof navigator.userAgent<"u"){const o=navigator.userAgent;n=/^((?!chrome|android).)*safari/i.test(o)===!0;const c=o.match(/Version\/(\d+)/);i=n&&c?parseInt(c[1],10):-1,s=o.indexOf("Firefox")>-1,a=s?o.match(/Firefox\/([0-9]+)\./)[1]:-1}typeof createImageBitmap>"u"||n&&i<17||s&&a<98?this.textureLoader=new yb(this.options.manager):this.textureLoader=new Dy(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new Vi(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),this.options.crossOrigin==="use-credentials"&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){const n=this,i=this.json,s=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(a){return a._markDefs&&a._markDefs()}),Promise.all(this._invokeAll(function(a){return a.beforeRoot&&a.beforeRoot()})).then(function(){return Promise.all([n.getDependencies("scene"),n.getDependencies("animation"),n.getDependencies("camera")])}).then(function(a){const o={scene:a[0][i.scene||0],scenes:a[0],animations:a[1],cameras:a[2],asset:i.asset,parser:n,userData:{}};return Ts(s,o,i),hi(o,i),Promise.all(n._invokeAll(function(c){return c.afterRoot&&c.afterRoot(o)})).then(function(){for(const c of o.scenes)c.updateMatrixWorld();e(o)})}).catch(t)}_markDefs(){const e=this.json.nodes||[],t=this.json.skins||[],n=this.json.meshes||[];for(let i=0,s=t.length;i{const c=this.associations.get(a);c!=null&&this.associations.set(o,c);for(const[l,h]of a.children.entries())s(h,o.children[l])};return s(n,i),i.name+="_instance_"+e.uses[t]++,i}_invokeOne(e){const t=Object.values(this.plugins);t.push(this);for(let n=0;n=2&&A.setY(C,S[I*c+1]),c>=3&&A.setZ(C,S[I*c+2]),c>=4&&A.setW(C,S[I*c+3]),c>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}A.normalized=p}return A})}loadTexture(e){const t=this.json,n=this.options,s=t.textures[e].source,a=t.images[s];let o=this.textureLoader;if(a.uri){const c=n.manager.getHandler(a.uri);c!==null&&(o=c)}return this.loadTextureImage(e,s,o)}loadTextureImage(e,t,n){const i=this,s=this.json,a=s.textures[e],o=s.images[t],c=(o.uri||o.bufferView)+":"+a.sampler;if(this.textureCache[c])return this.textureCache[c];const l=this.loadImageSource(t,n).then(function(h){h.flipY=!1,h.name=a.name||o.name||"",h.name===""&&typeof o.uri=="string"&&o.uri.startsWith("data:image/")===!1&&(h.name=o.uri);const d=(s.samplers||{})[a.sampler]||{};return h.magFilter=ZA[d.magFilter]||qe,h.minFilter=ZA[d.minFilter]||vn,h.wrapS=eg[d.wrapS]||ti,h.wrapT=eg[d.wrapT]||ti,h.generateMipmaps=!h.isCompressedTexture&&h.minFilter!==St&&h.minFilter!==qe,i.associations.set(h,{textures:e}),h}).catch(function(){return null});return this.textureCache[c]=l,l}loadImageSource(e,t){const n=this,i=this.json,s=this.options;if(this.sourceCache[e]!==void 0)return this.sourceCache[e].then(u=>u.clone());const a=i.images[e],o=self.URL||self.webkitURL;let c=a.uri||"",l=!1;if(a.bufferView!==void 0)c=n.getDependency("bufferView",a.bufferView).then(function(u){l=!0;const d=new Blob([u],{type:a.mimeType});return c=o.createObjectURL(d),c});else if(a.uri===void 0)throw new Error("THREE.GLTFLoader: Image "+e+" is missing URI and bufferView");const h=Promise.resolve(c).then(function(u){return new Promise(function(d,f){let p=d;t.isImageBitmapLoader===!0&&(p=function(m){const A=new Rt(m);A.needsUpdate=!0,d(A)}),t.load(bo.resolveURL(u,s.path),p,void 0,f)})}).then(function(u){return l===!0&&o.revokeObjectURL(c),hi(u,a),u.userData.mimeType=a.mimeType||NT(a.uri),u}).catch(function(u){throw console.error("THREE.GLTFLoader: Couldn't load texture",c),u});return this.sourceCache[e]=h,h}assignTexture(e,t,n,i){const s=this;return this.getDependency("texture",n.index).then(function(a){if(!a)return null;if(n.texCoord!==void 0&&n.texCoord>0&&(a=a.clone(),a.channel=n.texCoord),s.extensions[Je.KHR_TEXTURE_TRANSFORM]){const o=n.extensions!==void 0?n.extensions[Je.KHR_TEXTURE_TRANSFORM]:void 0;if(o){const c=s.associations.get(a);a=s.extensions[Je.KHR_TEXTURE_TRANSFORM].extendTexture(a,o),s.associations.set(a,c)}}return i!==void 0&&(a.colorSpace=i),e[t]=a,a})}assignFinalMaterial(e){const t=e.geometry;let n=e.material;const i=t.attributes.tangent===void 0,s=t.attributes.color!==void 0,a=t.attributes.normal===void 0;if(e.isPoints){const o="PointsMaterial:"+n.uuid;let c=this.cache.get(o);c||(c=new rb,Zn.prototype.copy.call(c,n),c.color.copy(n.color),c.map=n.map,c.sizeAttenuation=!1,this.cache.add(o,c)),n=c}else if(e.isLine){const o="LineBasicMaterial:"+n.uuid;let c=this.cache.get(o);c||(c=new sb,Zn.prototype.copy.call(c,n),c.color.copy(n.color),c.map=n.map,this.cache.add(o,c)),n=c}if(i||s||a){let o="ClonedMaterial:"+n.uuid+":";i&&(o+="derivative-tangents:"),s&&(o+="vertex-colors:"),a&&(o+="flat-shading:");let c=this.cache.get(o);c||(c=n.clone(),s&&(c.vertexColors=!0),a&&(c.flatShading=!0),i&&(c.normalScale&&(c.normalScale.y*=-1),c.clearcoatNormalScale&&(c.clearcoatNormalScale.y*=-1)),this.cache.add(o,c),this.associations.set(c,this.associations.get(n))),n=c}e.material=n}getMaterialType(){return Oo}loadMaterial(e){const t=this,n=this.json,i=this.extensions,s=n.materials[e];let a;const o={},c=s.extensions||{},l=[];if(c[Je.KHR_MATERIALS_UNLIT]){const u=i[Je.KHR_MATERIALS_UNLIT];a=u.getMaterialType(),l.push(u.extendParams(o,s,t))}else{const u=s.pbrMetallicRoughness||{};if(o.color=new Me(1,1,1),o.opacity=1,Array.isArray(u.baseColorFactor)){const d=u.baseColorFactor;o.color.setRGB(d[0],d[1],d[2],Ct),o.opacity=d[3]}u.baseColorTexture!==void 0&&l.push(t.assignTexture(o,"map",u.baseColorTexture,mt)),o.metalness=u.metallicFactor!==void 0?u.metallicFactor:1,o.roughness=u.roughnessFactor!==void 0?u.roughnessFactor:1,u.metallicRoughnessTexture!==void 0&&(l.push(t.assignTexture(o,"metalnessMap",u.metallicRoughnessTexture)),l.push(t.assignTexture(o,"roughnessMap",u.metallicRoughnessTexture))),a=this._invokeOne(function(d){return d.getMaterialType&&d.getMaterialType(e)}),l.push(Promise.all(this._invokeAll(function(d){return d.extendMaterialParams&&d.extendMaterialParams(e,o)})))}s.doubleSided===!0&&(o.side=Wt);const h=s.alphaMode||Zh.OPAQUE;if(h===Zh.BLEND?(o.transparent=!0,o.depthWrite=!1):(o.transparent=!1,h===Zh.MASK&&(o.alphaTest=s.alphaCutoff!==void 0?s.alphaCutoff:.5)),s.normalTexture!==void 0&&a!==fn&&(l.push(t.assignTexture(o,"normalMap",s.normalTexture)),o.normalScale=new pe(1,1),s.normalTexture.scale!==void 0)){const u=s.normalTexture.scale;o.normalScale.set(u,u)}if(s.occlusionTexture!==void 0&&a!==fn&&(l.push(t.assignTexture(o,"aoMap",s.occlusionTexture)),s.occlusionTexture.strength!==void 0&&(o.aoMapIntensity=s.occlusionTexture.strength)),s.emissiveFactor!==void 0&&a!==fn){const u=s.emissiveFactor;o.emissive=new Me().setRGB(u[0],u[1],u[2],Ct)}return s.emissiveTexture!==void 0&&a!==fn&&l.push(t.assignTexture(o,"emissiveMap",s.emissiveTexture,mt)),Promise.all(l).then(function(){const u=new a(o);return s.name&&(u.name=s.name),hi(u,s),t.associations.set(u,{materials:e}),s.extensions&&Ts(i,u,s),u})}createUniqueName(e){const t=nt.sanitizeNodeName(e||"");return t in this.nodeNamesUsed?t+"_"+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){const t=this,n=this.extensions,i=this.primitiveCache;function s(o){return n[Je.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(o,t).then(function(c){return tg(c,o,t)})}const a=[];for(let o=0,c=e.length;o0&&PT(g,s),g.name=t.createUniqueName(s.name||"mesh_"+e),hi(g,s),A.extensions&&Ts(i,g,A),t.assignFinalMaterial(g),u.push(g)}for(let f=0,p=u.length;f0){const f=h.userData.pivot,p=u[0];h.pivot=new R().fromArray(f),h.position.x-=f[0],h.position.y-=f[1],h.position.z-=f[2],p.position.set(0,0,0),delete h.userData.pivot}return h})}_loadNodeShallow(e){const t=this.json,n=this.extensions,i=this;if(this.nodeCache[e]!==void 0)return this.nodeCache[e];const s=t.nodes[e],a=s.name?i.createUniqueName(s.name):"",o=[],c=i._invokeOne(function(l){return l.createNodeMesh&&l.createNodeMesh(e)});return c&&o.push(c),s.camera!==void 0&&o.push(i.getDependency("camera",s.camera).then(function(l){return i._getNodeRef(i.cameraCache,s.camera,l)})),i._invokeAll(function(l){return l.createNodeAttachment&&l.createNodeAttachment(e)}).forEach(function(l){o.push(l)}),this.nodeCache[e]=Promise.all(o).then(function(l){let h;if(s.isBone===!0?h=new ib:l.length>1?h=new ds:l.length===1?h=l[0]:h=new ht,h!==l[0])for(let u=0,d=l.length;u1){const u=i.associations.get(h);i.associations.set(h,{...u})}return i.associations.get(h).nodes=e,h}),this.nodeCache[e]}loadScene(e){const t=this.extensions,n=this.json.scenes[e],i=this,s=new ds;n.name&&(s.name=i.createUniqueName(n.name)),hi(s,n),n.extensions&&Ts(t,s,n);const a=n.nodes||[],o=[];for(let c=0,l=a.length;c{const u=new Map;for(const[d,f]of i.associations)(d instanceof Zn||d instanceof Rt)&&u.set(d,f);return h.traverse(d=>{const f=i.associations.get(d);f!=null&&u.set(d,f)}),u};return i.associations=l(s),s})}_createAnimationTracks(e,t,n,i,s){const a=[],o=e.name?e.name:e.uuid,c=[];ts[s.path]===ts.weights?e.traverse(function(d){d.morphTargetInfluences&&c.push(d.name?d.name:d.uuid)}):c.push(o);let l;switch(ts[s.path]){case ts.weights:l=ua;break;case ts.rotation:l=da;break;case ts.translation:case ts.scale:l=fa;break;default:n.itemSize===1?l=ua:l=fa;break}const h=i.interpolation!==void 0?BT[i.interpolation]:oa,u=this._getArrayFromAccessor(n);for(let d=0,f=c.length;d{const i=this._getIdleWorker();i!==-1?(this._initWorker(i),this.workerStatus|=1<e.terminate()),this.workersResolve.length=0,this.workers.length=0,this.queue.length=0,this.workerStatus=0}}const GT=0,ng=2,HT=1,ig=2,zT=0,VT=1,WT=10,qT=0,Gb=9,Hb=15,zb=16,Vb=22,Wb=37,qb=43,jb=76,Xb=83,Kb=97,$b=100,Yb=103,Jb=109,Zb=122,ex=123,tx=131,nx=132,ix=133,sx=134,rx=137,ax=138,ox=139,cx=140,lx=141,hx=142,ux=145,dx=146,fx=148,px=152,Ax=153,gx=154,mx=155,bx=156,xx=157,Ex=158,_x=165,vx=166,yx=1000054e3,Sx=1000054001,Cx=1000054004,Mx=1000054005,$f=1000066e3,Ix=1000066004;class Pa{constructor(e,t,n,i){this._dataView=void 0,this._littleEndian=void 0,this._offset=void 0,this._dataView=new DataView(e.buffer,e.byteOffset+t,n),this._littleEndian=i,this._offset=0}_nextUint8(){const e=this._dataView.getUint8(this._offset);return this._offset+=1,e}_nextUint16(){const e=this._dataView.getUint16(this._offset,this._littleEndian);return this._offset+=2,e}_nextUint32(){const e=this._dataView.getUint32(this._offset,this._littleEndian);return this._offset+=4,e}_nextUint64(){const e=this._dataView.getUint32(this._offset,this._littleEndian)+4294967296*this._dataView.getUint32(this._offset+4,this._littleEndian);return this._offset+=8,e}_nextInt32(){const e=this._dataView.getInt32(this._offset,this._littleEndian);return this._offset+=4,e}_nextUint8Array(e){const t=new Uint8Array(this._dataView.buffer,this._dataView.byteOffset+this._offset,e);return this._offset+=e,t}_skip(e){return this._offset+=e,this}_scan(e,t=0){const n=this._offset;let i=0;for(;this._dataView.getUint8(this._offset)!==t&&ie.arrayBuffer()).then(e=>WebAssembly.instantiate(e,nu)).then(this._init):WebAssembly.instantiate(Buffer.from(rg,"base64"),nu).then(this._init),tu)}_init(e){Ni=e.instance,nu.env.emscripten_notify_memory_growth(0)}decode(e,t=0){if(!Ni)throw new Error("ZSTDDecoder: Await .init() before decoding.");const n=e.byteLength,i=Ni.exports.malloc(n);ef.set(e,i),t=t||Number(Ni.exports.ZSTD_findDecompressedSize(i,n));const s=Ni.exports.malloc(t),a=Ni.exports.ZSTD_decompress(s,t,i,n),o=ef.slice(s,s+a);return Ni.exports.free(i),Ni.exports.free(s),o}}const rg="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IAMNACAEQQNxBEADQCACRQ0FIAAgAkF/aiICaiIDIAEgAmotAAA6AAAgA0EDcQ0ACwsgAkEDTQ0AA0AgACACQXxqIgJqIAEgAmooAgA2AgAgAkEDSw0ACwsgAkUNAgNAIAAgAkF/aiICaiABIAJqLQAAOgAAIAINAAsMAgsgAkEDTQ0AIAIhBANAIAMgASgCADYCACABQQRqIQEgA0EEaiEDIARBfGoiBEEDSw0ACyACQQNxIQILIAJFDQADQCADIAEtAAA6AAAgA0EBaiEDIAFBAWohASACQX9qIgINAAsLIAAL8wICAn8BfgJAIAJFDQAgACACaiIDQX9qIAE6AAAgACABOgAAIAJBA0kNACADQX5qIAE6AAAgACABOgABIANBfWogAToAACAAIAE6AAIgAkEHSQ0AIANBfGogAToAACAAIAE6AAMgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIEayICQSBJDQAgAa0iBUIghiAFhCEFIAMgBGohAQNAIAEgBTcDGCABIAU3AxAgASAFNwMIIAEgBTcDACABQSBqIQEgAkFgaiICQR9LDQALCyAACy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAIajYCACADCy8BAn8gACgCBCAAKAIAQQJ0aiICLQACIQMgACACLwEAIAEgAi0AAxAFajYCACADCx8AIAAgASACKAIEEAg2AgAgARAEGiAAIAJBCGo2AgQLCAAgAGdBH3MLugUBDX8jAEEQayIKJAACfyAEQQNNBEAgCkEANgIMIApBDGogAyAEEAsaIAAgASACIApBDGpBBBAVIgBBbCAAEAMbIAAgACAESxsMAQsgAEEAIAEoAgBBAXRBAmoQECENQVQgAygAACIGQQ9xIgBBCksNABogAiAAQQVqNgIAIAMgBGoiAkF8aiEMIAJBeWohDiACQXtqIRAgAEEGaiELQQQh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ASIDNgLE4AEgACgCvOABIQQgACABNgK84AEgACABIAJqNgK44AEgACABIAQgA2tqNgLA4AELpgEBAX8gACAAKALs4QEQFjYCyOABIABCADcD+OABIABCADcDuOABIABBwOABakIANwMAIABBqNAAaiIBQYyAgOAANgIAIABBADYCmOIBIABCADcDiOEBIABCAzcDgOEBIABBrNABakHgEikCADcCACAAQbTQAWpB6BIoAgA2AgAgACABNgIMIAAgAEGYIGo2AgggACAAQaAwajYCBCAAIABBEGo2AgALYQEBf0G4fyEDAkAgAUEDSQ0AIAIgABAhIgFBA3YiADYCCCACIAFBAXE2AgQgAiABQQF2QQNxIgM2AgACQCADQX9qIgFBAksNAAJAIAFBAWsOAgEAAgtBbA8LIAAhAwsgAwsMACAAIAEgAkEAEC4LiAQCA38CfiADEBYhBCAAQQBBKBAQIQAgBCACSwRAIAQPCyABRQRAQX8PCwJAAkAgA0EBRg0AIAEoAAAiBkGo6r5pRg0AQXYhAyAGQXBxQdDUtMIBRw0BQQghAyACQQhJDQEgAEEAQSgQECEAIAEoAAQhASAAQQE2AhQgACABrTcDAEEADwsgASACIAMQLyIDIAJLDQAgACADNgIYQXIhAyABIARqIgVBf2otAAAiAkEIcQ0AIAJBIHEiBkUEQEFwIQMgBS0AACIFQacBSw0BIAVBB3GtQgEgBUEDdkEKaq2GIgdCA4h+IAd8IQggBEEBaiEECyACQQZ2IQMgAkECdiEFAkAgAkEDcUF/aiICQQJLBEBBACECDAELAkACQAJAIAJBAWsOAgECAAsgASAEai0AACECIARBAWohBAwCCyABIARqLwAAIQIgBEECaiEEDAELIAEgBGooAAAhAiAEQQRqIQQLIAVBAXEhBQJ+AkACQAJAIANBf2oiA0ECTQRAIANBAWsOAgIDAQtCfyAGRQ0DGiABIARqMQAADAMLIAEgBGovAACtQoACfAwCCyABIARqKAAArQwBCyABIARqKQAACyEHIAAgBTYCICAAIAI2AhwgACAHNwMAQQAhAyAAQQA2AhQgACAHIAggBhsiBzcDCCAAIAdCgIAIIAdCgIAIVBs+AhALIAMLWwEBf0G4fyEDIAIQFiICIAFNBH8gACACakF/ai0AACIAQQNxQQJ0QaAeaigC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C0Egak8NAQsgByAHKQNoNwMQIAcgBykDYDcDCCAEIA0gB0EIaiAHQdwAaiAPIA4gESAQEB4hCwwBCyACIARqIQggBCAKEAcgAkERTwRAIARBEGohAgNAIAIgCkEQaiIKEAcgAkEQaiICIAhJDQALCyAIIAlrIQIgByATNgJcIAkgCCAOa0sEQCAJIAggEWtLBEBBbCELDAILIBAgAiAOayICaiIKIANqIBBNBEAgCCAKIAMQDxoMAgsgCCAKQQAgAmsQDyEIIAcgAiADaiIDNgJkIAggAmshCCAOIQILIAlBEE8EQCADIAhqIQMDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALDAELAkAgCUEHTQRAIAggAi0AADoAACAIIAItAAE6AAEgCCACLQACOgACIAggAi0AAzoAAyAIQQRqIAIgCUECdCIDQcAeaigCAGoiAhAXIAIgA0HgHmooAgBrIQIgBygCZCEDDAELIAggAhAMCyADQQlJDQAgAyAIaiEDIAhBCGoiCCACQQhqIgJrQQ9MBEADQCAIIAIQDCACQQhqIQIgCEEIaiIIIANJDQAMAgALAAsDQCAIIAIQByACQRBqIQIgCEEQaiIIIANJDQALCyAHQRhqEAQaIAsgDCALEAMiAhshDCAEIAQgC2ogAhshBCAFQX9qIgUNAAsgDBADDQFBbCEMIAdBGGoQBEECSQ0BQQAhCANAIAhBA0cEQCAAIAhBAnQiAmpBrNABaiACIAdqKAJENgIAIAhBAWohCAwBCwsgBygCXCEIC0G6fyEMIA8gCGsiACANIARrSw0AIAQEfyAEIAggABALIABqBUEACyABayEMCyAHQfAAaiQAIAwLkRcCFn8FfiMAQdABayIHJAAgByAAKALw4QEiCDYCvAEgASACaiESIAggACgCgOIBaiETAkACQCAFRQRAIAEhAwwBCyAAKALE4AEhESAAKALA4AEhFSAAKAK84AEhDyAAQQE2AozhAUEAIQgDQCAIQQNHBEAgByAIQQJ0IgJqIAAgAmpBrNABaigCADYCVCAIQQFqIQgMAQsLIAcgETYCZCAHIA82AmAgByABIA9rNgJoQWwhECAHQShqIAMgBBAGEAMNASAFQQQgBUEESBshFyAHQTxqIAdBKGogACgCABATIAdBxABqIAdBKGogACgCCBATIAdBzABqIAdB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IAdB0AFqJAAgEAslACAAQgA3AgAgAEEAOwEIIABBADoACyAAIAE2AgwgACACOgAKC7QFAQN/IwBBMGsiBCQAIABB/wFqIgVBfWohBgJAIAMvAQIEQCAEQRhqIAEgAhAGIgIQAw0BIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahASOgAAIAMgBEEIaiAEQRhqEBI6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0FIAEgBEEQaiAEQRhqEBI6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBSABIARBCGogBEEYahASOgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEjoAACABIAJqIABrIQIMAwsgAyAEQRBqIARBGGoQEjoAAiADIARBCGogBEEYahASOgADIANBBGohAwwAAAsACyAEQRhqIAEgAhAGIgIQAw0AIARBEGogBEEYaiADEBwgBEEIaiAEQRhqIAMQHCAAIQMDQAJAIARBGGoQBCADIAZPckUEQCADIARBEGogBEEYahAROgAAIAMgBEEIaiAEQRhqEBE6AAEgBEEYahAERQ0BIANBAmohAwsgBUF+aiEFAn8DQEG6fyECIAMiASAFSw0EIAEgBEEQaiAEQRhqEBE6AAAgAUEBaiEDIARBGGoQBEEDRgRAQQIhAiAEQQhqDAILIAMgBUsNBCABIARBCGogBEEYahAROgABIAFBAmohA0EDIQIgBEEYahAEQQNHDQALIARBEGoLIQUgAyAFIARBGGoQEToAACABIAJqIABrIQIMAgsgAyAEQRBqIARBGGoQEToAAiADIARBCGogBEEYahAROgADIANBBGohAwwAAAsACyAEQTBqJAAgAgtpAQF/An8CQAJAIAJBB00NACABKAAAQbfIwuF+Rw0AIAAgASgABDYCmOIBQWIgAEEQaiABIAIQPiIDEAMNAhogAEKBgICAEDcDiOEBIAAgASADaiACIANrECoMAQsgACABIAIQKgtBAAsLrQMBBn8jAEGAAWsiAyQAQWIhCAJAIAJBCUkNACAAQZjQAGogAUEIaiIEIAJBeGogAEGY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wOABCwutAgIEfwF+IwBBQGoiBCQAAkACQCACQQhJDQAgASgAAEFwcUHQ1LTCAUcNACABIAIQIiEBIABCADcDCCAAQQA2AgQgACABNgIADAELIARBGGogASACEC0iAxADBEAgACADEBoMAQsgAwRAIABBuH8QGgwBCyACIAQoAjAiA2shAiABIANqIQMDQAJAIAAgAyACIARBCGoQLCIFEAMEfyAFBSACIAVBA2oiBU8NAUG4fwsQGgwCCyAGQQFqIQYgAiAFayECIAMgBWohAyAEKAIMRQ0ACyAEKAI4BEAgAkEDTQRAIABBuH8QGgwCCyADQQRqIQMLIAQoAighAiAEKQMYIQcgAEEANgIEIAAgAyABazYCACAAIAIgBmytIAcgB0J/URs3AwgLIARBQGskAAslAQF/IwBBEGsiAiQAIAIgACABEFEgAigCACEAIAJBEGokACAAC30BBH8jAEGQBGsiBCQAIARB/wE2AggCQCAEQRBqIARBCGogBEEMaiABIAIQFSIGEAMEQCAGIQUMAQtBVCEFIAQoAgwiB0EGSw0AIAMgBEEQaiAEKAIIIAcQQSIFEAMNACAAIAEgBmogAiAGayADEDwhBQsgBEGQBGokACAFC4cBAgJ/An5BABAWIQMCQANAIAEgA08EQAJAIAAoAABBcHFB0NS0wgFGBEAgACABECIiAhADRQ0BQn4PCyAAIAEQVSIEQn1WDQMgBCAFfCIFIARUIQJCfiEEIAINAyAAIAEQUiICEAMNAwsgASACayEBIAAgAmohAAwBCwtCfiAFIAEbIQQLIAQLPwIBfwF+IwBBMGsiAiQAAn5CfiACQQhqIAAgARAtDQAaQgAgAigCHEEBRg0AGiACKQMICyEDIAJBMGokACADC40BAQJ/IwBBMGsiASQAAkAgAEUNACAAKAKI4gENACABIABB/OEBaigCADYCKCABIAApAvThATcDICAAEDAgACgCqOIBIQIgASABKAIoNgIYIAEgASkDIDcDECACIAFBEGoQGyAAQQA2AqjiASABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALKgECfyMAQRBrIgAkACAAQQA2AgggAEIANwMAIAAQWCEBIABBEGokACABC4cBAQN/IwBBEGsiAiQAAkAgACgCAEUgACgCBEVzDQAgAiAAKAIINgIIIAIgACkCADcDAAJ/IAIoAgAiAQRAIAIoAghBqOMJIAERBQAMAQtBqOMJECgLIgFFDQAgASAAKQIANwL04QEgAUH84QFqIAAoAgg2AgAgARBZIAEhAwsgAkEQaiQAIAMLywEBAn8jAEEgayIBJAAgAEGBgIDAADYCtOIBIABBADYCiOIBIABBADYC7OEBIABCADcDkOIBIABBADYCpOMJIABBADYC3OIBIABCADcCzOIBIABBADYCvOIBIABBADYCxOABIABCADcCnOIBIABBpOIBakIANwIAIABBrOIBakEANgIAIAFCADcCECABQgA3AhggASABKQMYNwMIIAEgASkDEDcDACABKAIIQQh2QQFxIQIgAEEANgLg4gEgACACNgKM4gEgAUEgaiQAC3YBA38jAEEwayIBJAAgAARAIAEgAEHE0AFqIgIoAgA2AiggASAAKQK80AE3AyAgACgCACEDIAEgAigCADYCGCABIAApArzQATcDECADIAFBEGoQGyABIAEoAig2AgggASABKQMgNwMAIAAgARAbCyABQTBqJAALzAEBAX8gACABKAK00AE2ApjiASAAIAEoAgQiAjYCwOABIAAgAjYCvOABIAAgAiABKAIIaiICNgK44AEgACACNgLE4AEgASgCuNABBEAgAEKBgICAEDcDiOEBIAAgAUGk0ABqNgIMIAAgAUGUIGo2AgggACABQZwwajYCBCAAIAFBDGo2AgAgAEGs0AFqIAFBqNABaigCADYCACAAQbDQAWogAUGs0AFqKAIANgIAIABBtNABaiABQbDQAWooAgA2AgAPCyAAQgA3A4jhAQs7ACACRQRAQbp/DwsgBEUEQEFsDwsgAiAEEGAEQCAAIAEgAiADIAQgBRBhDwsgACABIAIgAyAEIAUQZQtGAQF/IwBBEGsiBSQAIAVBCGogBBAOAn8gBS0ACQRAIAAgASACIAMgBBAyDAELIAAgASACIAMgBBA0CyEAIAVBEGokACAACzQAIAAgAyAEIAUQNiIFEAMEQCAFDwsgBSAESQR/IAEgAiADIAVqIAQgBWsgABA1BUG4fwsLRgEBfyMAQRBrIgUkACAFQQhqIAQQDgJ/IAUtAAkEQCAAIAEgAiADIAQQYgwBCyAAIAEgAiADIAQQNQshACAFQRBqJAAgAAtZAQF/QQ8hAiABIABJBEAgAUEE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",KT="display-p3",$T="display-p3-linear";({...tt.spaces[mt]});const iu=new WeakMap;let su=0,ru;class Un extends Ei{constructor(e){super(e),this.transcoderPath="",this.transcoderBinary=null,this.transcoderPending=null,this.workerPool=new QT,this.workerSourceURL="",this.workerConfig=null,typeof MSC_TRANSCODER<"u"&&console.warn('THREE.KTX2Loader: Please update to latest "basis_transcoder". "msc_basis_transcoder" is no longer supported in three.js r125+.')}setTranscoderPath(e){return this.transcoderPath=e,this}setWorkerLimit(e){return this.workerPool.setWorkerLimit(e),this}async detectSupportAsync(e){return console.warn('KTX2Loader: "detectSupportAsync()" has been deprecated. Use "detectSupport()" and "await renderer.init();" when creating the renderer.'),await e.init(),this.detectSupport(e)}detectSupport(e){return e.isWebGPURenderer===!0?this.workerConfig={astcSupported:e.hasFeature("texture-compression-astc"),astcHDRSupported:!1,etc1Supported:e.hasFeature("texture-compression-etc1"),etc2Supported:e.hasFeature("texture-compression-etc2"),dxtSupported:e.hasFeature("texture-compression-s3tc"),bptcSupported:e.hasFeature("texture-compression-bc"),pvrtcSupported:e.hasFeature("texture-compression-pvrtc")}:(this.workerConfig={astcSupported:e.extensions.has("WEBGL_compressed_texture_astc"),astcHDRSupported:e.extensions.has("WEBGL_compressed_texture_astc")&&e.extensions.get("WEBGL_compressed_texture_astc").getSupportedProfiles().includes("hdr"),etc1Supported:e.extensions.has("WEBGL_compressed_texture_etc1"),etc2Supported:e.extensions.has("WEBGL_compressed_texture_etc"),dxtSupported:e.extensions.has("WEBGL_compressed_texture_s3tc"),bptcSupported:e.extensions.has("EXT_texture_compression_bptc"),pvrtcSupported:e.extensions.has("WEBGL_compressed_texture_pvrtc")||e.extensions.has("WEBKIT_WEBGL_compressed_texture_pvrtc")},typeof navigator<"u"&&typeof navigator.platform<"u"&&typeof navigator.userAgent<"u"&&navigator.platform.indexOf("Linux")>=0&&navigator.userAgent.indexOf("Firefox")>=0&&this.workerConfig.astcSupported&&this.workerConfig.etc2Supported&&this.workerConfig.bptcSupported&&this.workerConfig.dxtSupported&&(this.workerConfig.astcSupported=!1,this.workerConfig.etc2Supported=!1)),this}init(){if(!this.transcoderPending){const e=new Vi(this.manager);e.setPath(this.transcoderPath),e.setWithCredentials(this.withCredentials);const t=e.loadAsync("basis_transcoder.js"),n=new Vi(this.manager);n.setPath(this.transcoderPath),n.setResponseType("arraybuffer"),n.setWithCredentials(this.withCredentials);const i=n.loadAsync("basis_transcoder.wasm");this.transcoderPending=Promise.all([t,i]).then(([s,a])=>{const o=Un.BasisWorker.toString(),c=["/* constants */","let _EngineFormat = "+JSON.stringify(Un.EngineFormat),"let _EngineType = "+JSON.stringify(Un.EngineType),"let _TranscoderFormat = "+JSON.stringify(Un.TranscoderFormat),"let _BasisFormat = "+JSON.stringify(Un.BasisFormat),"/* basis_transcoder.js */",s,"/* worker */",o.substring(o.indexOf("{")+1,o.lastIndexOf("}"))].join(` +`);this.workerSourceURL=URL.createObjectURL(new Blob([c])),this.transcoderBinary=a,this.workerPool.setWorkerCreator(()=>{const l=new Worker(this.workerSourceURL),h=this.transcoderBinary.slice(0);return l.postMessage({type:"init",config:this.workerConfig,transcoderBinary:h},[h]),l})}),su>0&&console.warn("THREE.KTX2Loader: Multiple active KTX2 loaders may cause performance issues. Use a single KTX2Loader instance, or call .dispose() on old instances."),su++}return this.transcoderPending}load(e,t,n,i){if(this.workerConfig===null)throw new Error("THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.");const s=new Vi(this.manager);s.setPath(this.path),s.setCrossOrigin(this.crossOrigin),s.setWithCredentials(this.withCredentials),s.setRequestHeader(this.requestHeader),s.setResponseType("arraybuffer"),s.load(e,a=>{this.parse(a,t,i)},n,i)}parse(e,t,n){if(this.workerConfig===null)throw new Error("THREE.KTX2Loader: Missing initialization with `.detectSupport( renderer )`.");if(iu.has(e))return iu.get(e).promise.then(t).catch(n);this._createTexture(e).then(i=>t?t(i):null).catch(n)}_createTextureFrom(e,t){const{type:n,error:i,data:{faces:s,width:a,height:o,format:c,type:l,dfdFlags:h}}=e;if(n==="error")return Promise.reject(i);let u;if(t.faceCount===6)u=new Tv(s,c,l);else{const d=s[0].mipmaps;u=t.layerCount>1?new wv(d,a,o,t.layerCount,c,l):new Js(d,a,o,c,l)}return u.minFilter=s[0].mipmaps.length===1?qe:vn,u.magFilter=qe,u.generateMipmaps=!1,u.needsUpdate=!0,u.colorSpace=wx(t),u.premultiplyAlpha=!!(h&HT),u}async _createTexture(e,t={}){const n=jT(new Uint8Array(e)),i=n.vkFormat===$f&&n.dataFormatDescriptor[0].colorModel===167;if(!(n.vkFormat===qT||i&&!this.workerConfig.astcHDRSupported))return JT(n);const a=t,o=this.init().then(()=>this.workerPool.postMessage({type:"transcode",buffer:e,taskConfig:a},[e])).then(c=>this._createTextureFrom(c.data,n));return iu.set(e,{promise:o}),o}dispose(){this.workerPool.dispose(),this.workerSourceURL&&URL.revokeObjectURL(this.workerSourceURL),su--}}Un.BasisFormat={ETC1S:0,UASTC:1,UASTC_HDR:2};Un.TranscoderFormat={ETC1:0,ETC2:1,BC1:2,BC3:3,BC4:4,BC5:5,BC7_M6_OPAQUE_ONLY:6,BC7_M5:7,PVRTC1_4_RGB:8,PVRTC1_4_RGBA:9,ASTC_4x4:10,ATC_RGB:11,ATC_RGBA_INTERPOLATED_ALPHA:12,RGBA32:13,RGB565:14,BGR565:15,RGBA4444:16,BC6H:22,RGB_HALF:24,RGBA_HALF:25};Un.EngineFormat={RGBAFormat:Tt,RGBA_ASTC_4x4_Format:Ys,RGB_BPTC_UNSIGNED_Format:yl,RGBA_BPTC_Format:ra,RGBA_ETC2_EAC_Format:To,RGBA_PVRTC_4BPPV1_Format:sa,RGBA_S3TC_DXT5_Format:$s,RGB_ETC1_Format:bl,RGB_ETC2_Format:wo,RGB_PVRTC_4BPPV1_Format:ml,RGBA_S3TC_DXT1_Format:Ks};Un.EngineType={UnsignedByteType:Le,HalfFloatType:yt,FloatType:Nt};Un.BasisWorker=function(){let r,e,t;const n=_EngineFormat,i=_EngineType,s=_TranscoderFormat,a=_BasisFormat;self.addEventListener("message",function(p){const m=p.data;switch(m.type){case"init":r=m.config,o(m.transcoderBinary);break;case"transcode":e.then(()=>{try{const{faces:A,buffers:g,width:b,height:x,hasAlpha:_,format:v,type:S,dfdFlags:I}=c(m.buffer);self.postMessage({type:"transcode",id:m.id,data:{faces:A,width:b,height:x,hasAlpha:_,format:v,type:S,dfdFlags:I}},g)}catch(A){console.error(A),self.postMessage({type:"error",id:m.id,error:A.message})}});break}});function o(p){e=new Promise(m=>{t={wasmBinary:p,onRuntimeInitialized:m},BASIS(t)}).then(()=>{t.initializeBasis(),t.KTX2File===void 0&&console.warn("THREE.KTX2Loader: Please update Basis Universal transcoder.")})}function c(p){const m=new t.KTX2File(new Uint8Array(p));function A(){m.close(),m.delete()}if(!m.isValid())throw A(),new Error("THREE.KTX2Loader: Invalid or unsupported .ktx2 file");let g;if(m.isUASTC())g=a.UASTC;else if(m.isETC1S())g=a.ETC1S;else if(m.isHDR())g=a.UASTC_HDR;else throw new Error("THREE.KTX2Loader: Unknown Basis encoding");const b=m.getWidth(),x=m.getHeight(),_=m.getLayers()||1,v=m.getLevels(),S=m.getFaces(),I=m.getHasAlpha(),E=m.getDFDFlags(),{transcoderFormat:C,engineFormat:D,engineType:w}=u(g,b,x,I);if(!b||!x||!v)throw A(),new Error("THREE.KTX2Loader: Invalid texture");if(!m.startTranscoding())throw A(),new Error("THREE.KTX2Loader: .startTranscoding failed");const L=[],U=[];for(let P=0;P1?($=Y.origWidth,q=Y.origHeight):($=Y.width,q=Y.height);let fe=new Uint8Array(m.getImageTranscodedSizeInBytes(F,Z,0,C));const Ge=m.transcodeImage(fe,F,Z,P,C,0,-1,-1);if(w===i.HalfFloatType&&(fe=new Uint16Array(fe.buffer,fe.byteOffset,fe.byteLength/Uint16Array.BYTES_PER_ELEMENT)),!Ge)throw A(),new Error("THREE.KTX2Loader: .transcodeImage failed.");k.push(fe)}const te=f(k);N.push({data:te,width:$,height:q}),U.push(te.buffer)}L.push({mipmaps:N,width:b,height:x,format:D,type:w})}return A(),{faces:L,buffers:U,width:b,height:x,hasAlpha:I,dfdFlags:E,format:D,type:w}}const l=[{if:"astcSupported",basisFormat:[a.UASTC],transcoderFormat:[s.ASTC_4x4,s.ASTC_4x4],engineFormat:[n.RGBA_ASTC_4x4_Format,n.RGBA_ASTC_4x4_Format],engineType:[i.UnsignedByteType],priorityETC1S:1/0,priorityUASTC:1,needsPowerOfTwo:!1},{if:"bptcSupported",basisFormat:[a.ETC1S,a.UASTC],transcoderFormat:[s.BC7_M5,s.BC7_M5],engineFormat:[n.RGBA_BPTC_Format,n.RGBA_BPTC_Format],engineType:[i.UnsignedByteType],priorityETC1S:3,priorityUASTC:2,needsPowerOfTwo:!1},{if:"dxtSupported",basisFormat:[a.ETC1S,a.UASTC],transcoderFormat:[s.BC1,s.BC3],engineFormat:[n.RGBA_S3TC_DXT1_Format,n.RGBA_S3TC_DXT5_Format],engineType:[i.UnsignedByteType],priorityETC1S:4,priorityUASTC:5,needsPowerOfTwo:!1},{if:"etc2Supported",basisFormat:[a.ETC1S,a.UASTC],transcoderFormat:[s.ETC1,s.ETC2],engineFormat:[n.RGB_ETC2_Format,n.RGBA_ETC2_EAC_Format],engineType:[i.UnsignedByteType],priorityETC1S:1,priorityUASTC:3,needsPowerOfTwo:!1},{if:"etc1Supported",basisFormat:[a.ETC1S,a.UASTC],transcoderFormat:[s.ETC1],engineFormat:[n.RGB_ETC1_Format],engineType:[i.UnsignedByteType],priorityETC1S:2,priorityUASTC:4,needsPowerOfTwo:!1},{if:"pvrtcSupported",basisFormat:[a.ETC1S,a.UASTC],transcoderFormat:[s.PVRTC1_4_RGB,s.PVRTC1_4_RGBA],engineFormat:[n.RGB_PVRTC_4BPPV1_Format,n.RGBA_PVRTC_4BPPV1_Format],engineType:[i.UnsignedByteType],priorityETC1S:5,priorityUASTC:6,needsPowerOfTwo:!0},{if:"bptcSupported",basisFormat:[a.UASTC_HDR],transcoderFormat:[s.BC6H],engineFormat:[n.RGB_BPTC_UNSIGNED_Format],engineType:[i.HalfFloatType],priorityHDR:1,needsPowerOfTwo:!1},{basisFormat:[a.ETC1S,a.UASTC],transcoderFormat:[s.RGBA32,s.RGBA32],engineFormat:[n.RGBAFormat,n.RGBAFormat],engineType:[i.UnsignedByteType,i.UnsignedByteType],priorityETC1S:100,priorityUASTC:100,needsPowerOfTwo:!1},{basisFormat:[a.UASTC_HDR],transcoderFormat:[s.RGBA_HALF],engineFormat:[n.RGBAFormat],engineType:[i.HalfFloatType],priorityHDR:100,needsPowerOfTwo:!1}],h={[a.ETC1S]:l.filter(p=>p.basisFormat.includes(a.ETC1S)).sort((p,m)=>p.priorityETC1S-m.priorityETC1S),[a.UASTC]:l.filter(p=>p.basisFormat.includes(a.UASTC)).sort((p,m)=>p.priorityUASTC-m.priorityUASTC),[a.UASTC_HDR]:l.filter(p=>p.basisFormat.includes(a.UASTC_HDR)).sort((p,m)=>p.priorityHDR-m.priorityHDR)};function u(p,m,A,g){const b=h[p];for(let x=0;x{const o=new XT;await o.init(),a(o)})),t=await ru);const n=[];for(let a=0;a>a),c=Math.max(1,r.pixelHeight>>a),l=r.pixelDepth?Math.max(1,r.pixelDepth>>a):0,h=r.levels[a];let u;if(r.supercompressionScheme===GT)u=h.levelData;else if(r.supercompressionScheme===ng)u=t.decode(h.levelData,h.uncompressedByteLength);else throw new Error("THREE.KTX2Loader: Unsupported supercompressionScheme.");let d;Sr[e]===Nt?d=new Float32Array(u.buffer,u.byteOffset,u.byteLength/Float32Array.BYTES_PER_ELEMENT):Sr[e]===yt?d=new Uint16Array(u.buffer,u.byteOffset,u.byteLength/Uint16Array.BYTES_PER_ELEMENT):Sr[e]===Yl||Sr[e]===Jl?d=new Uint32Array(u.buffer,u.byteOffset,u.byteLength/Uint32Array.BYTES_PER_ELEMENT):d=u,n.push({data:d,width:o,height:c,depth:l})}const i=r.levelCount===0||n.length>1;let s;if(YT.has(au[e]))s=r.pixelDepth===0?new ma(n[0].data,r.pixelWidth,r.pixelHeight):new J0(n[0].data,r.pixelWidth,r.pixelHeight,r.pixelDepth),s.minFilter=i?ga:St,s.magFilter=St,s.generateMipmaps=r.levelCount===0;else{if(r.pixelDepth>0)throw new Error("THREE.KTX2Loader: Unsupported pixelDepth.");s=new Js(n,r.pixelWidth,r.pixelHeight),s.minFilter=i?vn:qe,s.magFilter=qe}return s.mipmaps=n,s.type=Sr[e],s.format=au[e],s.colorSpace=wx(r),s.needsUpdate=!0,Promise.resolve(s)}function wx(r){const e=r.dataFormatDescriptor[0];return e.colorPrimaries===VT?e.transferFunction===ig?mt:Ct:e.colorPrimaries===WT?e.transferFunction===ig?KT:$T:(e.colorPrimaries===zT||console.warn(`THREE.KTX2Loader: Unsupported color primaries, "${e.colorPrimaries}"`),Nn)}var ag,og;const Xn=Symbol("retainerCount"),Ti=Symbol("recentlyUsed"),Mc=Symbol("evict"),Fa=Symbol("evictionThreshold"),ou=Symbol("cache");class ZT{constructor(e,t=5){this[ag]=new Map,this[og]=[],this[ou]=e,this[Fa]=t}set evictionThreshold(e){this[Fa]=e,this[Mc]()}get evictionThreshold(){return this[Fa]}get cache(){return this[ou]}retainerCount(e){return this[Xn].get(e)||0}reset(){this[Xn].clear(),this[Ti]=[]}retain(e){this[Xn].has(e)||this[Xn].set(e,0),this[Xn].set(e,this[Xn].get(e)+1);const t=this[Ti].indexOf(e);t!==-1&&this[Ti].splice(t,1),this[Ti].unshift(e),this[Mc]()}release(e){this[Xn].has(e)&&this[Xn].set(e,Math.max(this[Xn].get(e)-1,0)),this[Mc]()}[(ag=Xn,og=Ti,Mc)](){if(!(this[Ti].length=this[Fa];--e){const t=this[Ti][e];this[Xn].get(t)===0&&(this[ou].delete(t),this[Ti].splice(e,1))}}}const e1=r=>{const e=[],t=new Set;for(const n of r){let i=n,s=0;for(;t.has(i);)i=n+"."+ ++s;t.add(i),e.push(i)}return e},t1=r=>{const e=new Map;for(const t of r.mappings)for(const n of t.variants)e.set(n,{material:null,gltfMaterialIndex:t.material});return e};class n1{constructor(e){this.parser=e,this.name="KHR_materials_variants"}afterRoot(e){const t=this.parser,n=t.json;if(n.extensions===void 0||n.extensions[this.name]===void 0)return null;const s=n.extensions[this.name].variants||[],a=e1(s.map(o=>o.name));for(const o of e.scenes)o.traverse(c=>{const l=c;if(!l.material)return;const h=t.associations.get(l);if(h==null||h.meshes==null||h.primitives==null)return;const p=n.meshes[h.meshes].primitives[h.primitives].extensions;!p||!p[this.name]||(l.userData.variantMaterials=t1(p[this.name]))});return e.userData.variants=a,Promise.resolve()}}var Tx,cg;Rt.DEFAULT_ANISOTROPY=4;const i1=(r,e,t=()=>{})=>{const n=i=>{const s=i.loaded/i.total;t(Math.max(0,Math.min(1,isFinite(s)?s:1)))};return new Promise((i,s)=>{e.load(r,i,n,s)})},s1=r=>new Promise((e,t)=>{const n=document.createElement("script");document.body.appendChild(n),n.onload=e,n.onerror=t,n.async=!0,n.src=r}),Ri=new Map,cu=new Map;let lg;const hg=new sT;let ug;const xo=new Un;let lu,hu;const Os=Symbol("loader"),rs=Symbol("evictionPolicy"),dg=Symbol("GLTFInstance");class _n extends ii{static setDRACODecoderLocation(e){lg=e,hg.setDecoderPath(e)}static getDRACODecoderLocation(){return lg}static setKTX2TranscoderLocation(e){ug=e,xo.setTranscoderPath(e)}static getKTX2TranscoderLocation(){return ug}static setMeshoptDecoderLocation(e){lu!==e&&(lu=e,hu=s1(e).then(()=>KA.ready).then(()=>KA))}static getMeshoptDecoderLocation(){return lu}static initializeKTX2Loader(e){xo.detectSupport(e)}static get cache(){return Ri}static clearCache(){Ri.forEach((e,t)=>{this.delete(t)}),this[rs].reset()}static has(e){return Ri.has(e)}static async delete(e){if(!this.has(e))return;const t=Ri.get(e);cu.delete(e),Ri.delete(e),(await t).dispose()}static hasFinishedLoading(e){return!!cu.get(e)}constructor(e){super(),this[cg]=new aT().register(t=>new n1(t)),this[dg]=e,this[Os].setDRACOLoader(hg),this[Os].setKTX2Loader(xo)}get[(Tx=rs,cg=Os,rs)](){return this.constructor[rs]}async preload(e,t,n=()=>{}){if(this[Os].setWithCredentials(t.withCredentials),this.dispatchEvent({type:"preload",element:t,src:e}),!Ri.has(e)){hu!=null&&this[Os].setMeshoptDecoder(await hu);const i=i1(e,this[Os],o=>{n(o*.8)}),s=this[dg],a=i.then(o=>s.prepare(o)).then(o=>(n(.9),new s(o))).catch((o=>(console.error(o),new s)));Ri.set(e,a)}await Ri.get(e),cu.set(e,!0),n&&n(1)}async load(e,t,n=()=>{}){await this.preload(e,t,n);const s=await(await Ri.get(e)).clone();return this[rs].retain(e),s.dispose=()=>{this[rs].release(e)},s}}_n[Tx]=new ZT(_n);class r1 extends ht{constructor(e=document.createElement("div")){super(),this.isCSS2DObject=!0,this.element=e,this.element.style.position="absolute",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.center=new pe(.5,.5),this.addEventListener("removed",function(){this.traverse(function(t){t.element&&t.element instanceof t.element.ownerDocument.defaultView.Element&&t.element.parentNode!==null&&t.element.remove()})})}copy(e,t){return super.copy(e,t),this.element=e.element.cloneNode(!0),this.center=e.center,this}}const Cr=new R,fg=new Oe,pg=new Oe,Ag=new R,gg=new R;class a1{constructor(e={}){const t=this;let n,i,s,a;const o={objects:new WeakMap},c=e.element!==void 0?e.element:document.createElement("div");c.style.overflow="hidden",this.domElement=c,this.sortObjects=!0,this.getSize=function(){return{width:n,height:i}},this.render=function(p,m){p.matrixWorldAutoUpdate===!0&&p.updateMatrixWorld(),m.parent===null&&m.matrixWorldAutoUpdate===!0&&m.updateMatrixWorld(),fg.copy(m.matrixWorldInverse),pg.multiplyMatrices(m.projectionMatrix,fg),h(p,p,m),this.sortObjects&&f(p)},this.setSize=function(p,m){n=p,i=m,s=n/2,a=i/2,c.style.width=p+"px",c.style.height=m+"px"};function l(p){p.isCSS2DObject&&(p.element.style.display="none");for(let m=0,A=p.children.length;m=-1&&Cr.z<=1&&p.layers.test(A.layers)===!0,b=p.element;b.style.display=g===!0?"":"none",g===!0&&(p.onBeforeRender(t,m,A),b.style.transform="translate("+-100*p.center.x+"%,"+-100*p.center.y+"%)translate("+(Cr.x*s+s)+"px,"+(-Cr.y*a+a)+"px)",b.parentNode!==c&&c.appendChild(b),p.onAfterRender(t,m,A));const x={distanceToCameraSquared:u(A,p)};o.objects.set(p,x)}for(let g=0,b=p.children.length;g{const{geometry:a}=s;if(a!==void 0){const{position:o}=a.attributes;if(o!==void 0)for(let c=0,l=o.count;c4?a=r.array[i*r.itemSize+s]:(s===0?a=r.getX(i):s===1?a=r.getY(i):s===2?a=r.getZ(i):s===3&&(a=r.getW(i)),r.normalized===!0&&(a=Ll.normalize(a,r.array))),n.min[s]=Math.min(n.min[s],a),n.max[s]=Math.max(n.max[s],a)}return n}function Rx(r){return Math.ceil(r/4)*4}function du(r,e=0){const t=Rx(r.byteLength);if(t!==r.byteLength){const n=new Uint8Array(t);if(n.set(new Uint8Array(r)),e!==0)for(let i=r.byteLength;i"u"&&typeof OffscreenCanvas<"u"?new OffscreenCanvas(1,1):document.createElement("canvas")}function A1(r,e){if(typeof OffscreenCanvas<"u"&&r instanceof OffscreenCanvas){let t;return e==="image/jpeg"?t=.92:e==="image/webp"&&(t=.8),r.convertToBlob({type:e,quality:t})}else return new Promise(t=>r.toBlob(t,e))}class g1{constructor(){this.plugins=[],this.options={},this.pending=[],this.buffers=[],this.byteOffset=0,this.buffers=[],this.nodeMap=new Map,this.skins=[],this.extensionsUsed={},this.extensionsRequired={},this.uids=new Map,this.uid=0,this.json={asset:{version:"2.0",generator:"THREE.GLTFExporter r"+Xl}},this.cache={meshes:new Map,attributes:new Map,attributesNormalized:new Map,materials:new Map,textures:new Map,images:new Map},this.textureUtils=null}setPlugins(e){this.plugins=e}setTextureUtils(e){this.textureUtils=e}async writeAsync(e,t,n={}){this.options=Object.assign({binary:!1,trs:!1,onlyVisible:!0,maxTextureSize:1/0,animations:[],includeCustomExtensions:!1},n),this.options.animations.length>0&&(this.options.trs=!0),await this.processInputAsync(e),await Promise.all(this.pending);const i=this,s=i.buffers,a=i.json;n=i.options;const o=i.extensionsUsed,c=i.extensionsRequired,l=new Blob(s,{type:"application/octet-stream"}),h=Object.keys(o),u=Object.keys(c);if(h.length>0&&(a.extensionsUsed=h),u.length>0&&(a.extensionsRequired=u),a.buffers&&a.buffers.length>0&&(a.buffers[0].byteLength=l.size),n.binary===!0){const d=new FileReader;d.readAsArrayBuffer(l),d.onloadend=function(){const f=du(d.result),p=new DataView(new ArrayBuffer(Eg));p.setUint32(0,f.byteLength,!0),p.setUint32(4,u1,!0);const m=du(d1(JSON.stringify(a)),32),A=new DataView(new ArrayBuffer(Eg));A.setUint32(0,m.byteLength,!0),A.setUint32(4,h1,!0);const g=new ArrayBuffer(xg),b=new DataView(g);b.setUint32(0,c1,!0),b.setUint32(4,l1,!0);const x=xg+A.byteLength+m.byteLength+p.byteLength+f.byteLength;b.setUint32(8,x,!0);const _=new Blob([g,A,m,p,f],{type:"application/octet-stream"}),v=new FileReader;v.readAsArrayBuffer(_),v.onloadend=function(){t(v.result)}}}else if(a.buffers&&a.buffers.length>0){const d=new FileReader;d.readAsDataURL(l),d.onloadend=function(){const f=d.result;a.buffers[0].uri=f,t(a)}}else t(a)}serializeUserData(e,t){if(Object.keys(e.userData).length===0)return;const n=this.options,i=this.extensionsUsed;try{const s=JSON.parse(JSON.stringify(e.userData));if(n.includeCustomExtensions&&s.gltfExtensions){t.extensions===void 0&&(t.extensions={});for(const a in s.gltfExtensions)t.extensions[a]=s.gltfExtensions[a],i[a]=!0;delete s.gltfExtensions}Object.keys(s).length>0&&(t.extras=s)}catch(s){console.warn("THREE.GLTFExporter: userData of '"+e.name+"' won't be serialized because of JSON.stringify error - "+s.message)}}getUID(e,t=!1){if(this.uids.has(e)===!1){const i=new Map;i.set(!0,this.uid++),i.set(!1,this.uid++),this.uids.set(e,i)}return this.uids.get(e).get(t)}isNormalizedNormalAttribute(e){if(this.cache.attributesNormalized.has(e))return!1;const n=new R;for(let i=0,s=e.count;i5e-4)return!1;return!0}createNormalizedNormalAttribute(e){const t=this.cache;if(t.attributesNormalized.has(e))return t.attributesNormalized.get(e);const n=e.clone(),i=new R;for(let s=0,a=n.count;s4?A=e.array[p*e.itemSize+m]:(m===0?A=e.getX(p):m===1?A=e.getY(p):m===2?A=e.getZ(p):m===3&&(A=e.getW(p)),e.normalized===!0&&(A=Ll.normalize(A,e.array))),t===et.FLOAT?h.setFloat32(u,A,!0):t===et.INT?h.setInt32(u,A,!0):t===et.UNSIGNED_INT?h.setUint32(u,A,!0):t===et.SHORT?h.setInt16(u,A,!0):t===et.UNSIGNED_SHORT?h.setUint16(u,A,!0):t===et.BYTE?h.setInt8(u,A):t===et.UNSIGNED_BYTE&&h.setUint8(u,A),u+=o}u%c!==0&&(u+=c-u%c)}const d={buffer:this.processBuffer(h.buffer),byteOffset:this.byteOffset,byteLength:l};return s!==void 0&&(d.target=s),s===et.ARRAY_BUFFER&&(d.byteStride=c),this.byteOffset+=l,a.bufferViews.push(d),{id:a.bufferViews.length-1,byteLength:0}}processBufferViewImage(e){const t=this,n=t.json;return n.bufferViews||(n.bufferViews=[]),new Promise(function(i){const s=new FileReader;s.readAsArrayBuffer(e),s.onloadend=function(){const a=du(s.result),o={buffer:t.processBuffer(a),byteOffset:t.byteOffset,byteLength:a.byteLength};t.byteOffset+=a.byteLength,i(n.bufferViews.push(o)-1)}})}processAccessor(e,t,n,i){const s=this.json,a={1:"SCALAR",2:"VEC2",3:"VEC3",4:"VEC4",9:"MAT3",16:"MAT4"};let o;if(e.array.constructor===Float32Array)o=et.FLOAT;else if(e.array.constructor===Int32Array)o=et.INT;else if(e.array.constructor===Uint32Array)o=et.UNSIGNED_INT;else if(e.array.constructor===Int16Array)o=et.SHORT;else if(e.array.constructor===Uint16Array)o=et.UNSIGNED_SHORT;else if(e.array.constructor===Int8Array)o=et.BYTE;else if(e.array.constructor===Uint8Array)o=et.UNSIGNED_BYTE;else throw new Error("THREE.GLTFExporter: Unsupported bufferAttribute component type: "+e.array.constructor.name);if(n===void 0&&(n=0),(i===void 0||i===1/0)&&(i=e.count),i===0)return null;const c=p1(e,n,i);let l;t!==void 0&&(l=e===t.index?et.ELEMENT_ARRAY_BUFFER:et.ARRAY_BUFFER);const h=this.processBufferView(e,o,n,i,l),u={bufferView:h.id,byteOffset:h.byteOffset,componentType:o,count:i,max:c.max,min:c.min,type:a[e.itemSize]};return e.normalized===!0&&(u.normalized=!0),s.accessors||(s.accessors=[]),s.accessors.push(u)-1}processImage(e,t,n,i="image/png"){if(e!==null){const s=this,a=s.cache,o=s.json,c=s.options,l=s.pending;a.images.has(e)||a.images.set(e,{});const h=a.images.get(e),u=i+":flipY/"+n.toString();if(h[u]!==void 0)return h[u];o.images||(o.images=[]);const d={mimeType:i},f=_g();f.width=Math.min(e.width,c.maxTextureSize),f.height=Math.min(e.height,c.maxTextureSize);const p=f.getContext("2d",{willReadFrequently:!0});if(n===!0&&(p.translate(0,f.height),p.scale(1,-1)),e.data!==void 0){t!==Tt&&console.error("GLTFExporter: Only RGBAFormat is supported.",t),(e.width>c.maxTextureSize||e.height>c.maxTextureSize)&&console.warn("GLTFExporter: Image size is bigger than maxTextureSize",e);const A=new Uint8ClampedArray(e.height*e.width*4);for(let g=0;gs.processBufferViewImage(A)).then(A=>{d.bufferView=A})):d.uri=$0.getDataURL(f,i);const m=o.images.push(d)-1;return h[u]=m,m}else throw new Error("THREE.GLTFExporter: No valid image data found. Unable to process texture.")}processSampler(e){const t=this.json;t.samplers||(t.samplers=[]);const n={magFilter:Rn[e.magFilter],minFilter:Rn[e.minFilter],wrapS:Rn[e.wrapS],wrapT:Rn[e.wrapT]};return t.samplers.push(n)-1}async processTextureAsync(e){const n=this.options,i=this.cache,s=this.json;if(i.textures.has(e))return i.textures.get(e);s.textures||(s.textures=[]),e instanceof Js&&(e=await this.decompressTextureAsync(e,n.maxTextureSize));let a=e.userData.mimeType;a==="image/webp"&&(a="image/png");const o={sampler:this.processSampler(e),source:this.processImage(e.image,e.format,e.flipY,a)};e.name&&(o.name=e.name),await this._invokeAllAsync(async function(l){l.writeTexture&&await l.writeTexture(e,o)});const c=s.textures.push(o)-1;return i.textures.set(e,c),c}async processMaterialAsync(e){const t=this.cache,n=this.json;if(t.materials.has(e))return t.materials.get(e);if(e.isShaderMaterial)return console.warn("GLTFExporter: THREE.ShaderMaterial not supported."),null;n.materials||(n.materials=[]);const i={pbrMetallicRoughness:{}};e.isMeshStandardMaterial!==!0&&e.isMeshBasicMaterial!==!0&&console.warn("GLTFExporter: Use MeshStandardMaterial or MeshBasicMaterial for best results.");const s=e.color.toArray().concat([e.opacity]);if(Ui(s,[1,1,1,1])||(i.pbrMetallicRoughness.baseColorFactor=s),e.isMeshStandardMaterial?(i.pbrMetallicRoughness.metallicFactor=e.metalness,i.pbrMetallicRoughness.roughnessFactor=e.roughness):(i.pbrMetallicRoughness.metallicFactor=0,i.pbrMetallicRoughness.roughnessFactor=1),e.metalnessMap||e.roughnessMap){const o=await this.buildMetalRoughTextureAsync(e.metalnessMap,e.roughnessMap),c={index:await this.processTextureAsync(o),texCoord:o.channel};this.applyTextureTransform(c,o),i.pbrMetallicRoughness.metallicRoughnessTexture=c}if(e.map){const o={index:await this.processTextureAsync(e.map),texCoord:e.map.channel};this.applyTextureTransform(o,e.map),i.pbrMetallicRoughness.baseColorTexture=o}if(e.emissive){const o=e.emissive;if(Math.max(o.r,o.g,o.b)>0&&(i.emissiveFactor=e.emissive.toArray()),e.emissiveMap){const l={index:await this.processTextureAsync(e.emissiveMap),texCoord:e.emissiveMap.channel};this.applyTextureTransform(l,e.emissiveMap),i.emissiveTexture=l}}if(e.normalMap){const o={index:await this.processTextureAsync(e.normalMap),texCoord:e.normalMap.channel};e.normalScale&&e.normalScale.x!==1&&(o.scale=e.normalScale.x),this.applyTextureTransform(o,e.normalMap),i.normalTexture=o}if(e.aoMap){const o={index:await this.processTextureAsync(e.aoMap),texCoord:e.aoMap.channel};e.aoMapIntensity!==1&&(o.strength=e.aoMapIntensity),this.applyTextureTransform(o,e.aoMap),i.occlusionTexture=o}e.transparent?i.alphaMode="BLEND":e.alphaTest>0&&(i.alphaMode="MASK",i.alphaCutoff=e.alphaTest),e.side===Wt&&(i.doubleSided=!0),e.name!==""&&(i.name=e.name),this.serializeUserData(e,i),await this._invokeAllAsync(async function(o){o.writeMaterialAsync&&await o.writeMaterialAsync(e,i)});const a=n.materials.push(i)-1;return t.materials.set(e,a),a}async processMeshAsync(e){const t=this.cache,n=this.json,i=[e.geometry.uuid];if(Array.isArray(e.material))for(let _=0,v=e.material.length;_0){const _=[],v=[],S={};if(e.morphTargetDictionary!==void 0)for(const I in e.morphTargetDictionary)S[e.morphTargetDictionary[I]]=I;for(let I=0;I0&&(c.extras={},c.extras.targetNames=v)}const m=Array.isArray(e.material);if(m&&a.groups.length===0)return null;let A=!1;if(m&&a.index===null){const _=[];for(let v=0,S=a.attributes.position.count;v0&&(S.targets=u),a.index!==null){let E=this.getUID(a.index);(b[_].start!==void 0||b[_].count!==void 0)&&(E+=":"+b[_].start+":"+b[_].count),t.attributes.has(E)?S.indices=t.attributes.get(E):(S.indices=this.processAccessor(a.index,a,b[_].start,b[_].count),t.attributes.set(E,S.indices)),S.indices===null&&delete S.indices}const I=await this.processMaterialAsync(g[b[_].materialIndex]);I!==null&&(S.material=I),h.push(S)}A===!0&&a.setIndex(null),c.primitives=h,n.meshes||(n.meshes=[]),await this._invokeAllAsync(function(_){_.writeMesh&&_.writeMesh(e,c)});const x=n.meshes.push(c)-1;return t.meshes.set(s,x),x}detectMeshQuantization(e,t){if(this.extensionsUsed[uu])return;let n;switch(t.array.constructor){case Int8Array:n="byte";break;case Uint8Array:n="unsigned byte";break;case Int16Array:n="short";break;case Uint16Array:n="unsigned short";break;default:return}t.normalized&&(n+=" normalized");const i=e.split("_",1)[0];mg[i]&&mg[i].includes(n)&&(this.extensionsUsed[uu]=!0,this.extensionsRequired[uu]=!0)}processCamera(e){const t=this.json;t.cameras||(t.cameras=[]);const n=e.isOrthographicCamera,i={type:n?"orthographic":"perspective"};return n?i.orthographic={xmag:e.right*2,ymag:e.top*2,zfar:e.far<=0?.001:e.far,znear:e.near<0?0:e.near}:i.perspective={aspectRatio:e.aspect,yfov:Ll.degToRad(e.fov),zfar:e.far<=0?.001:e.far,znear:e.near<0?0:e.near},e.name!==""&&(i.name=e.type),t.cameras.push(i)-1}processAnimation(e,t){const n=this.json,i=this.nodeMap;n.animations||(n.animations=[]),e=Eo.Utils.mergeMorphTargetTracks(e.clone(),t);const s=e.tracks,a=[],o=[];for(let l=0;l0){const o=[];for(let c=0,l=e.children.length;c0&&(s.children=o)}return await this._invokeAllAsync(function(o){o.writeNode&&o.writeNode(e,s)}),a}async _processNodeWithPivotAsync(e){const t=this.json,n=this.options,i=this.nodeMap,s=e.pivot,a={},o=e.quaternion.toArray(),c=[e.position.x+s.x,e.position.y+s.y,e.position.z+s.z],l=e.scale.toArray();Ui(o,[0,0,0,1])||(a.rotation=o),Ui(c,[0,0,0])||(a.translation=c),Ui(l,[1,1,1])||(a.scale=l),a.extras={pivot:s.toArray()},e.name!==""&&(a.name=String(e.name)),this.serializeUserData(e,a);const h=t.nodes.push(a)-1;i.set(e,h);const u={},d=[-s.x,-s.y,-s.z];if(Ui(d,[0,0,0])||(u.translation=d),e.isMesh||e.isLine||e.isPoints){const m=await this.processMeshAsync(e);m!==null&&(u.mesh=m)}else e.isCamera&&(u.camera=this.processCamera(e));e.isSkinnedMesh&&this.skins.push(e);const p=[t.nodes.push(u)-1];if(e.children.length>0){const m=[];for(let A=0,g=e.children.length;A0&&(u.children=m)}return a.children=p,await this._invokeAllAsync(function(m){m.writeNode&&m.writeNode(e,a)}),h}async processSceneAsync(e){const t=this.json,n=this.options;t.scenes||(t.scenes=[],t.scene=0);const i={};e.name!==""&&(i.name=e.name),t.scenes.push(i);const s=[];for(let a=0,o=e.children.length;a0&&(i.nodes=s),this.serializeUserData(e,i)}async processObjectsAsync(e){const t=new ms;t.name="AuxScene";for(let n=0;n0&&await this.processObjectsAsync(n);for(let i=0;i0&&(a.range=e.distance)):e.isSpotLight&&(a.type="spot",e.distance>0&&(a.range=e.distance),a.spot={},a.spot.innerConeAngle=(1-e.penumbra)*e.angle,a.spot.outerConeAngle=e.angle),e.decay!==void 0&&e.decay!==2&&console.warn("THREE.GLTFExporter: Light decay may be lost. glTF is physically-based, and expects light.decay=2."),e.target&&(e.target.parent!==e||e.target.position.x!==0||e.target.position.y!==0||e.target.position.z!==-1)&&console.warn("THREE.GLTFExporter: Light direction may be lost. For best results, make light.target a child of the light with position 0,0,-1."),s[this.name]||(i.extensions=i.extensions||{},i.extensions[this.name]={lights:[]},s[this.name]=!0);const o=i.extensions[this.name].lights;o.push(a),t.extensions=t.extensions||{},t.extensions[this.name]={light:o.length-1}}}class b1{constructor(e){this.writer=e,this.name="KHR_materials_unlit"}async writeMaterialAsync(e,t){if(!e.isMeshBasicMaterial)return;const i=this.writer.extensionsUsed;t.extensions=t.extensions||{},t.extensions[this.name]={},i[this.name]=!0,t.pbrMetallicRoughness.metallicFactor=0,t.pbrMetallicRoughness.roughnessFactor=.9}}class x1{constructor(e){this.writer=e,this.name="KHR_materials_clearcoat"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.clearcoat===0)return;const n=this.writer,i=n.extensionsUsed,s={};if(s.clearcoatFactor=e.clearcoat,e.clearcoatMap){const a={index:await n.processTextureAsync(e.clearcoatMap),texCoord:e.clearcoatMap.channel};n.applyTextureTransform(a,e.clearcoatMap),s.clearcoatTexture=a}if(s.clearcoatRoughnessFactor=e.clearcoatRoughness,e.clearcoatRoughnessMap){const a={index:await n.processTextureAsync(e.clearcoatRoughnessMap),texCoord:e.clearcoatRoughnessMap.channel};n.applyTextureTransform(a,e.clearcoatRoughnessMap),s.clearcoatRoughnessTexture=a}if(e.clearcoatNormalMap){const a={index:await n.processTextureAsync(e.clearcoatNormalMap),texCoord:e.clearcoatNormalMap.channel};e.clearcoatNormalScale.x!==1&&(a.scale=e.clearcoatNormalScale.x),n.applyTextureTransform(a,e.clearcoatNormalMap),s.clearcoatNormalTexture=a}t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class E1{constructor(e){this.writer=e,this.name="KHR_materials_dispersion"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.dispersion===0)return;const i=this.writer.extensionsUsed,s={};s.dispersion=e.dispersion,t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class _1{constructor(e){this.writer=e,this.name="KHR_materials_iridescence"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.iridescence===0)return;const n=this.writer,i=n.extensionsUsed,s={};if(s.iridescenceFactor=e.iridescence,e.iridescenceMap){const a={index:await n.processTextureAsync(e.iridescenceMap),texCoord:e.iridescenceMap.channel};n.applyTextureTransform(a,e.iridescenceMap),s.iridescenceTexture=a}if(s.iridescenceIor=e.iridescenceIOR,s.iridescenceThicknessMinimum=e.iridescenceThicknessRange[0],s.iridescenceThicknessMaximum=e.iridescenceThicknessRange[1],e.iridescenceThicknessMap){const a={index:await n.processTextureAsync(e.iridescenceThicknessMap),texCoord:e.iridescenceThicknessMap.channel};n.applyTextureTransform(a,e.iridescenceThicknessMap),s.iridescenceThicknessTexture=a}t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class v1{constructor(e){this.writer=e,this.name="KHR_materials_transmission"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.transmission===0)return;const n=this.writer,i=n.extensionsUsed,s={};if(s.transmissionFactor=e.transmission,e.transmissionMap){const a={index:await n.processTextureAsync(e.transmissionMap),texCoord:e.transmissionMap.channel};n.applyTextureTransform(a,e.transmissionMap),s.transmissionTexture=a}t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class y1{constructor(e){this.writer=e,this.name="KHR_materials_volume"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.transmission===0)return;const n=this.writer,i=n.extensionsUsed,s={};if(s.thicknessFactor=e.thickness,e.thicknessMap){const a={index:await n.processTextureAsync(e.thicknessMap),texCoord:e.thicknessMap.channel};n.applyTextureTransform(a,e.thicknessMap),s.thicknessTexture=a}e.attenuationDistance!==1/0&&(s.attenuationDistance=e.attenuationDistance),s.attenuationColor=e.attenuationColor.toArray(),t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class S1{constructor(e){this.writer=e,this.name="KHR_materials_ior"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.ior===1.5)return;const i=this.writer.extensionsUsed,s={};s.ior=e.ior,t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class C1{constructor(e){this.writer=e,this.name="KHR_materials_specular"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.specularIntensity===1&&e.specularColor.equals(o1)&&!e.specularIntensityMap&&!e.specularColorMap)return;const n=this.writer,i=n.extensionsUsed,s={};if(e.specularIntensityMap){const a={index:await n.processTextureAsync(e.specularIntensityMap),texCoord:e.specularIntensityMap.channel};n.applyTextureTransform(a,e.specularIntensityMap),s.specularTexture=a}if(e.specularColorMap){const a={index:await n.processTextureAsync(e.specularColorMap),texCoord:e.specularColorMap.channel};n.applyTextureTransform(a,e.specularColorMap),s.specularColorTexture=a}s.specularFactor=e.specularIntensity,s.specularColorFactor=e.specularColor.toArray(),t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class M1{constructor(e){this.writer=e,this.name="KHR_materials_sheen"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.sheen==0)return;const n=this.writer,i=n.extensionsUsed,s={};if(e.sheenRoughnessMap){const a={index:await n.processTextureAsync(e.sheenRoughnessMap),texCoord:e.sheenRoughnessMap.channel};n.applyTextureTransform(a,e.sheenRoughnessMap),s.sheenRoughnessTexture=a}if(e.sheenColorMap){const a={index:await n.processTextureAsync(e.sheenColorMap),texCoord:e.sheenColorMap.channel};n.applyTextureTransform(a,e.sheenColorMap),s.sheenColorTexture=a}s.sheenRoughnessFactor=e.sheenRoughness,s.sheenColorFactor=e.sheenColor.toArray(),t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class I1{constructor(e){this.writer=e,this.name="KHR_materials_anisotropy"}async writeMaterialAsync(e,t){if(!e.isMeshPhysicalMaterial||e.anisotropy==0)return;const n=this.writer,i=n.extensionsUsed,s={};if(e.anisotropyMap){const a={index:await n.processTextureAsync(e.anisotropyMap)};n.applyTextureTransform(a,e.anisotropyMap),s.anisotropyTexture=a}s.anisotropyStrength=e.anisotropy,s.anisotropyRotation=e.anisotropyRotation,t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class w1{constructor(e){this.writer=e,this.name="KHR_materials_emissive_strength"}async writeMaterialAsync(e,t){if(!e.isMeshStandardMaterial||e.emissiveIntensity===1)return;const i=this.writer.extensionsUsed,s={};s.emissiveStrength=e.emissiveIntensity,t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class T1{constructor(e){this.writer=e,this.name="EXT_materials_bump"}async writeMaterialAsync(e,t){if(!e.isMeshStandardMaterial||e.bumpScale===1&&!e.bumpMap)return;const n=this.writer,i=n.extensionsUsed,s={};if(e.bumpMap){const a={index:await n.processTextureAsync(e.bumpMap),texCoord:e.bumpMap.channel};n.applyTextureTransform(a,e.bumpMap),s.bumpTexture=a}s.bumpFactor=e.bumpScale,t.extensions=t.extensions||{},t.extensions[this.name]=s,i[this.name]=!0}}class R1{constructor(e){this.writer=e,this.name="EXT_mesh_gpu_instancing"}writeNode(e,t){if(!e.isInstancedMesh)return;const n=this.writer,i=e,s=new Float32Array(i.count*3),a=new Float32Array(i.count*4),o=new Float32Array(i.count*3),c=new Oe,l=new R,h=new pn,u=new R;for(let f=0;fr.times[r.times.length-1]){if(Math.abs(r.times[r.times.length-1]-e)<.001)return r.times.length-1;i[i.length-1]=e,i.set(r.times,0),s.set(r.values,0),s.set(a.evaluate(e),r.values.length),o=i.length-1}else for(let c=0;ce){i.set(r.times.slice(0,c+1),0),i[c+1]=e,i.set(r.times.slice(c+1),c+2),s.set(r.values.slice(0,(c+1)*n),0),s.set(a.evaluate(e),(c+1)*n),s.set(r.values.slice((c+1)*n),(c+2)*n),o=c+1;break}}return r.times=i,r.values=s,o},mergeMorphTargetTracks:function(r,e){const t=[],n={},i=r.tracks;for(let s=0;sr.material!==void 0&&r.userData&&r.userData.variantMaterials&&!!Array.from(r.userData.variantMaterials.values()).filter(e=>ll(e.material)),ll=r=>r&&r.isMaterial&&!Array.isArray(r);class D1{constructor(e){this.writer=e,this.name="KHR_materials_variants",this.variantNames=[]}beforeParse(e){const t=new Set,n=i=>{if(!vg(i))return;const s=i.userData.variantMaterials,a=i.userData.variantData;for(const[o,c]of a){const l=s.get(c.index);l&&ll(l.material)&&t.add(o)}};if(Array.isArray(e))for(const i of e)i.traverse(n);else e.traverse(n);t.forEach(i=>this.variantNames.push(i))}async writeMesh(e,t){if(!vg(e))return;const n=e.userData,i=n.variantMaterials,s=n.variantData,a=new Map,o=new Map,c=Array.from(s.values()).sort((u,d)=>u.index-d.index);for(const[u,d]of c.entries())o.set(d.index,u);for(const u of s.values()){const d=i.get(u.index);if(!d||!ll(d.material))continue;const f=await this.writer.processMaterialAsync(d.material);a.has(f)||a.set(f,{material:f,variants:[]}),a.get(f).variants.push(o.get(u.index))}const l=Array.from(a.values()).map((u=>u.variants.sort((d,f)=>d-f)&&u)).sort((u,d)=>u.material-d.material);if(l.length===0)return;const h=ll(n.originalMaterial)?await this.writer.processMaterialAsync(n.originalMaterial):-1;for(const u of t.primitives)h>=0&&(u.material=h),u.extensions=u.extensions||{},u.extensions[this.name]={mappings:l}}afterParse(){if(this.variantNames.length===0)return;const e=this.writer.json;e.extensions=e.extensions||{};const t=this.variantNames.map(n=>({name:n}));e.extensions[this.name]={variants:t},this.writer.extensionsUsed[this.name]=!0}}class L1{constructor(e,t,n,i,s){this.xrLight=e,this.renderer=t,this.lightProbe=n,this.xrWebGLBinding=null,this.estimationStartCallback=s,this.frameCallback=this.onXRFrame.bind(this);const a=t.xr.getSession();if(i&&"XRWebGLBinding"in window){const o=new ih(16);e.environment=o.texture;const c=t.getContext();switch(a.preferredReflectionFormat){case"srgba8":c.getExtension("EXT_sRGB");break;case"rgba16f":c.getExtension("OES_texture_half_float");break}this.xrWebGLBinding=new XRWebGLBinding(a,c),this.lightProbe.addEventListener("reflectionchange",()=>{this.updateReflection()})}a.requestAnimationFrame(this.frameCallback)}updateReflection(){const e=this.renderer.properties.get(this.xrLight.environment);if(e){const t=this.xrWebGLBinding.getReflectionCubeMap(this.lightProbe);t&&(e.__webglTexture=t,this.xrLight.environment.needsPMREMUpdate=!0)}}onXRFrame(e,t){if(!this.xrLight)return;t.session.requestAnimationFrame(this.frameCallback);const i=t.getLightEstimate(this.lightProbe);if(i){this.xrLight.lightProbe.sh.fromArray(i.sphericalHarmonicsCoefficients),this.xrLight.lightProbe.intensity=1;const s=Math.max(1,Math.max(i.primaryLightIntensity.x,Math.max(i.primaryLightIntensity.y,i.primaryLightIntensity.z)));this.xrLight.directionalLight.color.setRGB(i.primaryLightIntensity.x/s,i.primaryLightIntensity.y/s,i.primaryLightIntensity.z/s),this.xrLight.directionalLight.intensity=s,this.xrLight.directionalLight.position.copy(i.primaryLightDirection),this.estimationStartCallback&&(this.estimationStartCallback(),this.estimationStartCallback=null)}}dispose(){this.xrLight=null,this.renderer=null,this.lightProbe=null,this.xrWebGLBinding=null}}class P1 extends ds{constructor(e,t=!0){super(),this.lightProbe=new By,this.lightProbe.intensity=0,this.add(this.lightProbe),this.directionalLight=new Mb,this.directionalLight.intensity=0,this.add(this.directionalLight),this.environment=null;let n=null,i=!1;e.xr.addEventListener("sessionstart",()=>{const s=e.xr.getSession();"requestLightProbe"in s&&s.requestLightProbe({reflectionFormat:s.preferredReflectionFormat}).then(a=>{n=new L1(this,e,a,t,()=>{i=!0,this.dispatchEvent({type:"estimationstart"})})})}),e.xr.addEventListener("sessionend",()=>{n&&(n.dispose(),n=null),i&&this.dispatchEvent({type:"estimationend"})}),this.dispose=()=>{n&&(n.dispose(),n=null),this.remove(this.lightProbe),this.lightProbe=null,this.remove(this.directionalLight),this.directionalLight=null,this.environment=null}}}const Bx=1e4,F1=.001,Dx=50;class rn{constructor(e=Dx){this.velocity=0,this.naturalFrequency=0,this.setDecayTime(e)}setDecayTime(e){this.naturalFrequency=1/Math.max(F1,e)}update(e,t,n,i){const s=2e-4*this.naturalFrequency;if(e==null||i===0||e===t&&this.velocity===0)return t;if(n<0)return e;const a=e-t,o=this.velocity+this.naturalFrequency*a,c=a+n*o,l=Math.exp(-this.naturalFrequency*n),h=(o-this.naturalFrequency*c)*l,u=-this.naturalFrequency*(h+o*l);return Math.abs(h)=0?(this.velocity=0,t):(this.velocity=h,t+c*l)}}const rt={MIN_TOUCH_AREA:.05,BASE_RADIUS:.15,LINE_WIDTH:.02,SEGMENTS:16,DELTA_PHI:Math.PI/32,COLORS:{EDGE_FALLOFF:new Me(.98,.98,.98),EDGE_CUTOFF:new Me(.8,.8,.8),FILL_FALLOFF:new Me(.4,.4,.4),FILL_CUTOFF:new Me(.4,.4,.4),ACTIVE_EDGE:new Me(1,1,1),ACTIVE_FILL:new Me(.6,.6,.6)},MAX_OPACITY:.75,FILL_OPACITY_MULTIPLIER:.5,INTERACTIVE_OPACITY_MULTIPLIER:1.2,MIN_DISTANCE:.5,MAX_DISTANCE:10,BASE_SCALE:1,DISTANCE_SCALE_FACTOR:.3,COLOR_LERP_FACTOR:.15,SCREEN_SPACE_SCALE:1.2,SIZE_UPDATE_THRESHOLD:.001,GEOMETRY_UPDATE_DEBOUNCE:100},yg=new pe,Tc=(r,e,t,n,i)=>{let s=e>0?t>0?0:-Math.PI/2:t>0?Math.PI/2:Math.PI;for(let a=0;a<=rt.SEGMENTS;++a)r.push(e+(n-i)*Math.cos(s),t+(n-i)*Math.sin(s),0,e+n*Math.cos(s),t+n*Math.sin(s),0),s+=rt.DELTA_PHI};class N1 extends at{constructor(e,t){const n=new on;super(n),this.shadowHeight=0,this.isActive=!1,this.isHovered=!1,this.lastGeometryUpdateTime=0,this.needsGeometryUpdate=!1,this.scene=e,this.side=t,this.currentSize=new R,this.goalSize=new R,this.sizeDamper=new rn,this.updateSizeFromScene(),this.edgeMaterial=new fn({color:rt.COLORS.EDGE_FALLOFF,transparent:!0,opacity:0,side:Wt,depthWrite:!1,blending:md}),this.fillMaterial=new fn({color:rt.COLORS.FILL_FALLOFF,transparent:!0,opacity:0,side:Wt,depthWrite:!1,blending:js}),this.material=this.edgeMaterial,this.goalOpacity=0,this.opacityDamper=new rn,this.createHitMeshes(),this.updatePositionFromScene(),e.target.add(this),e.target.add(this.hitBox),this.offsetHeight=0}updateSizeFromScene(){const{size:e}=this.scene;this.goalSize.copy(e);const t=Math.sqrt(e.x*e.x+e.z*e.z),n=Math.max(rt.MIN_TOUCH_AREA,t*.4);this.goalSize.x0}update(e,t){if(this.updateOpacity(e),!this.currentSize.equals(this.goalSize)){const i=new R;i.x=this.sizeDamper.update(this.currentSize.x,this.goalSize.x,e,1),i.y=this.sizeDamper.update(this.currentSize.y,this.goalSize.y,e,1),i.z=this.sizeDamper.update(this.currentSize.z,this.goalSize.z,e,1),i.distanceTo(this.currentSize)>rt.SIZE_UPDATE_THRESHOLD&&(this.currentSize.copy(i),this.needsGeometryUpdate=!0)}const n=performance.now();this.needsGeometryUpdate&&n-this.lastGeometryUpdateTime>rt.GEOMETRY_UPDATE_DEBOUNCE&&(this.updateGeometry(),this.updateHitMeshes(),this.needsGeometryUpdate=!1,this.lastGeometryUpdateTime=n),t&&this.applyDistanceScaling(t),this.updateVisualState()}getSize(){return this.goalSize.clone()}dispose(){const{geometry:e,material:t}=this.hitPlane;e.dispose(),t.dispose(),this.hitBox.geometry.dispose(),this.hitBox.material.dispose(),this.geometry.dispose(),this.edgeMaterial.dispose(),this.fillMaterial.dispose(),this.hitBox.removeFromParent(),this.removeFromParent()}}const An=(r,e)=>({type:"number",number:r,unit:e}),Hi=(()=>{const r={};return t=>{const n=t;if(n in r)return r[n];const i=[];let s=0;for(;t;){if(++s>1e3){t="";break}const a=Lx(t),o=a.nodes[0];if(o==null||o.terms.length===0)break;i.push(o),t=a.remainingInput}return r[n]=i}})(),Lx=(()=>{const r=/^(\-\-|[a-z\u0240-\uffff])/i,e=/^([\*\+\/]|[\-]\s)/i,t=/^[\),]/;return s=>{const a=[];for(;s.length&&(s=s.trim(),!t.test(s));)if(s[0]==="("){const{nodes:o,remainingInput:c}=Sg(s);s=c,a.push({type:"function",name:{type:"ident",value:"calc"},arguments:o})}else if(r.test(s)){const o=U1(s),c=o.nodes[0];if(s=o.remainingInput,s[0]==="("){const{nodes:l,remainingInput:h}=Sg(s);a.push({type:"function",name:c,arguments:l}),s=h}else a.push(c)}else if(e.test(s))a.push({type:"operator",value:s[0]}),s=s.slice(1);else{const{nodes:o,remainingInput:c}=s[0]==="#"?k1(s):O1(s);if(o.length===0)break;a.push(o[0]),s=c}return{nodes:[{type:"expression",terms:a}],remainingInput:s}}})(),U1=(()=>{const r=/[^a-z0-9_\-\u0240-\uffff]/i;return e=>{const t=e.match(r),n=t==null?e:e.substr(0,t.index),i=t==null?"":e.substr(t.index);return{nodes:[{type:"ident",value:n}],remainingInput:i}}})(),O1=(()=>{const r=/[\+\-]?(\d+[\.]\d+|\d+|[\.]\d+)([eE][\+\-]?\d+)?/,e=/^[a-z%]+/i,t=/^(m|mm|cm|rad|deg|[%])$/;return n=>{const i=n.match(r),s=i==null?"0":i[0];n=s==null?n:n.slice(s.length);const a=n.match(e);let o=a!=null&&a[0]!==""?a[0]:null;const c=a==null?n:n.slice(o.length);return o!=null&&!t.test(o)&&(o=null),{nodes:[{type:"number",number:parseFloat(s)||0,unit:o}],remainingInput:c}}})(),k1=(()=>{const r=/^[a-f0-9]*/i;return e=>{e=e.slice(1).trim();const t=e.match(r);return{nodes:t==null?[]:[{type:"hex",value:t[0]}],remainingInput:t==null?e:e.slice(t[0].length)}}})(),Sg=r=>{const e=[];for(r=r.slice(1).trim();r.length;){const t=Lx(r);if(e.push(t.nodes[0]),r=t.remainingInput.trim(),r[0]===",")r=r.slice(1).trim();else if(r[0]===")"){r=r.slice(1);break}}return{nodes:e,remainingInput:r}},Cg=Symbol("visitedTypes");class Q1{constructor(e){this[Cg]=e}walk(e,t){const n=e.slice();for(;n.length;){const i=n.shift();switch(this[Cg].indexOf(i.type)>-1&&t(i),i.type){case"expression":n.unshift(...i.terms);break;case"function":n.unshift(i.name,...i.arguments);break}}}}const bs=Object.freeze({type:"number",number:0,unit:null});const rh=(r,e=0)=>{let{number:t,unit:n}=r;if(!isFinite(t))t=e,n="rad";else if(r.unit==="rad"||r.unit==null)return r;return{type:"number",number:(n==="deg"&&t!=null?t:0)*Math.PI/180,unit:"rad"}},Mg=(r,e=0)=>{let{number:t,unit:n}=r;if(!isFinite(t))t=e,n="m";else if(r.unit==="m")return r;let i;switch(n){default:i=1;break;case"cm":i=1/100;break;case"mm":i=1/1e3;break}return{type:"number",number:i*t,unit:"m"}},Ai=(()=>{const r=t=>t,e={rad:r,deg:rh,m:r,mm:Mg,cm:Mg};return(t,n=bs)=>{isFinite(t.number)||(t.number=n.number,t.unit=n.unit);const{unit:i}=t;if(i==null)return t;const s=e[i];return s==null?n:s(t)}})();var Px,Ig,wg;const va=Symbol("evaluate"),hl=Symbol("lastValue");class Bt{constructor(){this[Px]=null}static evaluatableFor(e,t=bs){if(e instanceof Bt)return e;if(e.type==="number")return e.unit==="%"?new G1(e,t):e;switch(e.name.value){case"calc":return new V1(e,t);case"env":return new H1(e)}return bs}static evaluate(e){return e instanceof Bt?e.evaluate():e}static isConstant(e){return e instanceof Bt?e.isConstant:!0}static applyIntrinsics(e,t){const{basis:n,keywords:i}=t,{auto:s}=i;return n.map((a,o)=>{const c=s[o]==null?a:s[o];let l=e[o]?e[o]:c;if(l.type==="ident"){const h=l.value;h in i&&(l=i[h][o])}return(l==null||l.type==="ident")&&(l=c),l.unit==="%"?An(l.number/100*a.number,a.unit):(l=Ai(l,a),l.unit!==a.unit?a:l)})}get isConstant(){return!1}evaluate(){return(!this.isConstant||this[hl]==null)&&(this[hl]=this[va]()),this[hl]}}Px=hl;const Tg=Symbol("percentage"),pu=Symbol("basis");class G1 extends Bt{constructor(e,t){super(),this[Tg]=e,this[pu]=t}get isConstant(){return!0}[va](){return An(this[Tg].number/100*this[pu].number,this[pu].unit)}}const Rc=Symbol("identNode");class H1 extends Bt{constructor(e){super(),this[Ig]=null;const t=e.arguments.length?e.arguments[0].terms[0]:null;t!=null&&t.type==="ident"&&(this[Rc]=t)}get isConstant(){return!1}[(Ig=Rc,va)](){if(this[Rc]!=null&&this[Rc].value==="window-scroll-y"){const e=window.pageYOffset,t=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);return{type:"number",number:e/(t-window.innerHeight)||0,unit:null}}return bs}}const z1=/[\*\/]/,Ir=Symbol("evaluator");class V1 extends Bt{constructor(e,t=bs){if(super(),this[wg]=null,e.arguments.length!==1)return;const n=e.arguments[0].terms.slice(),i=[];for(;n.length;){const s=n.shift();if(i.length>0){const a=i[i.length-1];if(a.type==="operator"&&z1.test(a.value)){const o=i.pop(),c=i.pop();if(c==null)return;i.push(new Bg(o,Bt.evaluatableFor(c,t),Bt.evaluatableFor(s,t)));continue}}i.push(s.type==="operator"?s:Bt.evaluatableFor(s,t))}for(;i.length>2;){const[s,a,o]=i.splice(0,3);if(a.type!=="operator")return;i.unshift(new Bg(a,Bt.evaluatableFor(s,t),Bt.evaluatableFor(o,t)))}i.length===1&&(this[Ir]=i[0])}get isConstant(){return this[Ir]==null||Bt.isConstant(this[Ir])}[(wg=Ir,va)](){return this[Ir]!=null?Bt.evaluate(this[Ir]):bs}}const Rg=Symbol("operator"),Au=Symbol("left"),gu=Symbol("right");class Bg extends Bt{constructor(e,t,n){super(),this[Rg]=e,this[Au]=t,this[gu]=n}get isConstant(){return Bt.isConstant(this[Au])&&Bt.isConstant(this[gu])}[va](){const e=Ai(Bt.evaluate(this[Au])),t=Ai(Bt.evaluate(this[gu])),{number:n,unit:i}=e,{number:s,unit:a}=t;if(a!=null&&i!=null&&a!=i)return bs;const o=i||a;let c;switch(this[Rg].value){case"+":c=n+s;break;case"-":c=n-s;break;case"/":c=n/s;break;case"*":c=n*s;break;default:return bs}return{type:"number",number:c,unit:o}}}const mu=Symbol("evaluatables"),Dg=Symbol("intrinsics");class Fx extends Bt{constructor(e,t){super(),this[Dg]=t;const n=e[0],i=n!=null?n.terms:[];this[mu]=t.basis.map((s,a)=>{const o=i[a];return o==null?{type:"ident",value:"auto"}:o.type==="ident"?o:Bt.evaluatableFor(o,s)})}get isConstant(){for(const e of this[mu])if(!Bt.isConstant(e))return!1;return!0}[va](){const e=this[mu].map(t=>Bt.evaluate(t));return Bt.applyIntrinsics(e,this[Dg]).map(t=>t.number)}}var Nx,Ux,Ox,kx;const wr=Symbol("instances"),Lg=Symbol("activateListener"),Pg=Symbol("deactivateListener"),bu=Symbol("notifyInstances"),Fg=Symbol("notify"),Ng=Symbol("callback");class ui{static[bu](){for(const e of ui[wr])e[Fg]()}static[(Nx=wr,Lg)](){window.addEventListener("scroll",this[bu],{passive:!0})}static[Pg](){window.removeEventListener("scroll",this[bu])}constructor(e){this[Ng]=e}observe(){ui[wr].size===0&&ui[Lg](),ui[wr].add(this)}disconnect(){ui[wr].delete(this),ui[wr].size===0&&ui[Pg]()}[Fg](){this[Ng]()}}ui[Nx]=new Set;const Ug=Symbol("computeStyleCallback"),Qx=Symbol("astWalker"),oo=Symbol("dependencies"),Gx=Symbol("onScroll");class W1{constructor(e){this[Ux]={},this[Ox]=new Q1(["function"]),this[kx]=()=>{this[Ug]({relatedState:"window-scroll"})},this[Ug]=e}observeEffectsFor(e){const t={},n=this[oo];this[Qx].walk(e,i=>{const{name:s}=i,o=i.arguments[0].terms[0];if(!(s.value!=="env"||o==null||o.type!=="ident"))switch(o.value){case"window-scroll-y":if(t["window-scroll"]==null){const c="window-scroll"in n?n["window-scroll"]:new ui(this[Gx]);c.observe(),delete n["window-scroll"],t["window-scroll"]=c}break}});for(const i in n)n[i].disconnect();this[oo]=t}dispose(){for(const e in this[oo])this[oo][e].disconnect()}}Ux=oo,Ox=Qx,kx=Gx;const ss=r=>{const e=r.observeEffects||!1,t=r.intrinsics instanceof Function?r.intrinsics:(()=>r.intrinsics);return(n,i)=>{const s=n.updated,a=n.connectedCallback,o=n.disconnectedCallback,c=Symbol(`${i}StyleEffector`),l=Symbol(`${i}StyleEvaluator`),h=Symbol(`${i}UpdateEvaluator`),u=Symbol(`${i}EvaluateAndSync`);Object.defineProperties(n,{[c]:{value:null,writable:!0},[l]:{value:null,writable:!0},[h]:{value:function(){const d=Hi(this[i]);this[l]=new Fx(d,t(this)),this[c]==null&&e&&(this[c]=new W1(()=>this[u]())),this[c]!=null&&this[c].observeEffectsFor(d)}},[u]:{value:function(){if(this[l]==null)return;const d=this[l].evaluate();this[r.updateHandler](d)}},updated:{value:function(d){d.has(i)&&(this[h](),this[u]()),s.call(this,d)}},connectedCallback:{value:function(){a.call(this),this.requestUpdate(i,this[i])}},disconnectedCallback:{value:function(){o.call(this),this[c]!=null&&(this[c].dispose(),this[c]=null)}}})}};const Hx=r=>r<.5?2*r*r:-1+(4-2*r)*r,q1=(r,e,t=Hx)=>n=>r+(e-r)*t(n),j1=(r,e)=>{const t=(i=>s=>i+=s),n=e.map(t(0));return i=>{i=fi(i,0,1),i*=n[n.length-1];const s=n.findIndex(c=>c>=i),a=s<1?0:n[s-1],o=n[s];return r[s]((i-a)/(o-a))}},zr=r=>{const e=[],t=[];let n=r.initialValue;for(let i=0;i=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};const X1=5e3,K1=zr({initialValue:0,keyframes:[{frames:5,value:-1},{frames:1,value:-1},{frames:8,value:1},{frames:1,value:1},{frames:5,value:0},{frames:18,value:0}]}),$1=zr({initialValue:0,keyframes:[{frames:1,value:1},{frames:5,value:1},{frames:1,value:0},{frames:6,value:0}]}),Y1=30,J1=12,zx="0deg 75deg 105%",Z1="auto auto auto",eR="auto",tR=2.2,nR=["front","right","back","left"],iR=["upper-","","lower-"],sR=3e3,rR=". Use mouse, touch or arrow keys to move.",Bc={AUTO:"auto"},xu={BASIC:"basic",WIGGLE:"wiggle"},aR={NONE:"none"},Og=()=>({basis:[rh(An(Y1,"deg"))],keywords:{auto:[null]}}),oR=()=>({basis:[rh(An(J1,"deg"))],keywords:{auto:[null]}}),Vx=(()=>{const r=Hi(zx)[0].terms,e=Ai(r[0]),t=Ai(r[1]);return n=>{const i=n[J].idealCameraDistance();return{basis:[e,t,An(i,"m")],keywords:{auto:[null,null,An(105,"%")]}}}})(),cR=r=>{const e=tR*r[J].boundingSphere.radius;return{basis:[An(-1/0,"rad"),An(0,"rad"),An(e,"m")],keywords:{auto:[null,null,null]}}},lR=r=>{const e=Vx(r),n=new Fx([],e).evaluate()[2];return{basis:[An(1/0,"rad"),An(Math.PI,"rad"),An(n,"m")],keywords:{auto:[null,null,null]}}},hR=r=>{r[J].updateBoundingBoxAndShadowIfDirty();const e=r[J].boundingBox.getCenter(new R);return{basis:[An(e.x,"m"),An(e.y,"m"),An(e.z,"m")],keywords:{auto:[null,null,null]}}},Wx=Math.PI/2,uR=Math.PI/3,dR=Wx/2,fR=2*Math.PI,dt=Symbol("controls"),ul=Symbol("panElement"),Eu=Symbol("promptElement"),Dc=Symbol("promptAnimatedContainer"),_u=Symbol("fingerAnimatedContainers"),Lc=Symbol("deferInteractionPrompt"),kg=Symbol("updateAria"),Bi=Symbol("a11y"),Qg=Symbol("updateA11y"),Gg=Symbol("updateCameraForRadius"),Tr=Symbol("cancelPrompts"),vu=Symbol("onChange"),Ua=Symbol("onPointerChange"),Rs=Symbol("waitingToPromptUser"),Pc=Symbol("userHasInteracted"),Rr=Symbol("promptElementVisibleTime"),Oa=Symbol("lastPromptOffset"),Fc=Symbol("cancellationSource"),yu=Symbol("lastSpherical"),ka=Symbol("jumpCamera"),Su=Symbol("initialized"),Qa=Symbol("maintainThetaPhi"),Hg=Symbol("syncCameraOrbit"),zg=Symbol("syncFieldOfView"),Vg=Symbol("syncCameraTarget"),Wg=Symbol("syncMinCameraOrbit"),qg=Symbol("syncMaxCameraOrbit"),jg=Symbol("syncMinFieldOfView"),Xg=Symbol("syncMaxFieldOfView"),pR=r=>{var e,t,n,i,s,a,o,c,l,h,u,d,f,p,m,A,g,b;class x extends r{constructor(){super(...arguments),this.cameraControls=!1,this.cameraOrbit=zx,this.cameraTarget=Z1,this.fieldOfView=eR,this.minCameraOrbit="auto",this.maxCameraOrbit="auto",this.minFieldOfView="auto",this.maxFieldOfView="auto",this.interactionPromptThreshold=sR,this.interactionPrompt=Bc.AUTO,this.interactionPromptStyle=xu.WIGGLE,this.orbitSensitivity=1,this.zoomSensitivity=1,this.panSensitivity=1,this.touchAction=aR.NONE,this.disableZoom=!1,this.disablePan=!1,this.disableTap=!1,this.interpolationDecay=Dx,this.a11y=null,this[e]=this.shadowRoot.querySelector(".interaction-prompt"),this[t]=this.shadowRoot.querySelector("#prompt"),this[n]=[this.shadowRoot.querySelector("#finger0"),this.shadowRoot.querySelector("#finger1")],this[i]=this.shadowRoot.querySelector(".pan-target"),this[s]=0,this[a]=1/0,this[o]=!1,this[c]=!1,this[l]=Pt.AUTOMATIC,this[h]=new bR(this[J].camera,this[$n],this[J]),this[u]=new ol,this[d]=!1,this[f]=!1,this[p]=!1,this[m]={},this[A]=()=>{const v=this[dt].changeSource;this[Fc]=v,v===Pt.USER_INTERACTION&&(this[Pc]=!0,this[Lc]())},this[g]=()=>{this[kg](),this[en]();const v=this[dt].changeSource;this.dispatchEvent(new CustomEvent("camera-change",{detail:{source:v}}))},this[b]=v=>{this[pl].classList.toggle("pointer-tumbling",v.type==="pointer-change-start")}}get inputSensitivity(){return this[dt].inputSensitivity}set inputSensitivity(v){this[dt].inputSensitivity=v}getCameraOrbit(){const{theta:v,phi:S,radius:I}=this[yu];return{theta:v,phi:S,radius:I,toString(){return`${this.theta}rad ${this.phi}rad ${this.radius}m`}}}getCameraTarget(){return ls(this[ot].isPresenting?this[ot].arRenderer.target:this[J].getDynamicTarget())}getFieldOfView(){return this[dt].getFieldOfView()}getMinimumFieldOfView(){return this[dt].options.minimumFieldOfView}getMaximumFieldOfView(){return this[dt].options.maximumFieldOfView}getIdealAspect(){return this[J].idealAspect}jumpCameraToGoal(){this[ka]=!0,this.requestUpdate(ka,!1)}resetInteractionPrompt(){this[Oa]=0,this[Rr]=1/0,this[Pc]=!1,this[Rs]=this.interactionPrompt===Bc.AUTO&&this.cameraControls}zoom(v){const S=new WheelEvent("wheel",{deltaY:-30*v});this[$n].dispatchEvent(S)}connectedCallback(){super.connectedCallback(),this[dt].addEventListener("user-interaction",this[Tr]),this[dt].addEventListener("pointer-change-start",this[Ua]),this[dt].addEventListener("pointer-change-end",this[Ua])}disconnectedCallback(){super.disconnectedCallback(),this[dt].removeEventListener("user-interaction",this[Tr]),this[dt].removeEventListener("pointer-change-start",this[Ua]),this[dt].removeEventListener("pointer-change-end",this[Ua])}updated(v){super.updated(v);const S=this[dt],I=this[J];if(v.has("cameraControls")&&(this.cameraControls?(S.enableInteraction(),this.interactionPrompt===Bc.AUTO&&(this[Rs]=!0)):(S.disableInteraction(),this[Lc]()),this[$n].setAttribute("aria-label",this[Wr])),v.has("disableZoom")&&(S.disableZoom=this.disableZoom),v.has("disablePan")&&(S.enablePan=!this.disablePan),v.has("disableTap")&&(S.enableTap=!this.disableTap),(v.has("interactionPrompt")||v.has("cameraControls")||v.has("src"))&&(this.interactionPrompt===Bc.AUTO&&this.cameraControls&&!this[Pc]?this[Rs]=!0:this[Lc]()),v.has("interactionPromptStyle")&&(this[Dc].style.opacity=this.interactionPromptStyle==xu.BASIC?"1":"0"),v.has("touchAction")){const E=this.touchAction;S.applyOptions({touchAction:E}),S.updateTouchActionStyle()}v.has("orbitSensitivity")&&(S.orbitSensitivity=this.orbitSensitivity),v.has("zoomSensitivity")&&(S.zoomSensitivity=this.zoomSensitivity),v.has("panSensitivity")&&(S.panSensitivity=this.panSensitivity),v.has("interpolationDecay")&&(S.setDamperDecayTime(this.interpolationDecay),I.setTargetDamperDecayTime(this.interpolationDecay)),v.has("a11y")&&this[Qg](),this[ka]===!0&&Promise.resolve().then(()=>{S.jumpToGoal(),I.jumpToGoal(),this[vu](),this[ka]=!1})}async updateFraming(){const v=this[J],S=v.adjustedFoV(v.framedFoVDeg);await v.updateFraming();const I=v.adjustedFoV(v.framedFoVDeg),E=this[dt].getFieldOfView()/S;this[dt].setFieldOfView(I*E),this[Qa]=!0,this.requestUpdate("maxFieldOfView"),this.requestUpdate("fieldOfView"),this.requestUpdate("minCameraOrbit"),this.requestUpdate("maxCameraOrbit"),this.requestUpdate("cameraOrbit"),await this.updateComplete}interact(v,S,I){const E=this[$n],C=this[_u];if(C[0].style.opacity==="1"){console.warn("interact() failed because an existing interaction is running.");return}const D=new Array;D.push({x:zr(S.x),y:zr(S.y)});const w=[{x:D[0].x(0),y:D[0].y(0)}];I!=null&&(D.push({x:zr(I.x),y:zr(I.y)}),w.push({x:D[1].x(0),y:D[1].y(0)}));let L=performance.now();const{width:U,height:P}=this[J],N=this.getBoundingClientRect(),F=q=>{for(const[te,Z]of w.entries()){const{style:Y}=C[te];Y.transform=`translateX(${U*Z.x}px) translateY(${P*Z.y}px)`,q==="pointerdown"?Y.opacity="1":q==="pointerup"&&(Y.opacity="0");const fe={pointerId:te-5678,pointerType:"touch",target:E,clientX:U*Z.x+N.x,clientY:P*Z.y+N.y,altKey:!0};E.dispatchEvent(new PointerEvent(q,fe))}},k=()=>{const q=this[Fc];if(q!==Pt.AUTOMATIC||!E.isConnected){for(const Z of this[_u])Z.style.opacity="0";F("pointercancel"),this.dispatchEvent(new CustomEvent("interact-stopped",{detail:{source:q}})),document.removeEventListener("visibilitychange",$);return}const te=Math.min(1,(performance.now()-L)/v);for(const[Z,Y]of w.entries())Y.x=D[Z].x(te),Y.y=D[Z].y(te);F("pointermove"),te<1?requestAnimationFrame(k):(F("pointerup"),this.dispatchEvent(new CustomEvent("interact-stopped",{detail:{source:Pt.AUTOMATIC}})),document.removeEventListener("visibilitychange",$))},$=()=>{let q=0;document.visibilityState==="hidden"?q=performance.now()-L:L=performance.now()-q};document.addEventListener("visibilitychange",$),F("pointerdown"),this[Fc]=Pt.AUTOMATIC,requestAnimationFrame(k)}[(e=Eu,t=Dc,n=_u,i=ul,s=Oa,a=Rr,o=Pc,c=Rs,l=Fc,h=dt,u=yu,d=ka,f=Su,p=Qa,m=Bi,zg)](v){const S=this[dt],I=this[J];I.framedFoVDeg=v[0]*180/Math.PI,S.changeSource=Pt.NONE,S.setFieldOfView(I.adjustedFoV(I.framedFoVDeg)),this[Tr]()}[Hg](v){const S=this[dt];if(this[Qa]){const{theta:I,phi:E}=this.getCameraOrbit();v[0]=I,v[1]=E,this[Qa]=!1}S.changeSource=Pt.NONE,S.setOrbit(v[0],v[1],v[2]),this[Tr]()}[Wg](v){this[dt].applyOptions({minimumAzimuthalAngle:v[0],minimumPolarAngle:v[1],minimumRadius:v[2]}),this.jumpCameraToGoal()}[qg](v){this[dt].applyOptions({maximumAzimuthalAngle:v[0],maximumPolarAngle:v[1],maximumRadius:v[2]}),this[Gg](v[2]),this.jumpCameraToGoal()}[jg](v){this[dt].applyOptions({minimumFieldOfView:v[0]*180/Math.PI}),this.jumpCameraToGoal()}[Xg](v){const S=this[J].adjustedFoV(v[0]*180/Math.PI);this[dt].applyOptions({maximumFieldOfView:S}),this.jumpCameraToGoal()}[Vg](v){const[S,I,E]=v;this[ot].arRenderer.isPresenting||this[J].setTarget(S,I,E),this[dt].changeSource=Pt.NONE,this[ot].arRenderer.updateTarget(),this[Tr]()}[gi](v,S){if(super[gi](v,S),this[ot].isPresenting||!this[ir]())return;const I=this[dt],E=this[J],C=performance.now();if(this[Rs]&&this.loaded&&C>this[ho]+this.interactionPromptThreshold&&(this[Rs]=!1,this[Rr]=C,this[Eu].classList.add("visible")),isFinite(this[Rr])&&this.interactionPromptStyle===xu.WIGGLE){const L=(C-this[Rr])/X1%1,U=K1(L),P=$1(L);if(this[Dc].style.opacity=`${P}`,U!==this[Oa]){const N=U*E.width*.05,F=(U-this[Oa])*Math.PI/16;this[Dc].style.transform=`translateX(${N}px)`,I.changeSource=Pt.AUTOMATIC,I.adjustOrbit(F,0,0),this[Oa]=U}}const D=I.update(v,S),w=E.updateTarget(S);(D||w)&&this[vu]()}[Lc](){this[Rs]=!1,this[Eu].classList.remove("visible"),this[Rr]=1/0}[Gg](v){const S=Math.max(this[J].farRadius(),v),I=0,E=Math.abs(2*S);this[dt].updateNearFar(I,E)}[kg](){const{theta:v,phi:S}=this[dt].getCameraSpherical(this[yu]),I=(4+Math.floor((v%fR+dR)/Wx))%4,E=Math.floor(S/uR),C=nR[I],w=`${iR[E]}${C}`,L=w;L in this[Bi]?this[Gl](this[Bi][L]):this[Gl](`View from stage ${w}`)}get[Wr](){let v=rR;return"interaction-prompt"in this[Bi]&&(v=`. ${this[Bi]["interaction-prompt"]}`),super[Wr].replace(/\.$/,"")+(this.cameraControls?v:"")}async[Hl](v){const S=this[dt],I=this[J],E=I.adjustedFoV(I.framedFoVDeg);super[Hl](v);const C=I.adjustedFoV(I.framedFoVDeg)/E,D=S.getFieldOfView()*(isFinite(C)?C:1);S.updateAspect(this[J].aspect),this.requestUpdate("maxFieldOfView",this.maxFieldOfView),await this.updateComplete,this[dt].setFieldOfView(D),this.jumpCameraToGoal()}[mi](){super[mi](),this[Su]?this[Qa]=!0:this[Su]=!0,this.requestUpdate("maxFieldOfView",this.maxFieldOfView),this.requestUpdate("fieldOfView",this.fieldOfView),this.requestUpdate("minCameraOrbit",this.minCameraOrbit),this.requestUpdate("maxCameraOrbit",this.maxCameraOrbit),this.requestUpdate("cameraOrbit",this.cameraOrbit),this.requestUpdate("cameraTarget",this.cameraTarget),this.jumpCameraToGoal()}[(A=Tr,g=vu,b=Ua,Qg)](){if(typeof this.a11y=="string")if(this.a11y.startsWith("{"))try{this[Bi]=JSON.parse(this.a11y)}catch(v){console.warn("Error parsing a11y JSON:",v)}else this.a11y.length>0?console.warn("Error not supported format, should be a JSON string:",this.a11y):this[Bi]={};else typeof this.a11y=="object"&&this.a11y!=null?this[Bi]=Object.assign({},this.a11y):this[Bi]={};this[$n].setAttribute("aria-label",this[Wr])}}return Vt([Re({type:Boolean,attribute:"camera-controls"})],x.prototype,"cameraControls",void 0),Vt([ss({intrinsics:Vx,observeEffects:!0,updateHandler:Hg}),Re({type:String,attribute:"camera-orbit",hasChanged:()=>!0})],x.prototype,"cameraOrbit",void 0),Vt([ss({intrinsics:hR,observeEffects:!0,updateHandler:Vg}),Re({type:String,attribute:"camera-target",hasChanged:()=>!0})],x.prototype,"cameraTarget",void 0),Vt([ss({intrinsics:Og,observeEffects:!0,updateHandler:zg}),Re({type:String,attribute:"field-of-view",hasChanged:()=>!0})],x.prototype,"fieldOfView",void 0),Vt([ss({intrinsics:cR,updateHandler:Wg}),Re({type:String,attribute:"min-camera-orbit",hasChanged:()=>!0})],x.prototype,"minCameraOrbit",void 0),Vt([ss({intrinsics:lR,updateHandler:qg}),Re({type:String,attribute:"max-camera-orbit",hasChanged:()=>!0})],x.prototype,"maxCameraOrbit",void 0),Vt([ss({intrinsics:oR,updateHandler:jg}),Re({type:String,attribute:"min-field-of-view",hasChanged:()=>!0})],x.prototype,"minFieldOfView",void 0),Vt([ss({intrinsics:Og,updateHandler:Xg}),Re({type:String,attribute:"max-field-of-view",hasChanged:()=>!0})],x.prototype,"maxFieldOfView",void 0),Vt([Re({type:Number,attribute:"interaction-prompt-threshold"})],x.prototype,"interactionPromptThreshold",void 0),Vt([Re({type:String,attribute:"interaction-prompt"})],x.prototype,"interactionPrompt",void 0),Vt([Re({type:String,attribute:"interaction-prompt-style"})],x.prototype,"interactionPromptStyle",void 0),Vt([Re({type:Number,attribute:"orbit-sensitivity"})],x.prototype,"orbitSensitivity",void 0),Vt([Re({type:Number,attribute:"zoom-sensitivity"})],x.prototype,"zoomSensitivity",void 0),Vt([Re({type:Number,attribute:"pan-sensitivity"})],x.prototype,"panSensitivity",void 0),Vt([Re({type:String,attribute:"touch-action"})],x.prototype,"touchAction",void 0),Vt([Re({type:Boolean,attribute:"disable-zoom"})],x.prototype,"disableZoom",void 0),Vt([Re({type:Boolean,attribute:"disable-pan"})],x.prototype,"disablePan",void 0),Vt([Re({type:Boolean,attribute:"disable-tap"})],x.prototype,"disableTap",void 0),Vt([Re({type:Number,attribute:"interpolation-decay"})],x.prototype,"interpolationDecay",void 0),Vt([Re()],x.prototype,"a11y",void 0),x};const AR=.018,Kg=2,gR=300,mR=new pe,$g=new R,Yg=Object.freeze({minimumRadius:0,maximumRadius:1/0,minimumPolarAngle:0,maximumPolarAngle:Math.PI,minimumAzimuthalAngle:-1/0,maximumAzimuthalAngle:1/0,minimumFieldOfView:10,maximumFieldOfView:45,touchAction:"none"}),Nc=Math.PI/8,Uc=.04,Oc=10,Pt={USER_INTERACTION:"user-interaction",NONE:"none",AUTOMATIC:"automatic"};class bR extends ii{constructor(e,t,n){super(),this.camera=e,this.element=t,this.scene=n,this.orbitSensitivity=1,this.zoomSensitivity=1,this.panSensitivity=1,this.inputSensitivity=1,this.changeSource=Pt.NONE,this._interactionEnabled=!1,this._disableZoom=!1,this.isUserPointing=!1,this.enablePan=!0,this.enableTap=!0,this.panProjection=new Qe,this.panPerPixel=0,this.spherical=new ol,this.goalSpherical=new ol,this.thetaDamper=new rn,this.phiDamper=new rn,this.radiusDamper=new rn,this.logFov=Math.log(Yg.maximumFieldOfView),this.goalLogFov=this.logFov,this.fovDamper=new rn,this.touchMode=null,this.pointers=[],this.startTime=0,this.startPointerPosition={clientX:0,clientY:0},this.lastSeparation=0,this.touchDecided=!1,this.onContext=i=>{if(this.enablePan)i.preventDefault();else for(const s of this.pointers)this.onPointerUp(new PointerEvent("pointercancel",Object.assign(Object.assign({},this.startPointerPosition),{pointerId:s.id})))},this.touchModeZoom=(i,s)=>{if(!this._disableZoom){const a=this.twoTouchDistance(this.pointers[0],this.pointers[1]),o=Uc*this.zoomSensitivity*(this.lastSeparation-a)*50/this.scene.height;this.lastSeparation=a,this.userAdjustOrbit(0,0,o)}this.panPerPixel>0&&this.movePan(i,s)},this.disableScroll=i=>{i.preventDefault()},this.touchModeRotate=(i,s)=>{const{touchAction:a}=this._options;if(!this.touchDecided&&a!=="none"){this.touchDecided=!0;const o=Math.abs(i),c=Math.abs(s);if(this.changeSource===Pt.USER_INTERACTION&&(a==="pan-y"&&c>o||a==="pan-x"&&o>c)){this.touchMode=null;return}else this.element.addEventListener("touchmove",this.disableScroll,{passive:!1})}this.handleSinglePointerMove(i,s)},this.onPointerDown=i=>{if(this.pointers.length>2)return;const{element:s}=this;this.pointers.length===0&&(s.addEventListener("pointermove",this.onPointerMove),s.addEventListener("pointerup",this.onPointerUp),this.touchMode=null,this.touchDecided=!1,this.startPointerPosition.clientX=i.clientX,this.startPointerPosition.clientY=i.clientY,this.startTime=performance.now());try{s.setPointerCapture(i.pointerId)}catch{}this.pointers.push({clientX:i.clientX,clientY:i.clientY,id:i.pointerId}),this.isUserPointing=!1,i.pointerType==="touch"?(this.changeSource=i.altKey?Pt.AUTOMATIC:Pt.USER_INTERACTION,this.onTouchChange(i)):(this.changeSource=Pt.USER_INTERACTION,this.onMouseDown(i)),this.changeSource===Pt.USER_INTERACTION&&this.dispatchEvent({type:"user-interaction"})},this.onPointerMove=i=>{const s=this.pointers.find(l=>l.id===i.pointerId);if(s==null)return;if(i.pointerType==="mouse"&&i.buttons===0){this.onPointerUp(i);return}const a=this.pointers.length,o=(i.clientX-s.clientX)/a,c=(i.clientY-s.clientY)/a;o===0&&c===0||(s.clientX=i.clientX,s.clientY=i.clientY,i.pointerType==="touch"?(this.changeSource=i.altKey?Pt.AUTOMATIC:Pt.USER_INTERACTION,this.touchMode!==null&&this.touchMode(o,c)):(this.changeSource=Pt.USER_INTERACTION,this.panPerPixel>0?this.movePan(o,c):this.handleSinglePointerMove(o,c)))},this.onPointerUp=i=>{const{element:s}=this,a=this.pointers.findIndex(o=>o.id===i.pointerId);a!==-1&&this.pointers.splice(a,1),this.panPerPixel>0&&!i.altKey&&this.resetRadius(),this.pointers.length===0?(s.removeEventListener("pointermove",this.onPointerMove),s.removeEventListener("pointerup",this.onPointerUp),s.removeEventListener("touchmove",this.disableScroll),this.enablePan&&this.enableTap&&this.recenter(i)):this.touchMode!==null&&this.onTouchChange(i),this.scene.element[ul].style.opacity=0,s.style.cursor="grab",this.panPerPixel=0,this.isUserPointing&&this.dispatchEvent({type:"pointer-change-end"})},this.onWheel=i=>{this.changeSource=Pt.USER_INTERACTION;const s=i.deltaY*(i.deltaMode==1?18:1)*Uc*this.zoomSensitivity/30;this.userAdjustOrbit(0,0,s),i.preventDefault(),this.dispatchEvent({type:"user-interaction"})},this.onKeyDown=i=>{const{changeSource:s}=this;this.changeSource=Pt.USER_INTERACTION,(i.shiftKey&&this.enablePan?this.panKeyCodeHandler(i):this.orbitZoomKeyCodeHandler(i))?(i.preventDefault(),this.dispatchEvent({type:"user-interaction"})):this.changeSource=s},this._options=Object.assign({},Yg),this.setOrbit(0,Math.PI/2,1),this.setFieldOfView(100),this.jumpToGoal()}get interactionEnabled(){return this._interactionEnabled}enableInteraction(){if(this._interactionEnabled===!1){const{element:e}=this;e.addEventListener("pointerdown",this.onPointerDown),e.addEventListener("pointercancel",this.onPointerUp),this._disableZoom||e.addEventListener("wheel",this.onWheel),e.addEventListener("keydown",this.onKeyDown),e.addEventListener("touchmove",()=>{},{passive:!1}),e.addEventListener("contextmenu",this.onContext),this.element.style.cursor="grab",this._interactionEnabled=!0,this.updateTouchActionStyle()}}disableInteraction(){if(this._interactionEnabled===!0){const{element:e}=this;e.removeEventListener("pointerdown",this.onPointerDown),e.removeEventListener("pointermove",this.onPointerMove),e.removeEventListener("pointerup",this.onPointerUp),e.removeEventListener("pointercancel",this.onPointerUp),e.removeEventListener("wheel",this.onWheel),e.removeEventListener("keydown",this.onKeyDown),e.removeEventListener("contextmenu",this.onContext),e.style.cursor="",this.touchMode=null,this._interactionEnabled=!1,this.updateTouchActionStyle()}}get options(){return this._options}set disableZoom(e){this._disableZoom!=e&&(this._disableZoom=e,e===!0?this.element.removeEventListener("wheel",this.onWheel):this.element.addEventListener("wheel",this.onWheel),this.updateTouchActionStyle())}getCameraSpherical(e=new ol){return e.copy(this.spherical)}getFieldOfView(){return this.camera.fov}applyOptions(e){Object.assign(this._options,e),this.setOrbit(),this.setFieldOfView(Math.exp(this.goalLogFov))}updateNearFar(e,t){this.camera.far=t===0?2:t,this.camera.near=Math.max(e,this.camera.far/1e3),this.camera.updateProjectionMatrix()}updateAspect(e){this.camera.aspect=e,this.camera.updateProjectionMatrix()}setOrbit(e=this.goalSpherical.theta,t=this.goalSpherical.phi,n=this.goalSpherical.radius){const{minimumAzimuthalAngle:i,maximumAzimuthalAngle:s,minimumPolarAngle:a,maximumPolarAngle:o,minimumRadius:c,maximumRadius:l}=this._options,{theta:h,phi:u,radius:d}=this.goalSpherical,f=fi(e,i,s);!isFinite(i)&&!isFinite(s)&&(this.spherical.theta=this.wrapAngle(this.spherical.theta-f)+f);const p=fi(t,a,o),m=fi(n,c,l);return f===h&&p===u&&m===d||!isFinite(f)||!isFinite(p)||!isFinite(m)?!1:(this.goalSpherical.theta=f,this.goalSpherical.phi=p,this.goalSpherical.radius=m,this.goalSpherical.makeSafe(),!0)}setRadius(e){this.goalSpherical.radius=e,this.setOrbit()}setFieldOfView(e){const{minimumFieldOfView:t,maximumFieldOfView:n}=this._options;e=fi(e,t,n),this.goalLogFov=Math.log(e)}setDamperDecayTime(e){this.thetaDamper.setDecayTime(e),this.phiDamper.setDecayTime(e),this.radiusDamper.setDecayTime(e),this.fovDamper.setDecayTime(e)}adjustOrbit(e,t,n){const{theta:i,phi:s,radius:a}=this.goalSpherical,{minimumRadius:o,maximumRadius:c,minimumFieldOfView:l,maximumFieldOfView:h}=this._options,u=this.spherical.theta-i,d=Math.PI-.001,f=i-fi(e,-d-u,d-u),p=s-t,m=n===0?0:((n>0?c:o)-a)/(Math.log(n>0?h:l)-this.goalLogFov),A=a+n*(isFinite(m)?m:(c-o)*2);if(this.setOrbit(f,p,A),n!==0){const g=this.goalLogFov+n;this.setFieldOfView(Math.exp(g))}}jumpToGoal(){this.update(0,Bx)}update(e,t){if(this.isStationary())return!1;const{maximumPolarAngle:n,maximumRadius:i}=this._options,s=this.spherical.theta-this.goalSpherical.theta;return Math.abs(s)>Math.PI&&!isFinite(this._options.minimumAzimuthalAngle)&&!isFinite(this._options.maximumAzimuthalAngle)&&(this.spherical.theta-=Math.sign(s)*2*Math.PI),this.spherical.theta=this.thetaDamper.update(this.spherical.theta,this.goalSpherical.theta,t,Math.PI),this.spherical.phi=this.phiDamper.update(this.spherical.phi,this.goalSpherical.phi,t,n),this.spherical.radius=this.radiusDamper.update(this.spherical.radius,this.goalSpherical.radius,t,i),this.logFov=this.fovDamper.update(this.logFov,this.goalLogFov,t,1),this.moveCamera(),!0}updateTouchActionStyle(){const{style:e}=this.element;if(this._interactionEnabled){const{touchAction:t}=this._options;this._disableZoom&&t!=="none"?e.touchAction="manipulation":e.touchAction=t}else e.touchAction=""}isStationary(){return this.goalSpherical.theta===this.spherical.theta&&this.goalSpherical.phi===this.spherical.phi&&this.goalSpherical.radius===this.spherical.radius&&this.goalLogFov===this.logFov}moveCamera(){this.spherical.makeSafe(),this.camera.position.setFromSpherical(this.spherical),this.camera.setRotationFromEuler(new Gn(this.spherical.phi-Math.PI/2,this.spherical.theta,0,"YXZ")),this.camera.fov!==Math.exp(this.logFov)&&(this.camera.fov=Math.exp(this.logFov),this.camera.updateProjectionMatrix())}userAdjustOrbit(e,t,n){this.adjustOrbit(e*this.orbitSensitivity*this.inputSensitivity,t*this.orbitSensitivity*this.inputSensitivity,n*this.inputSensitivity)}wrapAngle(e){const t=(e+Math.PI)/(2*Math.PI);return(t-Math.floor(t))*2*Math.PI-Math.PI}pixelLengthToSphericalAngle(e){return 2*Math.PI*e/this.scene.height}twoTouchDistance(e,t){const{clientX:n,clientY:i}=e,{clientX:s,clientY:a}=t,o=s-n,c=a-i;return Math.sqrt(o*o+c*c)}handleSinglePointerMove(e,t){const n=this.pixelLengthToSphericalAngle(e),i=this.pixelLengthToSphericalAngle(t);this.isUserPointing===!1&&(this.isUserPointing=!0,this.dispatchEvent({type:"pointer-change-start"})),this.userAdjustOrbit(n,i,0)}initializePan(){const{theta:e,phi:t}=this.spherical,n=e-this.scene.yaw;this.panPerPixel=AR*this.panSensitivity/this.scene.height,this.panProjection.set(-Math.cos(n),-Math.cos(t)*Math.sin(n),0,0,Math.sin(t),0,Math.sin(n),-Math.cos(t)*Math.cos(n),0)}movePan(e,t){const{scene:n}=this,i=$g.set(e,t,0).multiplyScalar(this.inputSensitivity),s=this.spherical.radius*Math.exp(this.logFov)*this.panPerPixel;i.multiplyScalar(s);const a=n.getTarget();a.add(i.applyMatrix3(this.panProjection)),n.boundingSphere.clampPoint(a,a),n.setTarget(a.x,a.y,a.z)}recenter(e){if(performance.now()>this.startTime+gR||Math.abs(e.clientX-this.startPointerPosition.clientX)>Kg||Math.abs(e.clientY-this.startPointerPosition.clientY)>Kg)return;const{scene:t}=this,n=t.positionAndNormalFromPoint(t.getNDC(e.clientX,e.clientY));if(n==null){const{cameraTarget:i}=t.element;t.element.cameraTarget="",t.element.cameraTarget=i,this.userAdjustOrbit(0,0,1)}else t.target.worldToLocal(n.position),t.setTarget(n.position.x,n.position.y,n.position.z)}resetRadius(){const{scene:e}=this,t=e.positionAndNormalFromPoint(mR.set(0,0));if(t==null)return;e.target.worldToLocal(t.position);const n=e.getTarget(),{theta:i,phi:s}=this.spherical,a=i-e.yaw,o=$g.set(Math.sin(s)*Math.sin(a),Math.cos(s),Math.sin(s)*Math.cos(a)),c=o.dot(t.position.sub(n));n.add(o.multiplyScalar(c)),e.setTarget(n.x,n.y,n.z),this.setOrbit(void 0,void 0,this.goalSpherical.radius-c)}onTouchChange(e){if(this.pointers.length===1)this.touchMode=this.touchModeRotate;else{if(this._disableZoom){this.touchMode=null,this.element.removeEventListener("touchmove",this.disableScroll);return}this.touchMode=this.touchDecided&&this.touchMode===null?null:this.touchModeZoom,this.touchDecided=!0,this.element.addEventListener("touchmove",this.disableScroll,{passive:!1}),this.lastSeparation=this.twoTouchDistance(this.pointers[0],this.pointers[1]),this.enablePan&&this.touchMode!=null&&(this.initializePan(),e.altKey||(this.scene.element[ul].style.opacity=1))}}onMouseDown(e){this.panPerPixel=0,this.enablePan&&(e.button===2||e.ctrlKey||e.metaKey||e.shiftKey)&&(this.initializePan(),this.scene.element[ul].style.opacity=1),this.element.style.cursor="grabbing"}orbitZoomKeyCodeHandler(e){let t=!0;switch(e.key){case"PageUp":this.userAdjustOrbit(0,0,Uc*this.zoomSensitivity);break;case"PageDown":this.userAdjustOrbit(0,0,-1*Uc*this.zoomSensitivity);break;case"ArrowUp":this.userAdjustOrbit(0,-Nc,0);break;case"ArrowDown":this.userAdjustOrbit(0,Nc,0);break;case"ArrowLeft":this.userAdjustOrbit(-Nc,0,0);break;case"ArrowRight":this.userAdjustOrbit(Nc,0,0);break;default:t=!1;break}return t}panKeyCodeHandler(e){this.initializePan();let t=!0;switch(e.key){case"ArrowUp":this.movePan(0,-1*Oc);break;case"ArrowDown":this.movePan(0,Oc);break;case"ArrowLeft":this.movePan(-1*Oc,0);break;case"ArrowRight":this.movePan(Oc,0);break;default:t=!1;break}return t}}const Jg=` + +`,Zg=` + +`,em=` + + + + + + + + +`,ci={width:.16,height:.07,cornerRadius:.03,opacity:1,color:0,minDistance:.5,maxDistance:10,baseScale:1,distanceScaleFactor:.3},Ga={size:.05,zOffset:.01,spacing:.07},Ha={canvasSize:128,filter:qe};class ki extends ht{constructor(){super(),this.isActualSize=!1,this.preRenderIcons(),this.createPanel(),this.createButtons(),this.opacityDamper=new rn,this.goalOpacity=ci.opacity}createPanel(){const e=this.createPanelShape(),t=new Hf(e),n=new fn({color:ci.color,opacity:ci.opacity,transparent:!0});this.panelMesh=new at(t,n),this.panelMesh.name="MenuPanel",this.add(this.panelMesh)}createButtons(){this.exitButton=this.createButton("close"),this.exitButton.name="ExitButton",this.exitButton.position.set(Ga.spacing/2,0,Ga.zOffset),this.add(this.exitButton),this.toggleButton=this.createButton("view-real-size"),this.toggleButton.name="ToggleButton",this.toggleButton.position.set(-.07/2,0,Ga.zOffset),this.add(this.toggleButton)}createPanelShape(){const e=new db,{width:t,height:n,cornerRadius:i}=ci;return e.moveTo(-t/2+i,-n/2),e.lineTo(t/2-i,-n/2),e.quadraticCurveTo(t/2,-n/2,t/2,-n/2+i),e.lineTo(t/2,n/2-i),e.quadraticCurveTo(t/2,n/2,t/2-i,n/2),e.lineTo(-t/2+i,n/2),e.quadraticCurveTo(-t/2,n/2,-t/2,n/2-i),e.lineTo(-t/2,-n/2+i),e.quadraticCurveTo(-t/2,-n/2,-t/2+i,-n/2),e}preRenderIcons(){[{key:"close",svg:Jg},{key:"view-real-size",svg:Zg},{key:"replay",svg:em}].forEach(({key:t,svg:n})=>{ki.iconTextures.has(t)||this.createTextureFromSvg(n,t)})}createTextureFromSvg(e,t){const n=document.createElement("canvas");n.width=Ha.canvasSize,n.height=Ha.canvasSize;const i=n.getContext("2d"),s=new Image,a=new Blob([e],{type:"image/svg+xml"}),o=URL.createObjectURL(a);s.onload=()=>{i.drawImage(s,0,0,Ha.canvasSize,Ha.canvasSize);const c=new Nl(n);c.needsUpdate=!0,c.minFilter=Ha.filter,ki.iconTextures.set(t,c),URL.revokeObjectURL(o)},s.src=o}createButton(e){const t=new fn({transparent:!0}),n=new Hn(Ga.size,Ga.size),i=new at(n,t),s=ki.iconTextures.get(e);if(s)i.material.map=s,i.material.needsUpdate=!0;else{this.createTextureFromSvg(e==="close"?Jg:e==="view-real-size"?Zg:em,e);const a=()=>{const o=ki.iconTextures.get(e);o?(i.material.map=o,i.material.needsUpdate=!0):setTimeout(a,10)};a()}return i}exitButtonControllerIntersection(e,t){return e.hitFromController(t,this.exitButton)}scaleModeButtonControllerIntersection(e,t){return e.hitFromController(t,this.toggleButton)}handleScaleToggle(e,t,n,i){if(!e)return null;this.isActualSize=!this.isActualSize;const s=this.isActualSize?"replay":"view-real-size";this.updateScaleModeButtonLabel(s);const a=this.isActualSize?1:t;return Math.max(n,Math.min(i,a))}updateScaleModeButtonLabel(e){const t=ki.iconTextures.get(e);t&&(this.toggleButton.material.map=t,this.toggleButton.material.needsUpdate=!0)}updatePosition(e,t){if(!t)return;const n=new R;t.getWorldPosition(n);const i=t.getSize(),s=Math.min(i.x,i.z),a=-.2,o=.9,c=Math.max(.5,Math.min(2,s/1)),l=a*c,h=o*c,u=new R().copy(e.position).sub(n);u.y=0,u.normalize();const d=new R().copy(n).add(new R(0,l,0)).add(u.multiplyScalar(h));this.position.copy(d);const f=e.position.distanceTo(d),p=Math.max(ci.minDistance,Math.min(ci.maxDistance,f)),m=ci.baseScale+(p-ci.minDistance)*ci.distanceScaleFactor;this.scale.set(m,m,m),this.lookAt(e.position)}set show(e){this.goalOpacity=e?ci.opacity:0}updateOpacity(e){const n=this.panelMesh.material.opacity,i=this.opacityDamper.update(n,this.goalOpacity,e,1);this.traverse(s=>{if(s instanceof at){const a=s.material;a.transparent&&(a.opacity=i)}}),this.visible=i>0}dispose(){var e;this.children.forEach(t=>{t instanceof at&&(t.geometry&&t.geometry.dispose(),(Array.isArray(t.material)?t.material:[t.material]).forEach(i=>{i&&("map"in i&&i.map instanceof Nl&&i.map.dispose(),i.dispose())}))}),(e=this.parent)===null||e===void 0||e.remove(this)}}ki.iconTextures=new Map;const xR=30,kc=.8,tm=1.5,ER=20,_R=.2,vR=.25,yR=10,Bs=150,nm=5,SR=new R(0,1,0),CR=.3,MR=1.5,IR=15,im=.3,Cu=.01,wR=.15,TR=70,Mu=.001,RR=.2,Qi={NOT_PRESENTING:"not-presenting",SESSION_STARTED:"session-started",OBJECT_PLACED:"object-placed",FAILED:"failed"},tf={TRACKING:"tracking",NOT_TRACKING:"not-tracking"},za=new R,Iu=new pn,BR=new Oe,DR=new R,LR=new Jt(45,1,.1,100),sm=new on().setFromPoints([new R(0,0,0),new R(0,0,-1)]),$t={SCREEN_SPACE:"screen-space",WORLD_SPACE:"world-space"};class PR extends ii{isWorldSpaceReady(){return this.xrMode===$t.WORLD_SPACE&&this.worldSpaceInitialPlacementDone}constructor(e){super(),this.renderer=e,this.currentSession=null,this.placeOnWall=!1,this.placementBox=null,this.menuPanel=null,this.lastTick=null,this.turntableRotation=null,this.oldShadowIntensity=null,this.frame=null,this.initialHitSource=null,this.transientHitTestSource=null,this.inputSource=null,this._presentedScene=null,this.resolveCleanup=null,this.exitWebXRButtonContainer=null,this.overlay=null,this.xrLight=null,this.xrMode=null,this.xrController1=null,this.xrController2=null,this.selectedXRController=null,this.tracking=!0,this.frames=0,this.initialized=!1,this.oldTarget=new R,this.placementComplete=!1,this.isTranslating=!1,this.isRotating=!1,this.isTwoHandInteraction=!1,this.lastDragPosition=new R,this.deltaRotation=new pn,this.scaleLine=new Lo(sm),this.firstRatio=0,this.lastAngle=0,this.goalPosition=new R,this.goalYaw=0,this.goalScale=1,this.xDamper=new rn,this.yDamper=new rn,this.zDamper=new rn,this.yawDamper=new rn,this.pitchDamper=new rn,this.rollDamper=new rn,this.scaleDamper=new rn,this.wasTwoFingering=!1,this.worldSpaceInitialPlacementDone=!1,this.initialModelScale=1,this.minScale=1,this.maxScale=1,this.onExitWebXRButtonContainerClick=()=>this.stopPresenting(),this.onControllerSelectStart=t=>{var n,i,s;const a=this.presentedScene,o=t.target,c=this.menuPanel;if(this.menuPanel.exitButtonControllerIntersection(a,o)!=null){(n=this.menuPanel)===null||n===void 0||n.dispose(),this.stopPresenting();return}if(this.menuPanel.scaleModeButtonControllerIntersection(a,o)!=null){const d=this.menuPanel.handleScaleToggle(this.worldSpaceInitialPlacementDone,this.initialModelScale,this.minScale,this.maxScale);d!==null&&(this.goalScale=d);return}c&&(c.show=!1);const u=this.placementBox.controllerIntersection(a,o);if(u!=null){const f=new dn().setFromObject(a.scenePivot).min.y+RR;if(u.point.y<=f)this.selectedXRController!=null?(this.selectedXRController.userData.line.visible=!1,a.canScale&&this.isWorldSpaceReady()&&(this.isTwoHandInteraction=!0,this.firstRatio=this.controllerSeparation()/a.scenePivot.scale.x,this.scaleLine.visible=!0)):o.attach(a.scenePivot),this.selectedXRController=o,a.setShadowIntensity(.01);else if(o==this.xrController1?this.xrController1.userData.isSelected=!0:o==this.xrController2&&(this.xrController2.userData.isSelected=!0),!((i=this.xrController1)===null||i===void 0)&&i.userData.isSelected&&(!((s=this.xrController2)===null||s===void 0)&&s.userData.isSelected))a.canScale&&this.isWorldSpaceReady()&&(this.isTwoHandInteraction=!0,this.firstRatio=this.controllerSeparation()/a.scenePivot.scale.x,this.scaleLine.visible=!0);else{const m=o===this.xrController1?this.xrController2:this.xrController1;o.userData.initialX=o.position.x,m.userData.turning=!1,o.userData.turning=!0,o.userData.line.visible=!1}}},this.onControllerSelectEnd=t=>{const n=t.target;if(n.userData.turning=!1,n.userData.line.visible=!0,this.isTwoHandInteraction=!1,this.scaleLine.visible=!1,n==this.xrController1?this.xrController1.userData.isSelected=!1:n==this.xrController2&&(this.xrController2.userData.isSelected=!1),this.selectedXRController!=null&&this.selectedXRController!=n)return;const i=this.presentedScene;i.attach(i.scenePivot),this.selectedXRController=null,this.goalYaw=Math.atan2(i.scenePivot.matrix.elements[8],i.scenePivot.matrix.elements[10]),this.goalPosition.x=i.scenePivot.position.x,this.goalPosition.z=i.scenePivot.position.z,this.isWorldSpaceReady()&&(this.goalPosition.y=i.scenePivot.position.y);const s=this.menuPanel;s.show=!0},this.onUpdateScene=()=>{this.placementBox!=null&&this.isPresenting&&(this.placementBox.updateFromModelChanges(),this.placementBox.setScreenSpaceMode(this.xrMode===$t.SCREEN_SPACE)),this.xrMode!==$t.SCREEN_SPACE&&(this.menuPanel&&(this.menuPanel.dispose(),this.menuPanel=null),this.menuPanel=new ki,this.presentedScene.add(this.menuPanel),this.menuPanel.updatePosition(this.presentedScene.getCamera(),this.placementBox))},this.onSelectStart=t=>{const n=this.transientHitTestSource;if(n==null)return;const i=this.frame.getHitTestResultsForTransientInput(n),s=this.presentedScene,a=this.placementBox;if(i.length===1){this.inputSource=t.inputSource;const{axes:o}=this.inputSource.gamepad,c=a.getHit(this.presentedScene,o[0],o[1]);a.show=!0,c!=null?(this.isTranslating=!0,this.lastDragPosition.copy(c)):this.placeOnWall===!1&&(this.isRotating=!0,this.lastAngle=o[0]*tm)}else if(i.length===2){a.show=!0,this.isTwoHandInteraction=!0;const{separation:o,angle:c}=this.fingerPolar(i);this.lastAngle=c,this.firstRatio===0&&(this.firstRatio=o/s.scenePivot.scale.x),s.canScale&&this.setScale(o);return}},this.onSelectEnd=()=>{this.isTranslating=!1,this.isRotating=!1,this.isTwoHandInteraction=!1,this.inputSource=null,this.goalPosition.y+=this.placementBox.offsetHeight*this.presentedScene.scale.x,this.placementBox.show=!1},this.onBeforeXRSelect=t=>{const n=t.composedPath();for(const i of n)if(i instanceof HTMLElement){const s=i.tagName.toLowerCase();if(s==="input"||s==="button"||s==="select"||s==="textarea"||s==="a"||i.hasAttribute("data-pointer-coalesce")||i.classList.contains("interactive")){t.preventDefault();break}}},this.threeRenderer=e.threeRenderer,this.threeRenderer.xr.enabled=!0}async resolveARSession(){qA();const e=await navigator.xr.requestSession("immersive-ar",{requiredFeatures:[],optionalFeatures:["hit-test","dom-overlay","light-estimation"],domOverlay:this.overlay?{root:this.overlay}:void 0});return this.threeRenderer.xr.setReferenceSpaceType("local"),await this.threeRenderer.xr.setSession(e),this.threeRenderer.xr.cameraAutoUpdate=!1,e}get presentedScene(){return this._presentedScene}async supportsPresentation(){try{return qA(),await navigator.xr.isSessionSupported("immersive-ar")}catch(e){return console.warn("Request to present in WebXR denied:"),console.warn(e),console.warn("Falling back to next ar-mode"),!1}}async present(e,t=!1){this.isPresenting&&console.warn("Cannot present while a model is already presenting");let n=new Promise((l,h)=>{requestAnimationFrame(()=>l())});e.setHotspotsVisibility(!1),e.queueRender(),await n,this._presentedScene=e,this.overlay=e.element.shadowRoot.querySelector("div.default"),this.overlay!=null&&this.overlay.addEventListener("beforexrselect",this.onBeforeXRSelect),t===!0&&(this.xrLight=new P1(this.threeRenderer),this.xrLight.addEventListener("estimationstart",()=>{if(!this.isPresenting||this.xrLight==null)return;const l=this.presentedScene;l.add(this.xrLight),l.environment=this.xrLight.environment}));const i=await this.resolveARSession();i.addEventListener("end",()=>{this.postSessionCleanup()},{once:!0});const s=e.element.shadowRoot.querySelector(".slot.exit-webxr-ar-button");s.classList.add("enabled"),s.addEventListener("click",this.onExitWebXRButtonContainerClick),this.exitWebXRButtonContainer=s;const a=await i.requestReferenceSpace("viewer");this.xrMode=i.interactionMode,this.tracking=!0,this.frames=0,this.initialized=!1,this.turntableRotation=e.yaw,this.goalYaw=e.yaw,this.goalScale=1,e.setBackground(null),this.oldShadowIntensity=e.shadowIntensity,e.setShadowIntensity(.01),this.oldTarget.copy(e.getTarget()),e.element.addEventListener("load",this.onUpdateScene);const o=ER*Math.PI/180,c=this.placeOnWall===!0?void 0:new XRRay(new DOMPoint(0,0,0),{x:0,y:-Math.sin(o),z:-Math.cos(o)});i.requestHitTestSource({space:a,offsetRay:c}).then(l=>{this.initialHitSource=l}),this.xrMode!==$t.SCREEN_SPACE&&(this.setupXRControllers(),this.xDamper.setDecayTime(Bs),this.yDamper.setDecayTime(Bs),this.zDamper.setDecayTime(Bs),this.yawDamper.setDecayTime(Bs),this.pitchDamper.setDecayTime(Bs),this.rollDamper.setDecayTime(Bs),this.scaleDamper.setDecayTime(Bs)),this.currentSession=i,this.placementBox=new N1(e,this.placeOnWall?"back":"bottom"),this.placementBox&&this.placementBox.setScreenSpaceMode(this.xrMode===$t.SCREEN_SPACE),this.placementComplete=!1,this.xrMode!==$t.SCREEN_SPACE&&(this.menuPanel=new ki,e.add(this.menuPanel),this.menuPanel.updatePosition(e.getCamera(),this.placementBox)),this.lastTick=performance.now(),this.dispatchEvent({type:"status",status:Qi.SESSION_STARTED})}setupXRControllerLine(e){if(!e.userData.line){const t=new Lo(sm);t.name="line",t.scale.z=nm,e.userData.turning=!1,e.userData.line=t,e.add(t)}}setupController(e){this.setupXRControllerLine(e),e.addEventListener("selectstart",this.onControllerSelectStart),e.addEventListener("selectend",this.onControllerSelectEnd)}setupXRControllers(){this.xrController1=this.threeRenderer.xr.getController(0),this.xrController2=this.threeRenderer.xr.getController(1),this.setupController(this.xrController1),this.setupController(this.xrController2),this.scaleLine.name="scale line",this.scaleLine.visible=!1,this.xrController1.add(this.scaleLine);const e=this.presentedScene;e.add(this.xrController1),e.add(this.xrController2)}hover(e){if(this.xrMode===$t.SCREEN_SPACE||this.selectedXRController==e)return!1;const t=this.presentedScene,n=this.placementBox.controllerIntersection(t,e);return e.userData.line.scale.z=n==null?nm:n.distance,n!=null}controllerSeparation(){return this.xrController1.position.distanceTo(this.xrController2.position)}async stopPresenting(){if(!this.isPresenting)return;const e=new Promise(t=>{this.resolveCleanup=t});try{await this.currentSession.end(),await e}catch(t){console.warn("Error while trying to end WebXR AR session"),console.warn(t),this.postSessionCleanup()}}get isPresenting(){return this.presentedScene!=null}get target(){return this.oldTarget}updateTarget(){const e=this.presentedScene;if(e!=null){const t=e.getTarget();this.oldTarget.copy(t),this.placeOnWall?t.z=e.boundingBox.min.z:t.y=e.boundingBox.min.y,e.setTarget(t.x,t.y,t.z)}}cleanupXRController(e){e.userData.turning=!1,e.userData.line.visible=!0,e.removeEventListener("selectstart",this.onControllerSelectStart),e.removeEventListener("selectend",this.onControllerSelectEnd),e.removeFromParent()}postSessionCleanup(){const e=this.currentSession;e!=null&&(e.removeEventListener("selectstart",this.onSelectStart),e.removeEventListener("selectend",this.onSelectEnd),this.currentSession=null);const t=this.presentedScene;if(this._presentedScene=null,t!=null){const{element:a}=t;this.xrLight!=null&&(t.remove(this.xrLight),this.xrLight.dispose(),this.xrLight=null),this.menuPanel!=null&&(this.menuPanel.dispose(),this.menuPanel=null),t.add(t.scenePivot),t.scenePivot.quaternion.set(0,0,0,1),t.scenePivot.position.set(0,0,0),t.scenePivot.scale.set(1,1,1),t.setShadowOffset(0);const o=this.turntableRotation;o!=null&&(t.yaw=o);const c=this.oldShadowIntensity;c!=null&&t.setShadowIntensity(c),t.setEnvironmentAndSkybox(a[ro],a[ao]);const l=this.oldTarget;t.setTarget(l.x,l.y,l.z),t.xrCamera=null,t.element.removeEventListener("load",this.onUpdateScene),t.orientHotspots(0);const{width:h,height:u}=a.getBoundingClientRect();t.setSize(h,u),requestAnimationFrame(()=>{t.element.dispatchEvent(new CustomEvent("camera-change",{detail:{source:Pt.NONE}}))})}this.renderer.height=0;const n=this.exitWebXRButtonContainer;n!=null&&(n.classList.remove("enabled"),n.removeEventListener("click",this.onExitWebXRButtonContainerClick),this.exitWebXRButtonContainer=null);const i=this.transientHitTestSource;i!=null&&(i.cancel(),this.transientHitTestSource=null);const s=this.initialHitSource;s!=null&&(s.cancel(),this.initialHitSource=null),this.placementBox!=null&&(this.placementBox.dispose(),this.placementBox=null),this.xrMode!==$t.SCREEN_SPACE&&(this.xrController1!=null&&(this.cleanupXRController(this.xrController1),this.xrController1=null),this.xrController2!=null&&(this.cleanupXRController(this.xrController2),this.xrController2=null),this.selectedXRController=null,this.scaleLine.visible=!1),this.isTranslating=!1,this.isRotating=!1,this.isTwoHandInteraction=!1,this.lastTick=null,this.turntableRotation=null,this.oldShadowIntensity=null,this.frame=null,this.inputSource=null,this.overlay!=null&&(this.overlay.removeEventListener("beforexrselect",this.onBeforeXRSelect),this.overlay=null),this.worldSpaceInitialPlacementDone=!1,this.resolveCleanup!=null&&this.resolveCleanup(),this.dispatchEvent({type:"status",status:Qi.NOT_PRESENTING})}updateView(e){const t=this.presentedScene,n=this.threeRenderer.xr;n.updateCamera(LR),t.xrCamera=n.getCamera();const{elements:i}=t.getCamera().matrixWorld;if(t.orientHotspots(Math.atan2(i[1],i[5])),this.initialized||(this.placeInitially(),this.initialized=!0),e.requestViewportScale&&e.recommendedViewportScale){const a=e.recommendedViewportScale;e.requestViewportScale(Math.max(a,vR))}const s=n.getBaseLayer();if(s!=null){const a=s instanceof XRWebGLLayer?s.getViewport(e):n.getBinding().getViewSubImage(s,e).viewport;this.threeRenderer.setViewport(a.x,a.y,a.width,a.height)}}placeInitially(){const e=this.presentedScene,{scenePivot:t,element:n}=e,{position:i}=t,s=e.getCamera(),{width:a,height:o}=this.overlay.getBoundingClientRect();e.setSize(a,o),s.projectionMatrixInverse.copy(s.projectionMatrix).invert();const{theta:c}=n.getCameraOrbit(),l=s.getWorldDirection(za);if(e.yaw=Math.atan2(-l.x,-l.z)-c,this.goalYaw=e.yaw,this.xrMode===$t.WORLD_SPACE&&!this.worldSpaceInitialPlacementDone){const{position:h,scale:u}=this.calculateWorldSpaceOptimalPlacement(e,s);this.goalPosition.copy(h),this.goalScale=u,this.initialModelScale=u,i.copy(h),t.scale.set(u,u,u),this.worldSpaceInitialPlacementDone=!0,this.calculateWorldSpaceScaleLimits(e),this.enableWorldSpaceUserInteraction()}else if(this.xrMode===$t.SCREEN_SPACE){const h=Math.max(1,2*e.boundingSphere.radius);i.copy(s.position).add(l.multiplyScalar(h)),this.updateTarget();const u=e.getTarget();i.add(u).sub(this.oldTarget),this.goalPosition.copy(i)}if(e.setHotspotsVisibility(!0),this.xrMode===$t.SCREEN_SPACE){const{session:h}=this.frame;h.addEventListener("selectstart",this.onSelectStart),h.addEventListener("selectend",this.onSelectEnd),h.requestHitTestSourceForTransientInput({profile:"generic-touchscreen"}).then(u=>{this.transientHitTestSource=u})}}getTouchLocation(){const{axes:e}=this.inputSource.gamepad;let t=this.placementBox.getExpandedHit(this.presentedScene,e[0],e[1]);return t!=null&&(za.copy(t).sub(this.presentedScene.getCamera().position),za.length()>yR)?null:t}getHitPoint(e){const t=this.threeRenderer.xr.getReferenceSpace(),n=e.getPose(t);if(n==null)return null;const i=BR.fromArray(n.transform.matrix);return this.placeOnWall===!0&&(this.goalYaw=Math.atan2(i.elements[4],i.elements[6])),i.elements[5]>.75!==this.placeOnWall?DR.setFromMatrixPosition(i):null}moveToFloor(e){if(this.xrMode===$t.WORLD_SPACE&&!this.worldSpaceInitialPlacementDone){this.placementBox.show=!1,this.dispatchEvent({type:"status",status:Qi.OBJECT_PLACED});return}const t=this.initialHitSource;if(t==null)return;const n=e.getHitTestResults(t);if(n.length==0)return;const i=n[0],s=this.getHitPoint(i);s!=null&&(this.placementBox.show=!0,this.isTranslating||(this.placeOnWall?this.goalPosition.copy(s):this.goalPosition.y=s.y),t.cancel(),this.initialHitSource=null,this.dispatchEvent({type:"status",status:Qi.OBJECT_PLACED}))}fingerPolar(e){const t=e[0].inputSource.gamepad.axes,n=e[1].inputSource.gamepad.axes,i=n[0]-t[0],s=n[1]-t[1],a=Math.atan2(s,i);let o=this.lastAngle-a;return o>Math.PI?o-=2*Math.PI:o<-Math.PI&&(o+=2*Math.PI),{separation:Math.sqrt(i*i+s*s),deltaYaw:o,angle:a}}setScale(e){let t=e/this.firstRatio;t=Math.abs(t-1)<_R?1:t,this.isWorldSpaceReady()&&(t=Math.max(this.minScale,Math.min(this.maxScale,t))),this.goalScale=t}processInput(e){const t=this.transientHitTestSource;if(t==null)return;const n=e.getHitTestResultsForTransientInput(t),i=this.presentedScene,s=i.scenePivot.scale.x;if(n.length===2){if(!this.wasTwoFingering){const{separation:l,angle:h}=this.fingerPolar(n);this.firstRatio=l/s,this.lastAngle=h,this.wasTwoFingering=!0,this.isTwoHandInteraction=!0;return}const{separation:a,deltaYaw:o,angle:c}=this.fingerPolar(n);this.goalYaw+=o,this.lastAngle=c,i.canScale&&this.setScale(a),this.isTwoHandInteraction=!0;return}else this.wasTwoFingering&&(this.wasTwoFingering=!1,this.isTwoHandInteraction=!1,this.firstRatio=0);if(!(!this.isTranslating&&!this.isTwoHandInteraction&&!this.isRotating))if(this.isRotating){const a=this.inputSource.gamepad.axes[0]*tm;this.goalYaw+=a-this.lastAngle,this.lastAngle=a}else this.isTranslating&&n.forEach(a=>{if(a.inputSource!==this.inputSource)return;let o=null;if(a.results.length>0&&(o=this.getHitPoint(a.results[0])),o==null&&(o=this.getTouchLocation()),o!=null){if(this.goalPosition.sub(this.lastDragPosition),this.isWorldSpaceReady())console.log("[processInput] Setting goalPosition.y to hit.y:",o.y),this.goalPosition.add(o);else if(this.placeOnWall===!1){const c=o.y-this.lastDragPosition.y;if(c<0){this.placementBox.offsetHeight=c/s,this.presentedScene.setShadowOffset(c);const l=za.copy(i.getCamera().position),h=-c/(l.y-o.y);l.multiplyScalar(h),o.multiplyScalar(1-h).add(l)}this.goalPosition.add(o)}else this.goalPosition.add(o);this.lastDragPosition.copy(o)}})}applyXRControllerRotation(e,t){if(!e.userData.turning)return;const n=(e.position.x-e.userData.initialX)*CR;this.deltaRotation.setFromAxisAngle(SR,n),t.quaternion.multiplyQuaternions(this.deltaRotation,t.quaternion)}handleScalingInXR(e,t){if(this.xrMode===$t.WORLD_SPACE&&!this.worldSpaceInitialPlacementDone)return;if(this.xrController1&&this.xrController2&&this.isTwoHandInteraction){const i=this.controllerSeparation();this.setScale(i),this.scaleLine.scale.z=-i,this.scaleLine.lookAt(this.xrController2.position)}const n=e.scenePivot.scale.x;if(this.goalScale!==n){const i=this.scaleDamper.update(n,this.goalScale,t,1);e.scenePivot.scale.set(i,i,i)}}updatePivotPosition(e,t){const{scenePivot:n}=e,i=this.placementBox,s=e.boundingSphere.radius,a=this.goalPosition,o=n.position;let c=Pt.NONE;if(!a.equals(o)){c=Pt.USER_INTERACTION;let{x:l,y:h,z:u}=o;if(l=this.xDamper.update(l,a.x,t,s),h=this.yDamper.update(h,a.y,t,s),u=this.zDamper.update(u,a.z,t,s),o.set(l,h,u),this.xrMode===$t.SCREEN_SPACE&&!this.isTranslating){const d=a.y-h;this.placementComplete&&this.placeOnWall===!1?(i.offsetHeight=d/e.scenePivot.scale.x,e.setShadowOffset(d)):d===0&&(this.placementComplete=!0,i.show=!1,e.setShadowIntensity(kc))}this.xrMode!==$t.SCREEN_SPACE&&a.equals(o)&&e.setShadowIntensity(kc),this.isWorldSpaceReady()&&e.setShadowIntensity(kc)}if(this.xrMode===$t.WORLD_SPACE&&!this.worldSpaceInitialPlacementDone&&this.goalScale!==n.scale.x){const l=this.scaleDamper.update(n.scale.x,this.goalScale,t,1);n.scale.set(l,l,l)}return e.updateTarget(t),c}updateYaw(e,t){Iu.setFromAxisAngle(za.set(0,1,0),this.goalYaw);const n=e.scenePivot.quaternion.angleTo(Iu),i=n-this.yawDamper.update(n,0,t,Math.PI);e.scenePivot.quaternion.rotateTowards(Iu,i)}updateMenuPanel(e,t,n){this.menuPanel&&(this.menuPanel.updateOpacity(n),this.menuPanel.updatePosition(e.getCamera(),t))}applyXRInputToScene(e){const t=this.presentedScene,n=t.scenePivot,i=this.placementBox;if(this.updatePlacementBoxOpacity(i,e),this.updateTwoHandInteractionState(),this.applyXRControllerRotations(n),this.handleScalingInXR(t,e),n.parent!==t){this.updateMenuPanel(t,i,e);return}const s=this.updatePivotPosition(t,e);this.updateYaw(t,e),this.dispatchCameraChangeEvent(t,s),this.updateMenuPanel(t,i,e)}updatePlacementBoxOpacity(e,t){const n=this.presentedScene.getCamera();e.update(t,n.position);const i=this.hover(this.xrController1),s=this.hover(this.xrController2),a=(i||s)&&!this.isTwoHandInteraction;e.setInteractionState(this.isTranslating||this.isRotating,a)}updateTwoHandInteractionState(){var e,t;const n=((e=this.xrController1)===null||e===void 0?void 0:e.userData.isSelected)&&((t=this.xrController2)===null||t===void 0?void 0:t.userData.isSelected);this.isTwoHandInteraction=!!n}applyXRControllerRotations(e){this.isTwoHandInteraction||(this.xrController1&&this.applyXRControllerRotation(this.xrController1,e),this.xrController2&&this.applyXRControllerRotation(this.xrController2,e))}dispatchCameraChangeEvent(e,t){e.element.dispatchEvent(new CustomEvent("camera-change",{detail:{source:t}}))}updateXRControllerHover(){const e=this.hover(this.xrController1),t=this.hover(this.xrController2),n=(e||t)&&!this.isTwoHandInteraction;this.placementBox&&(this.placementBox.setInteractionState(this.isTranslating||this.isRotating,n),this.placementBox.show=n)}enableWorldSpaceUserInteraction(){this.placementBox&&(this.placementBox.show=!0),this.presentedScene&&this.presentedScene.setShadowIntensity(kc)}handleFirstView(e,t){(this.xrMode!==$t.WORLD_SPACE||!this.worldSpaceInitialPlacementDone)&&this.moveToFloor(e),this.processInput(e);const n=t-this.lastTick;this.applyXRInputToScene(n),this.renderer.preRender(this.presentedScene,t,n),this.lastTick=t,this.presentedScene.renderShadow(this.threeRenderer)}onWebXRFrame(e,t){this.xrMode!==$t.SCREEN_SPACE&&this.updateXRControllerHover(),this.frame=t,++this.frames;const n=this.threeRenderer.xr.getReferenceSpace(),i=t.getViewerPose(n);i==null&&this.tracking===!0&&this.frames>xR&&(this.tracking=!1,this.dispatchEvent({type:"tracking",status:tf.NOT_TRACKING}));const s=this.presentedScene;if(i==null||s==null||!s.element.loaded){this.threeRenderer.clear();return}this.tracking===!1&&(this.tracking=!0,this.dispatchEvent({type:"tracking",status:tf.TRACKING}));let a=!0;for(const o of i.views)this.updateView(o),a&&(this.handleFirstView(t,e),a=!1),this.threeRenderer.render(s,s.getCamera())}calculateWorldSpaceOptimalPlacement(e,t){const n=e.boundingBox,i={x:(n.max.x-n.min.x)/2,y:(n.max.y-n.min.y)/2,z:(n.max.z-n.min.z)/2},s=wR,a=Math.max(MR+s,2*Math.max(i.x,i.z)+s),o=IR*Math.PI/180,c=new R(0,-a*Math.sin(o),-a*Math.cos(o)),l=t.matrixWorld,h=c.clone().applyMatrix4(l),u=Math.max(i.x,i.z)+s,d=i.y,f=a*im,m=a*im/Math.max(d,Cu),A=f/Math.max(u,Cu),g=Math.min(m,A);return{position:h.clone().sub(new R(0,g*i.y,0)),scale:g}}calculateWorldSpaceScaleLimits(e){const t=e.size,n=Math.max(t.x,t.y,t.z),i=Math.max(Math.min(t.x,t.y,t.z),Mu),s=Cu/Math.max(n,Mu),a=TR/Math.max(i,Mu);this.minScale=Math.min(s,a,this.goalScale),this.maxScale=Math.max(s,a,this.goalScale)}}const rm=Symbol("prepared"),Ol=Symbol("prepare"),li=Symbol("preparedGLTF"),kl=Symbol("clone");class FR{static prepare(e){if(e.scene==null)throw new Error("Model does not have a scene");if(e[rm])return e;const t=this[Ol](e);return t[rm]=!0,t}static[Ol](e){const{scene:t}=e,n=[t];return Object.assign(Object.assign({},e),{scene:t,scenes:n})}get parser(){return this[li].parser}get animations(){return this[li].animations}get scene(){return this[li].scene}get scenes(){return this[li].scenes}get cameras(){return this[li].cameras}get asset(){return this[li].asset}get userData(){return this[li].userData}constructor(e){this[li]=e}clone(){const e=this.constructor,t=this[kl]();return new e(t)}dispose(){this.scenes.forEach(e=>{e.traverse(t=>{const n=t;if(!n.material)return;(Array.isArray(n.material)?n.material:[n.material]).forEach(s=>{for(const a in s){const o=s[a];if(o instanceof Rt){const c=o.source.data;c.close!=null&&c.close(),o.dispose()}}s.dispose()}),n.geometry.dispose()})})}[kl](){const e=this[li],t=Ub(this.scene);NR(t,this.scene);const n=[t],i=e.userData?Object.assign({},e.userData):{};return Object.assign(Object.assign({},e),{scene:t,scenes:n,userData:i})}}const NR=(r,e)=>{qx(r,e,(t,n)=>{n.userData.variantMaterials!==void 0&&(t.userData.variantMaterials=new Map(n.userData.variantMaterials)),n.userData.variantData!==void 0&&(t.userData.variantData=n.userData.variantData),n.userData.originalMaterial!==void 0&&(t.userData.originalMaterial=n.userData.originalMaterial)})},qx=(r,e,t)=>{t(r,e);for(let n=0;n{const u=t.threeObjectMap.get(l);if(u!=null){for(const d in u)if(d!=null&&d!=="primitives"){const f=d,p=u[f],m=s[f][p],A=a.get(h)||{};A[f]=p,a.set(h,A);const g=o.get(m)||new Set;g.add(h),o.set(m,g)}}});return new ko(e,s,a,o)}static[hm](e,t,n){const i=(s,a)=>{if(n(s,a),s.isObject3D){const o=s,c=a;if(o.material)if(Array.isArray(o.material))for(let l=0;l{s.renderOrder=1e3,s.frustumCulled=!1,s.name||(s.name=s.uuid);const a=s;if(a.material){const{geometry:o}=a;a.castShadow=!0,a.isSkinnedMesh&&(o.boundingSphere=i,o.boundingBox=null);const c=a.material;if(c.isMeshBasicMaterial===!0&&(c.toneMapped=!1),c.shadowSide=ei,c.aoMap){const{gltf:l,threeObjectMap:h}=t[Va],u=h.get(c);if(l.materials!=null&&u!=null&&u.materials!=null){const d=l.materials[u.materials];d.occlusionTexture&&d.occlusionTexture.texCoord===0&&o.attributes.uv!=null&&o.setAttribute("uv2",o.attributes.uv)}}}}),t}get correlatedSceneGraph(){return this[li][Va]}[kl](){const e=super[kl](),t=new Map;return e.scene.traverse(n=>{const i=n;if(i.material){const a=i.material;if(a!=null){if(t.has(a.uuid)){i.material=t.get(a.uuid);return}i.material=a.clone(),t.set(a.uuid,i.material)}}const s=n;s.target!==void 0&&s.add(s.target)}),e[Va]=ko.from(e,this.correlatedSceneGraph),e}}const jx=(r,e,t)=>{let n;switch(r){case Le:n=new Uint8ClampedArray(e*t*4);break;case yt:n=new Uint16Array(e*t*4);break;case ni:n=new Uint32Array(e*t*4);break;case Mf:n=new Int8Array(e*t*4);break;case If:n=new Int16Array(e*t*4);break;case $l:n=new Int32Array(e*t*4);break;case Nt:n=new Float32Array(e*t*4);break;default:throw new Error("Unsupported data type")}return n};let Qc;const OR=(r,e,t,n)=>{if(Qc!==void 0)return Qc;const i=new yn(1,1,n);e.setRenderTarget(i);const s=new at(new Hn,new fn({color:16777215}));e.render(s,t),e.setRenderTarget(null);const a=jx(r,i.width,i.height);return e.readRenderTargetPixels(i,0,0,i.width,i.height,a),i.dispose(),s.geometry.dispose(),s.material.dispose(),Qc=a[0]!==0,Qc};class Yf{_renderer;_rendererIsDisposable=!1;_material;_scene;_camera;_quad;_renderTarget;_width;_height;_type;_colorSpace;_supportsReadPixels=!0;constructor(e){this._width=e.width,this._height=e.height,this._type=e.type,this._colorSpace=e.colorSpace;const t={format:Tt,depthBuffer:!1,stencilBuffer:!1,type:this._type,colorSpace:this._colorSpace,anisotropy:e.renderTargetOptions?.anisotropy!==void 0?e.renderTargetOptions?.anisotropy:1,generateMipmaps:e.renderTargetOptions?.generateMipmaps!==void 0?e.renderTargetOptions?.generateMipmaps:!1,magFilter:e.renderTargetOptions?.magFilter!==void 0?e.renderTargetOptions?.magFilter:qe,minFilter:e.renderTargetOptions?.minFilter!==void 0?e.renderTargetOptions?.minFilter:qe,samples:e.renderTargetOptions?.samples!==void 0?e.renderTargetOptions?.samples:void 0,wrapS:e.renderTargetOptions?.wrapS!==void 0?e.renderTargetOptions?.wrapS:Dt,wrapT:e.renderTargetOptions?.wrapT!==void 0?e.renderTargetOptions?.wrapT:Dt};if(this._material=e.material,e.renderer?this._renderer=e.renderer:(this._renderer=Yf.instantiateRenderer(),this._rendererIsDisposable=!0),this._scene=new ms,this._camera=new rr,this._camera.position.set(0,0,10),this._camera.left=-.5,this._camera.right=.5,this._camera.top=.5,this._camera.bottom=-.5,this._camera.updateProjectionMatrix(),!OR(this._type,this._renderer,this._camera,t)){let n;this._type===yt&&(n=this._renderer.extensions.has("EXT_color_buffer_float")?Nt:void 0),n!==void 0?(console.warn(`This browser does not support reading pixels from ${this._type} RenderTargets, switching to ${Nt}`),this._type=n):(this._supportsReadPixels=!1,console.warn("This browser dos not support toArray or toDataTexture, calls to those methods will result in an error thrown"))}this._quad=new at(new Hn,this._material),this._quad.geometry.computeBoundingBox(),this._scene.add(this._quad),this._renderTarget=new yn(this.width,this.height,t),this._renderTarget.texture.mapping=e.renderTargetOptions?.mapping!==void 0?e.renderTargetOptions?.mapping:na}static instantiateRenderer(){const e=new Xf;return e.setSize(128,128),e}render=()=>{this._renderer.setRenderTarget(this._renderTarget);try{this._renderer.render(this._scene,this._camera)}catch(e){throw this._renderer.setRenderTarget(null),e}this._renderer.setRenderTarget(null)};toArray(){if(!this._supportsReadPixels)throw new Error("Can't read pixels in this browser");const e=jx(this._type,this._width,this._height);return this._renderer.readRenderTargetPixels(this._renderTarget,0,0,this._width,this._height,e),e}toDataTexture(e){const t=new ma(this.toArray(),this.width,this.height,Tt,this._type,e?.mapping||na,e?.wrapS||Dt,e?.wrapT||Dt,e?.magFilter||qe,e?.minFilter||qe,e?.anisotropy||1,Ct);return t.generateMipmaps=e?.generateMipmaps!==void 0?e?.generateMipmaps:!1,t}disposeOnDemandRenderer(){this._renderer.setRenderTarget(null),this._rendererIsDisposable&&(this._renderer.dispose(),this._renderer.forceContextLoss())}dispose(e){this.disposeOnDemandRenderer(),e&&this.renderTarget.dispose(),this.material instanceof gn&&Object.values(this.material.uniforms).forEach(t=>{t.value instanceof Rt&&t.value.dispose()}),Object.values(this.material).forEach(t=>{t instanceof Rt&&t.dispose()}),this.material.dispose(),this._quad.geometry.dispose()}get width(){return this._width}set width(e){this._width=e,this._renderTarget.setSize(this._width,this._height)}get height(){return this._height}set height(e){this._height=e,this._renderTarget.setSize(this._width,this._height)}get renderer(){return this._renderer}get renderTarget(){return this._renderTarget}set renderTarget(e){this._renderTarget=e,this._width=e.width,this._height=e.height}get material(){return this._material}get type(){return this._type}get colorSpace(){return this._colorSpace}}class Xx extends Error{}class Kx extends Error{}const Wa=(r,e,t)=>{const n=new RegExp(`${e}="([^"]*)"`,"i").exec(r);if(n)return n[1];const i=new RegExp(`<${e}[^>]*>([\\s\\S]*?)`,"i").exec(r);if(i){const s=i[1].match(/([^<]*)<\/rdf:li>/g);return s&&s.length===3?s.map(a=>a.replace(/<\/?rdf:li>/g,"")):i[1].trim()}if(t!==void 0)return t;throw new Error(`Can't find ${e} in gainmap metadata`)},kR=r=>{let e;typeof TextDecoder<"u"?e=new TextDecoder().decode(r):e=r.toString();let t=e.indexOf("",t),i=e.slice(t,n+10);try{const s=Wa(i,"hdrgm:GainMapMin","0"),a=Wa(i,"hdrgm:GainMapMax"),o=Wa(i,"hdrgm:Gamma","1"),c=Wa(i,"hdrgm:OffsetSDR","0.015625"),l=Wa(i,"hdrgm:OffsetHDR","0.015625"),h=/hdrgm:HDRCapacityMin="([^"]*)"/.exec(i),u=h?h[1]:"0",d=/hdrgm:HDRCapacityMax="([^"]*)"/.exec(i);if(!d)throw new Error("Incomplete gainmap metadata");const f=d[1];return{gainMapMin:Array.isArray(s)?s.map(p=>parseFloat(p)):[parseFloat(s),parseFloat(s),parseFloat(s)],gainMapMax:Array.isArray(a)?a.map(p=>parseFloat(p)):[parseFloat(a),parseFloat(a),parseFloat(a)],gamma:Array.isArray(o)?o.map(p=>parseFloat(p)):[parseFloat(o),parseFloat(o),parseFloat(o)],offsetSdr:Array.isArray(c)?c.map(p=>parseFloat(p)):[parseFloat(c),parseFloat(c),parseFloat(c)],offsetHdr:Array.isArray(l)?l.map(p=>parseFloat(p)):[parseFloat(l),parseFloat(l),parseFloat(l)],hdrCapacityMin:parseFloat(u),hdrCapacityMax:parseFloat(f)}}catch{}t=e.indexOf("{const i=this.options.debug,s=new DataView(e.buffer);if(s.getUint16(0)!==65496){n(new Error("Not a valid jpeg"));return}const a=s.byteLength;let o=2,c=0,l;for(;o250){n(new Error(`Found no marker after ${c} loops 😵`));return}if(s.getUint8(o)!==255){n(new Error(`Not a valid marker at offset 0x${o.toString(16)}, found: 0x${s.getUint8(o).toString(16)}`));return}if(l=s.getUint8(o+1),i&&console.log(`Marker: ${l.toString(16)}`),l===226){i&&console.log("Found APP2 marker (0xffe2)");const h=o+4;if(s.getUint32(h)===1297106432){const u=h+4;let d;if(s.getUint16(u)===18761)d=!1;else if(s.getUint16(u)===19789)d=!0;else{n(new Error("No valid endianness marker found in TIFF header"));return}if(s.getUint16(u+2,!d)!==42){n(new Error("Not valid TIFF data! (no 0x002A marker)"));return}const f=s.getUint32(u+4,!d);if(f<8){n(new Error("Not valid TIFF data! (First offset less than 8)"));return}const p=u+f,m=s.getUint16(p,!d),A=p+2;let g=0;for(let v=A;v{const e=kR(r);if(!e)throw new Kx("Gain map XMP metadata not found");const n=await new QR({extractFII:!0,extractNonFII:!0}).extract(r);if(n.length!==2)throw new Xx("Gain map recovery image not found");return{sdr:new Uint8Array(await n[0].arrayBuffer()),gainMap:new Uint8Array(await n[1].arrayBuffer()),metadata:e}},fm=r=>new Promise((e,t)=>{const n=document.createElement("img");n.onload=()=>{e(n)},n.onerror=i=>{t(i)},n.src=URL.createObjectURL(r)});class HR extends Ei{_renderer;_renderTargetOptions;_internalLoadingManager;_config;constructor(e,t){super(t),this._config=e,e.renderer&&(this._renderer=e.renderer),this._internalLoadingManager=new vb}setRenderer(e){return this._renderer=e,this}setRenderTargetOptions(e){return this._renderTargetOptions=e,this}prepareQuadRenderer(){this._renderer||console.warn("WARNING: A Renderer was not passed to this Loader constructor or in setRenderer, the result of this Loader will need to be converted to a Data Texture with toDataTexture() before you can use it in your renderer.");const e=this._config.createMaterial({gainMapMax:[1,1,1],gainMapMin:[0,0,0],gamma:[1,1,1],offsetHdr:[1,1,1],offsetSdr:[1,1,1],hdrCapacityMax:1,hdrCapacityMin:0,maxDisplayBoost:1,gainMap:new Rt,sdr:new Rt});return this._config.createQuadRenderer({width:16,height:16,type:yt,colorSpace:Ct,material:e,renderer:this._renderer,renderTargetOptions:this._renderTargetOptions})}async processImages(e,t,n){const i=t?new Blob([t],{type:"image/jpeg"}):void 0,s=new Blob([e],{type:"image/jpeg"});let a,o,c=!1;if(typeof createImageBitmap>"u"){const l=await Promise.all([i?fm(i):Promise.resolve(void 0),fm(s)]);o=l[0],a=l[1],c=n==="flipY"}else{const l=await Promise.all([i?createImageBitmap(i,{imageOrientation:n||"flipY"}):Promise.resolve(void 0),createImageBitmap(s,{imageOrientation:n||"flipY"})]);o=l[0],a=l[1]}return{sdrImage:a,gainMapImage:o,needsFlip:c}}createTextures(e,t,n){const i=new Rt(t||new ImageData(2,2),na,Dt,Dt,qe,Cp,Tt,Le,1,Ct);i.flipY=n,i.needsUpdate=!0;const s=new Rt(e,na,Dt,Dt,qe,Cp,Tt,Le,1,mt);return s.flipY=n,s.needsUpdate=!0,{gainMap:i,sdr:s}}updateQuadRenderer(e,t,n,i,s){e.width=t.width,e.height=t.height,e.material.gainMap=n,e.material.sdr=i,e.material.gainMapMin=s.gainMapMin,e.material.gainMapMax=s.gainMapMax,e.material.offsetHdr=s.offsetHdr,e.material.offsetSdr=s.offsetSdr,e.material.gamma=s.gamma,e.material.hdrCapacityMin=s.hdrCapacityMin,e.material.hdrCapacityMax=s.hdrCapacityMax,e.material.maxDisplayBoost=Math.pow(2,s.hdrCapacityMax),e.material.needsUpdate=!0}}const zR=` +varying vec2 vUv; + +void main() { + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); +} +`,VR=` +// min half float value +#define HALF_FLOAT_MIN vec3( -65504, -65504, -65504 ) +// max half float value +#define HALF_FLOAT_MAX vec3( 65504, 65504, 65504 ) + +uniform sampler2D sdr; +uniform sampler2D gainMap; +uniform vec3 gamma; +uniform vec3 offsetHdr; +uniform vec3 offsetSdr; +uniform vec3 gainMapMin; +uniform vec3 gainMapMax; +uniform float weightFactor; + +varying vec2 vUv; + +void main() { + vec3 rgb = texture2D( sdr, vUv ).rgb; + vec3 recovery = texture2D( gainMap, vUv ).rgb; + vec3 logRecovery = pow( recovery, gamma ); + vec3 logBoost = gainMapMin * ( 1.0 - logRecovery ) + gainMapMax * logRecovery; + vec3 hdrColor = (rgb + offsetSdr) * exp2( logBoost * weightFactor ) - offsetHdr; + vec3 clampedHdrColor = max( HALF_FLOAT_MIN, min( HALF_FLOAT_MAX, hdrColor )); + gl_FragColor = vec4( clampedHdrColor , 1.0 ); +} +`;class WR extends gn{_maxDisplayBoost;_hdrCapacityMin;_hdrCapacityMax;constructor({gamma:e,offsetHdr:t,offsetSdr:n,gainMapMin:i,gainMapMax:s,maxDisplayBoost:a,hdrCapacityMin:o,hdrCapacityMax:c,sdr:l,gainMap:h}){super({name:"GainMapDecoderMaterial",vertexShader:zR,fragmentShader:VR,uniforms:{sdr:{value:l},gainMap:{value:h},gamma:{value:new R(1/e[0],1/e[1],1/e[2])},offsetHdr:{value:new R().fromArray(t)},offsetSdr:{value:new R().fromArray(n)},gainMapMin:{value:new R().fromArray(i)},gainMapMax:{value:new R().fromArray(s)},weightFactor:{value:(Math.log2(a)-o)/(c-o)}},blending:Jn,depthTest:!1,depthWrite:!1}),this._maxDisplayBoost=a,this._hdrCapacityMin=o,this._hdrCapacityMax=c,this.needsUpdate=!0,this.uniformsNeedUpdate=!0}get sdr(){return this.uniforms.sdr.value}set sdr(e){this.uniforms.sdr.value=e}get gainMap(){return this.uniforms.gainMap.value}set gainMap(e){this.uniforms.gainMap.value=e}get offsetHdr(){return this.uniforms.offsetHdr.value.toArray()}set offsetHdr(e){this.uniforms.offsetHdr.value.fromArray(e)}get offsetSdr(){return this.uniforms.offsetSdr.value.toArray()}set offsetSdr(e){this.uniforms.offsetSdr.value.fromArray(e)}get gainMapMin(){return this.uniforms.gainMapMin.value.toArray()}set gainMapMin(e){this.uniforms.gainMapMin.value.fromArray(e)}get gainMapMax(){return this.uniforms.gainMapMax.value.toArray()}set gainMapMax(e){this.uniforms.gainMapMax.value.fromArray(e)}get gamma(){const e=this.uniforms.gamma.value;return[1/e.x,1/e.y,1/e.z]}set gamma(e){const t=this.uniforms.gamma.value;t.x=1/e[0],t.y=1/e[1],t.z=1/e[2]}get hdrCapacityMin(){return this._hdrCapacityMin}set hdrCapacityMin(e){this._hdrCapacityMin=e,this.calculateWeight()}get hdrCapacityMax(){return this._hdrCapacityMax}set hdrCapacityMax(e){this._hdrCapacityMax=e,this.calculateWeight()}get maxDisplayBoost(){return this._maxDisplayBoost}set maxDisplayBoost(e){this._maxDisplayBoost=Math.max(1,Math.min(65504,e)),this.calculateWeight()}calculateWeight(){const e=(Math.log2(this._maxDisplayBoost)-this._hdrCapacityMin)/(this._hdrCapacityMax-this._hdrCapacityMin);this.uniforms.weightFactor.value=Math.max(0,Math.min(1,e))}}class qR extends HR{constructor(e,t){super({renderer:e,createMaterial:n=>new WR(n),createQuadRenderer:n=>new Yf(n)},t)}async render(e,t,n,i){const{sdrImage:s,gainMapImage:a,needsFlip:o}=await this.processImages(n,i,"flipY"),{gainMap:c,sdr:l}=this.createTextures(s,a,o);this.updateQuadRenderer(e,s,c,l,t),e.render()}}class jR extends qR{load(e,t,n,i){const s=this.prepareQuadRenderer(),a=new Vi(this._internalLoadingManager);return a.setResponseType("arraybuffer"),a.setRequestHeader(this.requestHeader),a.setPath(this.path),a.setWithCredentials(this.withCredentials),this.manager.itemStart(e),a.load(e,async o=>{if(typeof o=="string")throw new Error("Invalid buffer, received [string], was expecting [ArrayBuffer]");const c=new Uint8Array(o);let l,h,u;try{const d=await GR(c);l=d.sdr,h=d.gainMap,u=d.metadata}catch(d){if(d instanceof Kx||d instanceof Xx)console.warn(`Failure to reconstruct an HDR image from ${e}: Gain map metadata not found in the file, HDRJPGLoader will render the SDR jpeg`),u={gainMapMin:[0,0,0],gainMapMax:[1,1,1],gamma:[1,1,1],hdrCapacityMin:0,hdrCapacityMax:1,offsetHdr:[0,0,0],offsetSdr:[0,0,0]},l=c;else throw d}try{await this.render(s,u,l.buffer,h?.buffer)}catch(d){this.manager.itemError(e),typeof i=="function"&&i(d),s.disposeOnDemandRenderer();return}typeof t=="function"&&t(s),this.manager.itemEnd(e),s.disposeOnDemandRenderer()},n,o=>{this.manager.itemError(e),typeof i=="function"&&i(o)}),s}}class XR extends Cy{constructor(e){super(e),this.type=yt}parse(e){const a=function(E,C){switch(E){case 1:throw new Error("THREE.HDRLoader: Read Error: "+(C||""));case 2:throw new Error("THREE.HDRLoader: Write Error: "+(C||""));case 3:throw new Error("THREE.HDRLoader: Bad File Format: "+(C||""));default:case 4:throw new Error("THREE.HDRLoader: Memory Error: "+(C||""))}},u=function(E,C,D){C=C||1024;let L=E.pos,U=-1,P=0,N="",F=String.fromCharCode.apply(null,new Uint16Array(E.subarray(L,L+128)));for(;0>(U=F.indexOf(` +`))&&P=E.byteLength||!(N=u(E)))&&a(1,"no header found"),(F=N.match(C))||a(3,"bad initial token"),P.valid|=1,P.programtype=F[1],P.string+=N+` +`;N=u(E),N!==!1;){if(P.string+=N+` +`,N.charAt(0)==="#"){P.comments+=N+` +`;continue}if((F=N.match(D))&&(P.gamma=parseFloat(F[1])),(F=N.match(w))&&(P.exposure=parseFloat(F[1])),(F=N.match(L))&&(P.valid|=2,P.format=F[1]),(F=N.match(U))&&(P.valid|=4,P.height=parseInt(F[1],10),P.width=parseInt(F[2],10)),P.valid&2&&P.valid&4)break}return P.valid&2||a(3,"missing format specifier"),P.valid&4||a(3,"missing image size specifier"),P},f=function(E,C,D){const w=C;if(w<8||w>32767||E[0]!==2||E[1]!==2||E[2]&128)return new Uint8Array(E);w!==(E[2]<<8|E[3])&&a(3,"wrong scanline width");const L=new Uint8Array(4*C*D);L.length||a(4,"unable to allocate buffer space");let U=0,P=0;const N=4*w,F=new Uint8Array(4),k=new Uint8Array(N);let $=D;for(;$>0&&PE.byteLength&&a(1),F[0]=E[P++],F[1]=E[P++],F[2]=E[P++],F[3]=E[P++],(F[0]!=2||F[1]!=2||(F[2]<<8|F[3])!=w)&&a(3,"bad rgbe scanline format");let q=0,te;for(;q128;if(Y&&(te-=128),(te===0||q+te>N)&&a(3,"bad scanline data"),Y){const fe=E[P++];for(let Ge=0;Gethis.ldrLoader(t).load(e,s,()=>{},a));return i.name=e,i.flipY=!1,i}async loadKTX2(e,t){xo.setWithCredentials(t);const n=await new Promise((i,s)=>xo.load(e,i,()=>{},s));return n.name=e,n.flipY=!1,n}async loadLottie(e,t,n){const i=await this.getLottieLoader(n);i.setQuality(t);const s=await new Promise((a,o)=>i.load(e,a,()=>{},o));return s.name=e,s}async loadEquirect(e,t=!1,n=()=>{}){try{const i=ZR.test(e),s=i?this.hdrLoader(t):this.imageLoader(t),a=await new Promise((o,c)=>s.load(e,l=>{const{renderTarget:h}=l;if(h!=null){let u;try{const d=l.toDataTexture();d.needsUpdate=!0;const f=d.image.data;let p=!1;const m=f.length;for(let A=0;A{n(l.loaded/l.total*.9)},c));return n(1),a.name=e,a.mapping=sl,!i&&a.type!==yt&&(a.colorSpace=mt),a}finally{n&&n(1)}}async generateEnvironmentMapAndSkybox(e=null,t=null,n=()=>{},i=!1){const s=t!=="legacy";(t==="legacy"||t==="neutral")&&(t=null),t=Nb(t);let a=Promise.resolve(null),o;e&&(a=this.loadEquirectFromUrl(e,i,n)),t?o=this.loadEquirectFromUrl(t,i,n):e?o=this.loadEquirectFromUrl(e,i,n):o=s?this.loadGeneratedEnvironmentMapAlt():this.loadGeneratedEnvironmentMap();const[c,l]=await Promise.all([o,a]);if(c==null)throw new Error("Failed to load environment map.");return{environmentMap:c,skybox:l}}async loadEquirectFromUrl(e,t,n){if(!this.skyboxCache.has(e)){const i=this.loadEquirect(e,t,n);this.skyboxCache.set(e,i)}return this.skyboxCache.get(e)}async GenerateEnvironmentMap(e,t){await qw();const n=this.threeRenderer,i=new ih(256,{generateMipmaps:!1,type:yt,format:Tt,colorSpace:Ct,depthBuffer:!0}),s=new Xd(.1,100,i),a=s.renderTarget.texture;a.name=t;const o=n.outputColorSpace,c=n.toneMapping;return n.toneMapping=kn,n.outputColorSpace=Ct,s.update(n,e),this.blurCubemap(i,JR),n.toneMapping=c,n.outputColorSpace=o,a}async loadGeneratedEnvironmentMap(){return this.generatedEnvironmentMap==null&&(this.generatedEnvironmentMap=this.GenerateEnvironmentMap(new pm("legacy"),"legacy")),this.generatedEnvironmentMap}async loadGeneratedEnvironmentMapAlt(){return this.generatedEnvironmentMapAlt==null&&(this.generatedEnvironmentMapAlt=this.GenerateEnvironmentMap(new pm("neutral"),"neutral")),this.generatedEnvironmentMapAlt}blurCubemap(e,t){if(this.blurMaterial==null){this.blurMaterial=this.getBlurShader(Br);const i=new qi,s=new at(i,this.blurMaterial);this.blurScene=new ms,this.blurScene.add(s)}const n=e.clone();this.halfblur(e,n,t,"latitudinal"),this.halfblur(n,e,t,"longitudinal")}halfblur(e,t,n,i){const a=e.width,o=isFinite(n)?Math.PI/(2*a):2*Math.PI/(2*Br-1),c=n/o,l=isFinite(n)?1+Math.floor(3*c):Br;l>Br&&console.warn(`sigmaRadians, ${n}, is too large and will clip, as it requested ${l} samples when the maximum is set to ${Br}`);const h=[];let u=0;for(let p=0;p= samples ) { + + break; + + } + + float theta = dTheta * float( i ); + gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); + gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); + + } + } + `,blending:Jn,depthTest:!1,depthWrite:!1,side:an})}async dispose(){for(const[,e]of this.skyboxCache)(await e).dispose();this.generatedEnvironmentMap!=null&&((await this.generatedEnvironmentMap).dispose(),this.generatedEnvironmentMap=null),this.generatedEnvironmentMapAlt!=null&&((await this.generatedEnvironmentMapAlt).dispose(),this.generatedEnvironmentMapAlt=null),this.blurMaterial!=null&&this.blurMaterial.dispose()}}const tB=.2,wu=40,Tu=60,gm=5,Dr=[1,.79,.62,.5,.4,.31,.25],nB=3,mm="high-performance",iB=1.3;class On extends ii{static get singleton(){return this._singleton||(this._singleton=new On({powerPreference:(self.ModelViewerElement||{}).powerPreference||mm,debug:XA()})),this._singleton}static resetSingleton(){const e=this._singleton.dispose();for(const t of e)t.disconnectedCallback();this._singleton=new On({powerPreference:(self.ModelViewerElement||{}).powerPreference||mm,debug:XA()});for(const t of e)t.connectedCallback()}get canRender(){return this.threeRenderer!=null}get scaleFactor(){return Dr[this.scaleStep]}set minScale(e){let t=1;for(;t{this.dispatchEvent({type:"contextlost",sourceEvent:t})},this.onWebGLContextRestored=()=>{var t;(t=this.textureUtils)===null||t===void 0||t.dispose(),this.textureUtils=this.canRender?new Am(this.threeRenderer):null;for(const n of this.scenes)n.element[Ul]()},this.dpr=window.devicePixelRatio,this.canvas3D=document.createElement("canvas"),this.canvas3D.id="webgl-canvas",this.canvas3D.classList.add("show");try{this.threeRenderer=new Xf({canvas:this.canvas3D,alpha:!0,antialias:!0,powerPreference:e.powerPreference,preserveDrawingBuffer:!0}),this.threeRenderer.autoClear=!0,this.threeRenderer.setPixelRatio(1),this.threeRenderer.debug={checkShaderErrors:!!e.debug,onShaderError:null},this.threeRenderer.toneMapping=ta}catch(t){console.warn(t)}this.arRenderer=this.canRender?new PR(this):null,this.textureUtils=this.canRender?new Am(this.threeRenderer):null,this.canRender&&_n.initializeKTX2Loader(this.threeRenderer),this.canvas3D.addEventListener("webglcontextlost",this.onWebGLContextLost),this.canvas3D.addEventListener("webglcontextrestored",this.onWebGLContextRestored),this.updateRendererSize()}registerScene(e){if(this.scenes.add(e),e.forceRescale(),this.canRender){const t=new pe;this.threeRenderer.getSize(t),e.canvas.width=t.x,e.canvas.height=t.y,this.scenes.size>0&&this.threeRenderer.setAnimationLoop((n,i)=>this.render(n,i))}}unregisterScene(e){this.scenes.delete(e),this.canvas3D.parentElement===e.canvas.parentElement&&e.canvas.parentElement.removeChild(this.canvas3D),this.canRender&&this.scenes.size===0&&this.threeRenderer.setAnimationLoop(null)}displayCanvas(e){return e.element.modelIsVisible&&!this.multipleScenesVisible?this.canvas3D:e.element[hf]}countVisibleScenes(){const{canvas3D:e}=this;let t=0,n=null;for(const s of this.scenes){const{element:a}=s;a.modelIsVisible&&s.externalRenderer==null&&++t,e.parentElement===s.canvas.parentElement&&(n=s)}const i=t>1;if(n!=null){const s=i&&!this.multipleScenesVisible,a=!n.element.modelIsVisible;if(s||a){const{width:o,height:c}=this.sceneSize(n);this.copyPixels(n,o,c),e.parentElement.removeChild(e)}}this.multipleScenesVisible=i}updateRendererSize(){var e;const t=window.devicePixelRatio;if(t!==this.dpr)for(const s of this.scenes){const{element:a}=s;a[Qr](a.getBoundingClientRect())}let n=0,i=0;for(const s of this.scenes)n=Math.max(n,s.width),i=Math.max(i,s.height);if(!(n===this.width&&i===this.height&&t===this.dpr)){this.width=n,this.height=i,this.dpr=t,n=Math.ceil(n*t),i=Math.ceil(i*t),this.canRender&&this.threeRenderer.setSize(n,i,!1);for(const s of this.scenes){const{canvas:a}=s;a.width=n,a.height=i,s.forceRescale(),(e=s.effectRenderer)===null||e===void 0||e.setSize(n,i)}}}updateRendererScale(e){const t=this.scaleStep;this.avgFrameDuration+=fi(tB*(e-this.avgFrameDuration),-gm,gm),this.avgFrameDuration>Tu?++this.scaleStep:this.avgFrameDuration0&&--this.scaleStep,this.scaleStep=Math.min(this.scaleStep,this.lastStep),t!==this.scaleStep&&(this.avgFrameDuration=(Tu+wu)/2)}shouldRender(e){if(e.shouldRender())e.scaleStep!=this.scaleStep&&(e.scaleStep=this.scaleStep,this.rescaleCanvas(e));else if(e.scaleStep!=0)e.scaleStep=0,this.rescaleCanvas(e);else return!1;return!0}rescaleCanvas(e){const t=Dr[e.scaleStep],n=Math.ceil(this.width/t),i=Math.ceil(this.height/t),{style:s}=e.canvas;s.width=`${n}px`,s.height=`${i}px`,this.canvas3D.style.width=`${n}px`,this.canvas3D.style.height=`${i}px`;const a=this.dpr*t,o=t<1?"GPU throttling":this.dpr!==window.devicePixelRatio?"No meta viewport tag":"";e.element.dispatchEvent(new CustomEvent("render-scale",{detail:{reportedDpr:window.devicePixelRatio,renderedDpr:a,minimumDpr:this.dpr*Dr[this.lastStep],pixelWidth:Math.ceil(e.width*a),pixelHeight:Math.ceil(e.height*a),reason:o}}))}sceneSize(e){const{dpr:t}=this,n=Dr[e.scaleStep],i=Math.min(Math.ceil(e.width*n*t),this.canvas3D.width),s=Math.min(Math.ceil(e.height*n*t),this.canvas3D.height);return{width:i,height:s}}copyPixels(e,t,n){const i=e.context;if(i==null){console.log("could not acquire 2d context");return}i.clearRect(0,0,t,n),i.drawImage(this.canvas3D,0,0,t,n,0,0,t,n),e.canvas.classList.add("show")}orderedScenes(){const e=[];for(const t of[!1,!0])for(const n of this.scenes)n.element.modelIsVisible===t&&e.push(n);return e}get isPresenting(){var e;return((e=this.arRenderer)===null||e===void 0?void 0:e.isPresenting)===!0}preRender(e,t,n){const{element:i,exposure:s,toneMapping:a}=e;i[gi](t,n);const o=typeof s=="number"&&!Number.isNaN(s),c=i.environmentImage,l=i.skyboxImage,h=a===ta&&(c==="neutral"||c==="legacy"||!c&&!l);this.threeRenderer.toneMappingExposure=(o?s:1)*(h?iB:1)}render(e,t){if(t!=null){this.arRenderer!=null&&this.arRenderer.onWebXRFrame(e,t);return}const n=e-this.lastTick;if(this.lastTick=e,!this.canRender||this.isPresenting)return;this.countVisibleScenes(),this.updateRendererSize(),this.renderedLastFrame&&(this.updateRendererScale(n),this.renderedLastFrame=!1);const{canvas3D:i}=this;for(const s of this.orderedScenes()){const{element:a}=s;if(!a.loaded||!a.modelIsVisible&&s.renderCount>0||(this.preRender(s,e,n),!this.shouldRender(s)))continue;if(s.externalRenderer!=null){const l=s.getCamera();l.updateMatrix();const{matrix:h,projectionMatrix:u}=l,d=h.elements.slice(),f=s.getTarget();d[12]+=f.x,d[13]+=f.y,d[14]+=f.z,s.externalRenderer.render({viewMatrix:d,projectionMatrix:u.elements});continue}if(!a.modelIsVisible&&!this.multipleScenesVisible)for(const l of this.scenes)l.element.modelIsVisible&&l.queueRender();const{width:o,height:c}=this.sceneSize(s);s.renderShadow(this.threeRenderer),this.threeRenderer.setRenderTarget(null),this.threeRenderer.setViewport(0,Math.ceil(this.height*this.dpr)-c,o,c),s.effectRenderer!=null?s.effectRenderer.render(n):(this.threeRenderer.autoClear=!0,this.threeRenderer.toneMapping=s.toneMapping,this.threeRenderer.render(s,s.camera)),this.multipleScenesVisible||!s.element.modelIsVisible&&s.renderCount===0?this.copyPixels(s,o,c):i.parentElement!==s.canvas.parentElement&&(s.canvas.parentElement.appendChild(i),s.canvas.classList.remove("show")),s.hasRendered(),++s.renderCount,this.renderedLastFrame=!0}}dispose(){this.textureUtils!=null&&this.textureUtils.dispose(),this.threeRenderer!=null&&this.threeRenderer.dispose(),this.textureUtils=null,this.threeRenderer=null;const e=[];for(const t of this.scenes)e.push(t.element);return this.canvas3D.removeEventListener("webglcontextlost",this.onWebGLContextLost),this.canvas3D.removeEventListener("webglcontextrestored",this.onWebGLContextRestored),e}}const Xe=Symbol("correlatedObjects"),lt=Symbol("onUpdate");class zo{constructor(e,t){this[lt]=e,this[Xe]=t}}const bm=new fn,sB=new Hn(2,2);let rB=0;const Pn=Symbol("threeTexture"),xm=Symbol("threeTextures");let aB=class extends zo{get[Pn](){var e;return(e=this[Xe])===null||e===void 0?void 0:e.values().next().value}get[xm](){return this[Xe]}constructor(e,t){super(e,new Set(t?[t]:[]));const n=this[Pn].image;n.src||(n.src=t.name?t.name:"adhoc_image"+rB++),n.name||(n.name=t&&n&&n.src?n.src.split("/").pop():"adhoc_image")}get name(){return this[Pn].image.name||""}get uri(){return this[Pn].image.src}get bufferView(){return this[Pn].image.bufferView}get element(){const e=this[Pn];if(e&&(e.isCanvasTexture||e.isVideoTexture))return e.image}get animation(){const e=this[Pn];if(e&&e.isCanvasTexture&&e.animation)return e.animation}get type(){return this.uri!=null?"external":"embedded"}set name(e){for(const t of this[xm])t.image.name=e}update(){const e=this[Pn];e&&e.isCanvasTexture&&!e.animation&&(this[Pn].needsUpdate=!0,this[lt]())}async createThumbnail(e,t){const n=new ms;bm.map=this[Pn];const i=new at(sB,bm);n.add(i);const s=new rr(-1,1,1,-1,0,1),{threeRenderer:a}=On.singleton,o=new yn(e,t);a.setRenderTarget(o),a.render(n,s),a.setRenderTarget(null);const c=new Uint8Array(e*t*4);a.readRenderTargetPixels(o,0,0,e,t,c),ps.width=e,ps.height=t;const l=ps.getContext("2d"),h=l.createImageData(e,t);return h.data.set(c),l.putImageData(h,0,0),new Promise(async(u,d)=>{ps.toBlob(f=>{if(!f)return d("Failed to capture thumbnail.");u(URL.createObjectURL(f))},"image/png")})}};var Zt;(function(r){r[r.Nearest=9728]="Nearest",r[r.Linear=9729]="Linear",r[r.NearestMipmapNearest=9984]="NearestMipmapNearest",r[r.LinearMipmapNearest=9985]="LinearMipmapNearest",r[r.NearestMipmapLinear=9986]="NearestMipmapLinear",r[r.LinearMipmapLinear=9987]="LinearMipmapLinear"})(Zt||(Zt={}));var As;(function(r){r[r.ClampToEdge=33071]="ClampToEdge",r[r.MirroredRepeat=33648]="MirroredRepeat",r[r.Repeat=10497]="Repeat"})(As||(As={}));const Em=new Map([[As.Repeat,ti],[As.ClampToEdge,Dt],[As.MirroredRepeat,er]]),nf=new Map([[ti,As.Repeat],[Dt,As.ClampToEdge],[er,As.MirroredRepeat]]),oB=new Map([[Zt.Nearest,St],[Zt.Linear,qe],[Zt.NearestMipmapNearest,ga],[Zt.LinearMipmapNearest,Xs],[Zt.NearestMipmapLinear,hs],[Zt.LinearMipmapLinear,vn]]),$x=new Map([[St,Zt.Nearest],[qe,Zt.Linear],[ga,Zt.NearestMipmapNearest],[Xs,Zt.LinearMipmapNearest],[hs,Zt.NearestMipmapLinear],[vn,Zt.LinearMipmapLinear]]),cB=new Map([[Zt.Nearest,St],[Zt.Linear,qe]]),Yx=new Map([[St,Zt.Nearest],[qe,Zt.Linear]]),lB=r=>$x.has(r),hB=r=>Yx.has(r),uB=r=>nf.has(r),dB=(r,e)=>{switch(r){case"minFilter":return lB(e);case"magFilter":return hB(e);case"wrapS":case"wrapT":return uB(e);case"rotation":case"repeat":case"offset":return!0;default:throw new Error(`Cannot configure property "${r}" on Sampler`)}},Di=Symbol("threeTexture"),_m=Symbol("threeTextures"),ns=Symbol("setProperty");class fB extends zo{get[Di](){var e;return(e=this[Xe])===null||e===void 0?void 0:e.values().next().value}get[_m](){return this[Xe]}constructor(e,t){super(e,new Set(t?[t]:[]))}get name(){return this[Di].name||""}get minFilter(){return $x.get(this[Di].minFilter)}get magFilter(){return Yx.get(this[Di].magFilter)}get wrapS(){return nf.get(this[Di].wrapS)}get wrapT(){return nf.get(this[Di].wrapT)}get rotation(){return this[Di].rotation}get scale(){return uf(this[Di].repeat)}get offset(){return uf(this[Di].offset)}setMinFilter(e){this[ns]("minFilter",oB.get(e))}setMagFilter(e){this[ns]("magFilter",cB.get(e))}setWrapS(e){this[ns]("wrapS",Em.get(e))}setWrapT(e){this[ns]("wrapT",Em.get(e))}setRotation(e){e==null&&(e=0),this[ns]("rotation",e)}setScale(e){e==null&&(e={u:1,v:1}),this[ns]("repeat",new pe(e.u,e.v))}setOffset(e){e==null&&(e={u:0,v:0}),this[ns]("offset",new pe(e.u,e.v))}[ns](e,t){if(dB(e,t))for(const n of this[_m])n[e]=t,n.needsUpdate=!0;this[lt]()}}const vm=Symbol("image"),ym=Symbol("sampler"),Sm=Symbol("threeTexture");class Jx extends zo{get[Sm](){var e;return(e=this[Xe])===null||e===void 0?void 0:e.values().next().value}constructor(e,t){super(e,new Set(t?[t]:[])),this[ym]=new fB(e,t),this[vm]=new aB(e,t)}get name(){return this[Sm].name||""}set name(e){for(const t of this[Xe])t.name=e}get sampler(){return this[ym]}get source(){return this[vm]}}var Zx,eE,tE;const ks=Symbol("texture"),Qs=Symbol("transform"),Ru=Symbol("materials"),Cm=Symbol("usage"),Lr=Symbol("onUpdate"),co=Symbol("activeVideo");var Ue;(function(r){r[r.Base=0]="Base",r[r.MetallicRoughness=1]="MetallicRoughness",r[r.Normal=2]="Normal",r[r.Occlusion=3]="Occlusion",r[r.Emissive=4]="Emissive",r[r.Clearcoat=5]="Clearcoat",r[r.ClearcoatRoughness=6]="ClearcoatRoughness",r[r.ClearcoatNormal=7]="ClearcoatNormal",r[r.SheenColor=8]="SheenColor",r[r.SheenRoughness=9]="SheenRoughness",r[r.Transmission=10]="Transmission",r[r.Thickness=11]="Thickness",r[r.Specular=12]="Specular",r[r.SpecularColor=13]="SpecularColor",r[r.Iridescence=14]="Iridescence",r[r.IridescenceThickness=15]="IridescenceThickness",r[r.Anisotropy=16]="Anisotropy"})(Ue||(Ue={}));class Vr{constructor(e,t,n,i){this[Zx]=null,this[eE]={rotation:0,scale:new pe(1,1),offset:new pe(0,0)},this[tE]=!1,n&&(this[Qs].rotation=n.rotation,this[Qs].scale.copy(n.repeat),this[Qs].offset.copy(n.offset),this[ks]=new Jx(e,n)),this[Lr]=e,this[Ru]=i,this[Cm]=t}get texture(){return this[ks]}setTexture(e){var t,n;const i=e!=null?e.source[Pn]:null,s=(t=this[ks])===null||t===void 0?void 0:t.source[Pn];if(s!=null&&s.isVideoTexture?this[co]=!1:!((n=this[ks])===null||n===void 0)&&n.source.animation&&this[ks].source.animation.removeEventListener("enterFrame",this[Lr]),this[ks]=e,i!=null&&i.isVideoTexture){const o=i.image;if(this[co]=!0,o.requestVideoFrameCallback!=null){const c=()=>{this[co]&&(this[Lr](),o.requestVideoFrameCallback(c))};o.requestVideoFrameCallback(c)}else{const c=()=>{this[co]&&(this[Lr](),requestAnimationFrame(c))};requestAnimationFrame(c)}}else e?.source.animation!=null&&e.source.animation.addEventListener("enterFrame",this[Lr]);let a=mt;if(this[Ru])for(const o of this[Ru]){switch(this[Cm]){case Ue.Base:o.map=i;break;case Ue.MetallicRoughness:a=Ct,o.metalnessMap=i,o.roughnessMap=i;break;case Ue.Normal:a=Ct,o.normalMap=i;break;case Ue.Occlusion:a=Ct,o.aoMap=i;break;case Ue.Emissive:o.emissiveMap=i;break;case Ue.Clearcoat:o.clearcoatMap=i;break;case Ue.ClearcoatRoughness:o.clearcoatRoughnessMap=i;break;case Ue.ClearcoatNormal:o.clearcoatNormalMap=i;break;case Ue.SheenColor:o.sheenColorMap=i;break;case Ue.SheenRoughness:o.sheenRoughnessMap=i;break;case Ue.Transmission:o.transmissionMap=i;break;case Ue.Thickness:o.thicknessMap=i;break;case Ue.Specular:o.specularIntensityMap=i;break;case Ue.SpecularColor:o.specularColorMap=i;break;case Ue.Iridescence:o.iridescenceMap=i;break;case Ue.IridescenceThickness:o.iridescenceThicknessMap=i;break;case Ue.Anisotropy:o.anisotropyMap=i;break}o.needsUpdate=!0}i&&(i.colorSpace=a,i.rotation=this[Qs].rotation,i.repeat=this[Qs].scale,i.offset=this[Qs].offset),this[Lr]()}}Zx=ks,eE=Qs,tE=co;const qa=Symbol("threeMaterial"),Gc=Symbol("threeMaterials"),Mm=Symbol("baseColorTexture"),Im=Symbol("metallicRoughnessTexture");class pB extends zo{get[Gc](){return this[Xe]}get[qa](){var e;return(e=this[Xe])===null||e===void 0?void 0:e.values().next().value}constructor(e,t){super(e,t);const{map:n,metalnessMap:i}=t.values().next().value;this[Mm]=new Vr(e,Ue.Base,n,t),this[Im]=new Vr(e,Ue.MetallicRoughness,i,t)}get baseColorFactor(){const e=[0,0,0,this[qa].opacity];return this[qa].color.toArray(e),e}get metallicFactor(){return this[qa].metalness}get roughnessFactor(){return this[qa].roughness}get baseColorTexture(){return this[Mm]}get metallicRoughnessTexture(){return this[Im]}setBaseColorFactor(e){const t=new Me;e instanceof Array?t.fromArray(e):t.set(e);for(const n of this[Gc])n.color.set(t),e instanceof Array&&e.length>3?n.opacity=e[3]:(e=[0,0,0,n.opacity],t.toArray(e));this[lt]()}setMetallicFactor(e){for(const t of this[Gc])t.metalness=e;this[lt]()}setRoughnessFactor(e){for(const t of this[Gc])t.roughness=e;this[lt]()}}var wm,Tm;const Rm=Symbol("pbrMetallicRoughness"),Bm=Symbol("normalTexture"),Dm=Symbol("occlusionTexture"),Lm=Symbol("emissiveTexture"),Mt=Symbol("backingThreeMaterial"),Pm=Symbol("applyAlphaCutoff"),Bu=Symbol("getAlphaMode"),Pr=Symbol("lazyLoadGLTFInfo"),Du=Symbol("initialize"),sf=Symbol("getLoadedMaterial"),be=Symbol("ensureMaterialIsLoaded"),Fm=Symbol("gltfIndex"),lo=Symbol("setActive"),Yr=Symbol("variantIndices"),Lu=Symbol("isActive"),Nm=Symbol("modelVariants"),Pu=Symbol("name"),Sn=Symbol("pbrTextures");class Fu extends zo{get[(wm=Yr,Tm=Sn,Mt)](){return this[Xe].values().next().value}constructor(e,t,n,i,s,a,o=void 0){super(e,s),this[wm]=new Set,this[Tm]=new Map,this[Fm]=t,this[Lu]=n,this[Nm]=i,this[Pu]=a,o==null?this[Du]():this[Pr]=o}[Du](){const e=this[lt],t=this[Xe];this[Rm]=new pB(e,t);const{normalMap:n,aoMap:i,emissiveMap:s}=t.values().next().value;this[Bm]=new Vr(e,Ue.Normal,n,t),this[Dm]=new Vr(e,Ue.Occlusion,i,t),this[Lm]=new Vr(e,Ue.Emissive,s,t);const a=o=>{this[Sn].set(o,new Vr(e,o,null,t))};a(Ue.Clearcoat),a(Ue.ClearcoatRoughness),a(Ue.ClearcoatNormal),a(Ue.SheenColor),a(Ue.SheenRoughness),a(Ue.Transmission),a(Ue.Thickness),a(Ue.Specular),a(Ue.SpecularColor),a(Ue.Iridescence),a(Ue.IridescenceThickness),a(Ue.Anisotropy)}async[sf](){if(this[Pr]!=null){const e=await this[Pr].doLazyLoad();return this[Du](),this[Pr]=void 0,this.ensureLoaded=async()=>{},e}return null}colorFromRgb(e){const t=new Me;return e instanceof Array?t.fromArray(e):t.set(e),t}[be](){if(this[Pr]!=null)throw new Error(`Material "${this.name}" has not been loaded, call 'await + myMaterial.ensureLoaded()' before using an unloaded material.`)}async ensureLoaded(){await this[sf]()}get isLoaded(){return this[Pr]==null}get isActive(){return this[Lu]}[lo](e){this[Lu]=e}get name(){return this[Pu]||""}set name(e){if(this[Pu]=e,this[Xe]!=null)for(const t of this[Xe])t.name=e}get pbrMetallicRoughness(){return this[be](),this[Rm]}get normalTexture(){return this[be](),this[Bm]}get occlusionTexture(){return this[be](),this[Dm]}get emissiveTexture(){return this[be](),this[Lm]}get emissiveFactor(){return this[be](),this[Mt].emissive.toArray()}get index(){return this[Fm]}hasVariant(e){const t=this[Nm].get(e);return t!=null&&this[Yr].has(t.index)}setEmissiveFactor(e){this[be]();const t=this.colorFromRgb(e);for(const n of this[Xe])n.emissive.set(t);this[lt]()}[Bu](){return this[Mt].transparent?"BLEND":this[Mt].alphaTest>0?"MASK":"OPAQUE"}[Pm](){this[be]();for(const e of this[Xe])this[Bu]()==="MASK"?e.alphaTest==null&&(e.alphaTest=.5):e.alphaTest=void 0,e.needsUpdate=!0}setAlphaCutoff(e){this[be]();for(const t of this[Xe])t.alphaTest=e,t.needsUpdate=!0;this[Pm](),this[lt]()}getAlphaCutoff(){return this[be](),this[Mt].alphaTest}setDoubleSided(e){this[be]();for(const t of this[Xe])t.side=e?Wt:ei,t.needsUpdate=!0;this[lt]()}getDoubleSided(){return this[be](),this[Mt].side==Wt}setAlphaMode(e){this[be]();const t=(n,i)=>{n.transparent=i,n.depthWrite=!i};for(const n of this[Xe])t(n,e==="BLEND"),e==="MASK"?n.alphaTest=.5:n.alphaTest=void 0,n.needsUpdate=!0;this[lt]()}getAlphaMode(){return this[be](),this[Bu]()}get emissiveStrength(){return this[be](),this[Mt].emissiveIntensity}setEmissiveStrength(e){this[be]();for(const t of this[Xe])t.emissiveIntensity=e;this[lt]()}get clearcoatFactor(){return this[be](),this[Mt].clearcoat}get clearcoatRoughnessFactor(){return this[be](),this[Mt].clearcoatRoughness}get clearcoatTexture(){return this[be](),this[Sn].get(Ue.Clearcoat)}get clearcoatRoughnessTexture(){return this[be](),this[Sn].get(Ue.ClearcoatRoughness)}get clearcoatNormalTexture(){return this[be](),this[Sn].get(Ue.ClearcoatNormal)}get clearcoatNormalScale(){return this[be](),this[Mt].clearcoatNormalScale.x}setClearcoatFactor(e){this[be]();for(const t of this[Xe])t.clearcoat=e;this[lt]()}setClearcoatRoughnessFactor(e){this[be]();for(const t of this[Xe])t.clearcoatRoughness=e;this[lt]()}setClearcoatNormalScale(e){this[be]();for(const t of this[Xe])t.clearcoatNormalScale=new pe(e,e);this[lt]()}get ior(){return this[be](),this[Mt].ior}setIor(e){this[be]();for(const t of this[Xe])t.ior=e;this[lt]()}get sheenColorFactor(){return this[be](),this[Mt].sheenColor.toArray()}get sheenColorTexture(){return this[be](),this[Sn].get(Ue.SheenColor)}get sheenRoughnessFactor(){return this[be](),this[Mt].sheenRoughness}get sheenRoughnessTexture(){return this[be](),this[Sn].get(Ue.SheenRoughness)}setSheenColorFactor(e){this[be]();const t=this.colorFromRgb(e);for(const n of this[Xe])n.sheenColor.set(t),n.sheen=1;this[lt]()}setSheenRoughnessFactor(e){this[be]();for(const t of this[Xe])t.sheenRoughness=e,t.sheen=1;this[lt]()}get transmissionFactor(){return this[be](),this[Mt].transmission}get transmissionTexture(){return this[be](),this[Sn].get(Ue.Transmission)}setTransmissionFactor(e){this[be]();for(const t of this[Xe])t.transmission=e;this[lt]()}get thicknessFactor(){return this[be](),this[Mt].thickness}get thicknessTexture(){return this[be](),this[Sn].get(Ue.Thickness)}get attenuationDistance(){return this[be](),this[Mt].attenuationDistance}get attenuationColor(){return this[be](),this[Mt].attenuationColor.toArray()}setThicknessFactor(e){this[be]();for(const t of this[Xe])t.thickness=e;this[lt]()}setAttenuationDistance(e){this[be]();for(const t of this[Xe])t.attenuationDistance=e;this[lt]()}setAttenuationColor(e){this[be]();const t=this.colorFromRgb(e);for(const n of this[Xe])n.attenuationColor.set(t);this[lt]()}get specularFactor(){return this[be](),this[Mt].specularIntensity}get specularTexture(){return this[be](),this[Sn].get(Ue.Specular)}get specularColorFactor(){return this[be](),this[Mt].specularColor.toArray()}get specularColorTexture(){return this[be](),this[Sn].get(Ue.SheenColor)}setSpecularFactor(e){this[be]();for(const t of this[Xe])t.specularIntensity=e;this[lt]()}setSpecularColorFactor(e){this[be]();const t=this.colorFromRgb(e);for(const n of this[Xe])n.specularColor.set(t);this[lt]()}get iridescenceFactor(){return this[be](),this[Mt].iridescence}get iridescenceTexture(){return this[be](),this[Sn].get(Ue.Iridescence)}get iridescenceIor(){return this[be](),this[Mt].iridescenceIOR}get iridescenceThicknessMinimum(){return this[be](),this[Mt].iridescenceThicknessRange[0]}get iridescenceThicknessMaximum(){return this[be](),this[Mt].iridescenceThicknessRange[1]}get iridescenceThicknessTexture(){return this[be](),this[Sn].get(Ue.IridescenceThickness)}setIridescenceFactor(e){this[be]();for(const t of this[Xe])t.iridescence=e;this[lt]()}setIridescenceIor(e){this[be]();for(const t of this[Xe])t.iridescenceIOR=e;this[lt]()}setIridescenceThicknessMinimum(e){this[be]();for(const t of this[Xe])t.iridescenceThicknessRange[0]=e;this[lt]()}setIridescenceThicknessMaximum(e){this[be]();for(const t of this[Xe])t.iridescenceThicknessRange[1]=e;this[lt]()}get anisotropyStrength(){return this[be](),this[Mt].anisotropy}get anisotropyRotation(){return this[be](),this[Mt].anisotropyRotation}get anisotropyTexture(){return this[be](),this[Sn].get(Ue.Anisotropy)}setAnisotropyStrength(e){this[be]();for(const t of this[Xe])t.anisotropy=e;this[lt]()}setAnisotropyRotation(e){this[be]();for(const t of this[Xe])t.anisotropyRotation=e;this[lt]()}}let nE=class{constructor(e){this.name="",this.children=new Array,this.name=e}};class Nu extends nE{constructor(e,t,n,i){super(e.name),this.materials=new Map,this.variantToMaterialMap=new Map,this.initialMaterialIdx=0,this.activeMaterialIdx=0,this.mesh=e;const{gltf:s,threeGLTF:a,threeObjectMap:o}=i;this.parser=a.parser,this.modelVariants=n,this.mesh.userData.variantData=n;const c=o.get(e.material);c.materials!=null?this.initialMaterialIdx=this.activeMaterialIdx=c.materials:console.error(`Primitive (${e.name}) missing initial material reference.`);const l=e.userData.associations||{};if(l.meshes==null){console.error("Mesh is missing primitive index association");return}const d=((s.meshes||[])[l.meshes].primitives||[])[l.primitives];if(d==null){console.error("Mesh primitive definition is missing.");return}if(d.material!=null)this.materials.set(d.material,t[d.material]);else{const f=t.findIndex(p=>p.name==="Default");f>=0?this.materials.set(f,t[f]):console.warn("gltfPrimitive has no material!")}if(d.extensions&&d.extensions.KHR_materials_variants){const f=d.extensions.KHR_materials_variants,m=a.parser.json.extensions.KHR_materials_variants.variants;for(const A of f.mappings){const g=t[A.material];this.materials.set(A.material,g);for(const b of A.variants){const{name:x}=m[b];this.variantToMaterialMap.set(b,g),g[Yr].add(b),n.has(x)||n.set(x,{name:x,index:b})}}}}async setActiveMaterial(e){const t=this.materials.get(e);if(e!==this.activeMaterialIdx){const n=t[Xe],i=await t[sf]();i!=null?this.mesh.material=i:this.mesh.material=n.values().next().value,this.parser.assignFinalMaterial(this.mesh),n.add(this.mesh.material),this.activeMaterialIdx=e}return this.mesh.material}getActiveMaterial(){return this.materials.get(this.activeMaterialIdx)}getMaterial(e){return this.materials.get(e)}async enableVariant(e){if(e==null)return this.setActiveMaterial(this.initialMaterialIdx);if(this.variantToMaterialMap!=null&&this.modelVariants.has(e)){const t=this.modelVariants.get(e);return this.enableVariantHelper(t.index)}return null}async enableVariantHelper(e){if(this.variantToMaterialMap!=null&&e!=null){const t=this.variantToMaterialMap.get(e);if(t!=null)return this.setActiveMaterial(t.index)}return null}async instantiateVariants(){if(this.variantToMaterialMap!=null)for(const e of this.variantToMaterialMap.keys()){const t=this.mesh.userData.variantMaterials.get(e);if(t.material!=null)continue;const n=await this.enableVariantHelper(e);n!=null&&(t.material=n)}}get variantInfo(){return this.variantToMaterialMap}addVariant(e,t){if(!this.ensureVariantIsUnused(t))return!1;this.modelVariants.has(t)||this.modelVariants.set(t,{name:t,index:this.modelVariants.size});const i=this.modelVariants.get(t).index;return e[Yr].add(i),this.variantToMaterialMap.set(i,e),this.materials.set(e.index,e),this.updateVariantUserData(i,e),!0}deleteVariant(e){if(this.variantInfo.has(e)){this.variantInfo.delete(e);const t=this.mesh.userData.variantMaterials;t?.delete(e)}}updateVariantUserData(e,t){t[Yr].add(e),this.mesh.userData.variantData=this.modelVariants,this.mesh.userData.variantMaterials=this.mesh.userData.variantMaterials||new Map,this.mesh.userData.variantMaterials.set(e,{material:t[Xe].values().next().value,gltfMaterialIndex:t.index})}ensureVariantIsUnused(e){const t=this.modelVariants.get(e);return t!=null&&this.variantInfo.has(t.index)?(console.warn(`Primitive cannot add variant '${e}' for this material, it already exists.`),!1):!0}}var Um,Om,km,Qm,Gm,Hm;const Ds=Symbol("materials"),Hc=Symbol("hierarchy"),zm=Symbol("roots"),Li=Symbol("primitives"),iE=Symbol("prepareVariantsForExport"),sE=Symbol("switchVariant"),rf=Symbol("materialFromPoint"),af=Symbol("nodeFromPoint"),rE=Symbol("nodeFromIndex"),un=Symbol("variantData"),of=Symbol("availableVariants"),Uu=Symbol("modelOnUpdate"),Vm=Symbol("cloneMaterial");class AB{constructor(e,t,n,i){this.gltf=e,this.gltfElementMap=t,this.mapKey=n,this.doLazyLoad=i}}class Wm{constructor(e,t=()=>{}){this[Um]=new Array,this[Om]=new Array,this[km]=new Array,this[Qm]=new Array,this[Gm]=()=>{},this[Hm]=new Map,this[Uu]=t;const{gltf:n,threeGLTF:i,gltfElementMap:s}=e;for(const[c,l]of n.materials.entries()){const h=s.get(l);if(h!=null)this[Ds].push(new Fu(t,c,!0,this[un],h,l.name));else{const d=(n.materials||[])[c],f=new Set;s.set(d,f);const p=async()=>{const m=await i.parser.getDependency("material",c);return f.add(m),m};this[Ds].push(new Fu(t,c,!1,this[un],f,l.name,new AB(n,s,d,p)))}}const a=new Map,o=new Array;for(const c of i.scene.children)o.push(c);for(;o.length>0;){const c=o.pop();let l=null;c instanceof at?(l=new Nu(c,this.materials,this[un],e),this[Li].push(l)):l=new nE(c.name);const h=a.get(c);h!=null?h.children.push(l):this[zm].push(l),this[Hc].push(l);for(const u of c.children)o.push(u),a.set(c,l)}}get materials(){return this[Ds]}[(Um=Ds,Om=Hc,km=zm,Qm=Li,Gm=Uu,Hm=un,of)](){const e=Array.from(this[un].values());return e.sort((t,n)=>t.index-n.index),e.map(t=>t.name)}getMaterialByName(e){const t=this[Ds].filter(n=>n.name===e);return t.length>0?t[0]:null}[rE](e,t){const n=this[Hc].find(i=>{if(i instanceof Nu){const{meshes:s,primitives:a}=i.mesh.userData.associations;if(s==e&&a==t)return!0}return!1});return n??null}[af](e){const t=this[Hc].find(n=>n instanceof Nu&&n.mesh===e.object);return t||null}[rf](e){const t=this[af](e);return t?t.getActiveMaterial():null}async[sE](e){for(const t of this[Li])await t.enableVariant(e);for(const t of this.materials)t[lo](!1);for(const t of this[Li])this.materials[t.getActiveMaterial().index][lo](!0)}async[iE](){const e=new Array;for(const t of this[Li])e.push(t.instantiateVariants());await Promise.all(e)}[Vm](e,t){const n=this.materials[e];n.isLoaded||console.error(`Cloning an unloaded material, + call 'material.ensureLoaded() before cloning the material.`);const i=n[Xe],s=new Set;for(const[o,c]of i.entries()){const l=c.clone();l.name=t+(i.size>1?"_inst"+o:""),s.add(l)}const a=new Fu(this[Uu],this[Ds].length,!1,this[un],s,t);return this[Ds].push(a),a}createMaterialInstanceForVariant(e,t,n,i=!0){let s=null;for(const a of this[Li]){const o=this[un].get(n);o!=null&&a.variantInfo.has(o.index)||a.getMaterial(e)!=null&&(this.hasVariant(n)||this.createVariant(n),s==null&&(s=this[Vm](e,t)),a.addVariant(s,n))}if(i&&s!=null){s[lo](!0),this.materials[e][lo](!1);for(const a of this[Li])a.enableVariant(n)}return s}createVariant(e){this[un].has(e)?console.warn(`Variant '${e}'' already exists`):this[un].set(e,{name:e,index:this[un].size})}hasVariant(e){return this[un].has(e)}setMaterialToVariant(e,t){if(this[of]().find(n=>n===t)==null){console.warn(`Can't add material to '${t}', the variant does not exist.'`);return}if(e<0||e>=this.materials.length){console.error("setMaterialToVariant(): materialIndex is out of bounds.");return}for(const n of this[Li]){const i=n.getMaterial(e);i!=null&&n.addVariant(i,t)}}updateVariantName(e,t){const n=this[un].get(e);n!=null&&(n.name=t,this[un].set(t,n),this[un].delete(e))}deleteVariant(e){const t=this[un].get(e);if(t!=null){for(const n of this.materials)n.hasVariant(e)&&n[Yr].delete(t.index);for(const n of this[Li])n.deleteVariant(t.index);this[un].delete(e)}}}var Ou=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var o=r.length-1;o>=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};const dl=Symbol("currentGLTF"),fl=Symbol("originalGltfJson"),Gs=Symbol("model"),ja=Symbol("extraModels"),zc=Symbol("getOnUpdateMethod"),Xa=Symbol("buildTexture"),gB=r=>{var e,t,n,i;class s extends r{constructor(){super(...arguments),this[e]=void 0,this[t]=[],this[n]=null,this[i]=null,this.variantName=null,this.orientation="0 0 0",this.scale="1 1 1"}get model(){return this[Gs]}get extraModels(){return this[ja]}get availableVariants(){return this.model?this.model[of]():[]}get originalGltfJson(){return this[fl]}[(e=Gs,t=ja,n=dl,i=fl,zc)](){return()=>{this[en]()}}[Xa](o){return o.colorSpace=mt,o.wrapS=ti,o.wrapT=ti,new Jx(this[zc](),o)}async createTexture(o,c="image/png"){const{textureUtils:l}=this[ot],h=await l.loadImage(o,this.withCredentials,c),u=c==="image/ktx2"?"image/png":c;return h.userData.mimeType=u,this[Xa](h)}async createLottieTexture(o,c=1){const{textureUtils:l}=this[ot],h=await l.loadLottie(o,c,this.withCredentials);return this[Xa](h)}createVideoTexture(o){const c=document.createElement("video");c.crossOrigin=this.withCredentials?"use-credentials":"anonymous",c.src=o,c.muted=!0,c.playsInline=!0,c.loop=!0,c.play();const l=new Iv(c);return this[Xa](l)}createCanvasTexture(){const o=document.createElement("canvas"),c=new Nl(o);return this[Xa](c)}async updated(o){if(super.updated(o),o.has("variantName")){const c=this[nr].beginActivity("variant-update");c(.1);const l=this[Gs],{variantName:h}=this;l!=null&&(await l[sE](h),this[en](),this.dispatchEvent(new CustomEvent("variant-applied"))),c(1)}if(o.has("orientation")||o.has("scale")){if(!this.loaded)return;const c=this[J];c.applyTransform(),c.updateBoundingBox(),c.updateShadow(),this[ot].arRenderer.onUpdateScene(),this[en]()}}[mi](){super[mi]();const{currentGLTFs:o}=this[J],c=o.length>0?o[0]:null;if(c!=null){const{correlatedSceneGraph:h}=c;h!=null&&c!==this[dl]&&(this[Gs]=new Wm(h,this[zc]()),this[fl]=JSON.parse(JSON.stringify(h.gltf))),"variants"in c.userData&&this.requestUpdate("variantName")}this[ja]=[];const l=Array.from(this.querySelectorAll("extra-model"));for(let h=1;h{const u={binary:!0,onlyVisible:!0,maxTextureSize:1/0,includeCustomExtensions:!1,forceIndices:!1};Object.assign(u,o),u.animations=c.animations,u.truncateDrawRange=!0;const d=c.shadow;let f=!1;d!=null&&(f=d.visible,d.visible=!1),await this[Gs][iE]();const p=new Eo().register(A=>new D1(A));p.setTextureUtils({decompress:(A,g)=>B1(A,g??1/0,void 0)});let m;if(c.models.length>1){m=new ht;for(const A of c.models)m.add(A)}else m=c.models[0];p.parse(m,A=>{if(c.models.length>1)for(const g of c.models)c.target.add(g);else c.target.add(c.models[0]);return l(new Blob([u.binary?A:JSON.stringify(A)],{type:u.binary?"application/octet-stream":"application/json"}))},()=>h("glTF export failed"),u),d!=null&&(d.visible=f)})}materialFromPoint(o,c){const l=this[J],h=l.getNDC(o,c),u=l.hitFromPoint(h);if(u==null||u.face==null)return null;const d=this[Gs];if(d!=null){const f=d[rf](u);if(f!=null)return f}for(const f of this[ja]){const p=f[rf](u);if(p!=null)return p}return null}}return Ou([Re({type:String,attribute:"variant-name"})],s.prototype,"variantName",void 0),Ou([Re({type:String,attribute:"orientation"})],s.prototype,"orientation",void 0),Ou([Re({type:String,attribute:"scale"})],s.prototype,"scale",void 0),s};class mB extends at{constructor(){super(void 0,new fn({depthWrite:!1})),this.height=0,this.radius=0,this.resolution=0,this.userData.noHit=!0}get map(){return this.material.map}set map(e){this.material.map=e}isUsable(){return this.height>0&&this.radius>0&&this.geometry!=null&&this.map!=null}updateGeometry(e=this.height,t=this.radius,n=128){(e!=this.height||t!=this.radius||n!=this.resolution)&&(this.height=e,this.radius=t,this.resolution=n,e>0&&t>0&&(this.geometry.dispose(),this.geometry=bB(e,t,n)))}}function bB(r,e,t){const n=new zf(e,2*t,t);n.scale(1,1,-1);const i=n.getAttribute("position"),s=new R;for(let a=0;a0&&--this.referenceCount,this.referenceCount===0}updatePosition(e){if(e==null)return;const t=Hi(e)[0].terms;for(let n=0;n<3;++n)this.position.setComponent(n,Ai(t[n]).number);this.updateMatrixWorld()}updateNormal(e){if(e==null)return;const t=Hi(e)[0].terms;for(let n=0;n<3;++n)this.normal.setComponent(n,t[n].number)}updateSurface(){const{mesh:e,tri:t,bary:n}=this;if(e==null||t==null||n==null)return;e.getVertexPosition(t.x,Vc),e.getVertexPosition(t.y,ku),e.getVertexPosition(t.z,Qu),Vc.toArray(Wc.elements,0),ku.toArray(Wc.elements,3),Qu.toArray(Wc.elements,6),this.position.copy(n).applyMatrix3(Wc);const i=this.parent;i.worldToLocal(e.localToWorld(this.position)),qm.set(Vc,ku,Qu),qm.getNormal(this.normal).transformDirection(e.matrixWorld);const s=i.parent;jm.setFromAxisAngle(Vc.set(0,1,0),-s.rotation.y),this.normal.applyQuaternion(jm)}orient(e){this.pivotEl.style.transform=`rotate(${e}rad)`}updateVisibility(e){this.element.classList.toggle("hide",!e),this.slot.assignedNodes().forEach(t=>{if(t.nodeType!==Node.ELEMENT_NODE)return;const n=t,i=n.dataset.visibilityAttribute;if(i!=null){const s=`data-${i}`;n.toggleAttribute(s,e)}n.dispatchEvent(new CustomEvent("hotspot-visibility",{detail:{visible:e}}))}),this.initialized=!0}}const xB={name:"HorizontalBlurShader",uniforms:{tDiffuse:{value:null},h:{value:1/512}},vertexShader:` + + varying vec2 vUv; + + void main() { + + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + }`,fragmentShader:` + + uniform sampler2D tDiffuse; + uniform float h; + + varying vec2 vUv; + + void main() { + + vec4 sum = vec4( 0.0 ); + + sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051; + sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918; + sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245; + sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633; + sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531; + sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245; + sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918; + sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051; + + gl_FragColor = sum; + + }`},EB={name:"VerticalBlurShader",uniforms:{tDiffuse:{value:null},v:{value:1/512}},vertexShader:` + + varying vec2 vUv; + + void main() { + + vUv = uv; + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + + }`,fragmentShader:` + + uniform sampler2D tDiffuse; + uniform float v; + + varying vec2 vUv; + + void main() { + + vec4 sum = vec4( 0.0 ); + + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918; + sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051; + + gl_FragColor = sum; + + }`};function Xm(r,e,t){return(1-t)*r+t*e}const Km=9,_B=6,Gu=2,vB=.3;class yB extends ht{constructor(e,t,n){super(),this.camera=new rr,this.renderTarget=null,this.renderTargetBlur=null,this.depthMaterial=new bb,this.horizontalBlurMaterial=new gn(xB),this.verticalBlurMaterial=new gn(EB),this.intensity=0,this.softness=1,this.boundingBox=new dn,this.size=new R,this.maxDimension=0,this.isAnimated=!1,this.needsUpdate=!1;const{camera:i}=this;i.rotation.x=Math.PI/2,i.left=-.5,i.right=.5,i.bottom=-.5,i.top=.5,this.add(i);const s=new Hn,a=new fn({opacity:1,transparent:!0,side:an});this.floor=new at(s,a),this.floor.userData.noHit=!0,i.add(this.floor),this.blurPlane=new at(s),this.blurPlane.visible=!1,i.add(this.blurPlane),e.target.add(this),this.depthMaterial.onBeforeCompile=function(o){o.fragmentShader=o.fragmentShader.replace(/gl_FragColor\s*=\s*vec4\(\s*vec3\(\s*1\.0\s*-\s*fragCoordZ\s*\),\s*opacity\s*\);/,"gl_FragColor = vec4( vec3( 0.0 ), ( 1.0 - fragCoordZ ) * opacity );")},this.depthMaterial.side=Wt,this.horizontalBlurMaterial.depthTest=!1,this.verticalBlurMaterial.depthTest=!1,this.setScene(e,t,n)}setScene(e,t,n){const{boundingBox:i,size:s,rotation:a,position:o}=this;if(this.isAnimated=e.animationNames.length>0,this.boundingBox.copy(e.boundingBox),this.size.copy(e.size),this.maxDimension=Math.max(s.x,s.y,s.z)*(this.isAnimated?Gu:1),this.boundingBox.getCenter(o),n==="back"){const{min:c,max:l}=i;[c.y,c.z]=[c.z,c.y],[l.y,l.z]=[l.z,l.y],[s.y,s.z]=[s.z,s.y],a.x=Math.PI/2,a.y=Math.PI}else a.x=0,a.y=0;if(this.isAnimated){const c=i.min.y,l=i.max.y;s.y=this.maxDimension,i.expandByVector(s.subScalar(this.maxDimension).multiplyScalar(-.5)),i.min.y=c,i.max.y=l,s.set(this.maxDimension,l-c,this.maxDimension)}n==="bottom"?o.y=i.min.y:o.z=i.min.y,this.setSoftness(t)}setSoftness(e){this.softness=e;const{size:t,camera:n}=this,i=this.isAnimated?Gu:1,s=i*Math.pow(2,Km-e*(Km-_B));this.setMapSize(s);const a=t.y/2,o=t.y*i;n.near=0,n.far=Xm(o,a,e),this.depthMaterial.opacity=1/e,n.updateProjectionMatrix(),this.setIntensity(this.intensity),this.setOffset(0)}setMapSize(e){const{size:t}=this;this.isAnimated&&(e*=Gu);const n=Math.floor(t.x>t.z?e:e*t.x/t.z),i=Math.floor(t.x>t.z?e*t.z/t.x:e),s=10,a=s+n,o=s+i;if(this.renderTarget!=null&&(this.renderTarget.width!==a||this.renderTarget.height!==o)&&(this.renderTarget.dispose(),this.renderTarget=null,this.renderTargetBlur.dispose(),this.renderTargetBlur=null),this.renderTarget==null){const h={format:Tt};this.renderTarget=new yn(a,o,h),this.renderTargetBlur=new yn(a,o,h),this.floor.material.map=this.renderTarget.texture}const c=t.x*(1+s/n),l=t.z*(1+s/i);this.camera.left=-c/2,this.camera.right=c/2,this.camera.bottom=-l/2,this.camera.top=l/2,this.camera.scale.set(1,1,1),this.floor.scale.set(c,l,1),this.blurPlane.scale.set(c,l,1),this.needsUpdate=!0}setIntensity(e){this.intensity=e,e>0?(this.visible=!0,this.floor.visible=!0,this.floor.material.opacity=e*Xm(vB,1,this.softness*this.softness)):(this.visible=!1,this.floor.visible=!1)}getIntensity(){return this.intensity}setOffset(e){this.floor.position.z=-e+this.gap()}gap(){return .001*this.maxDimension}render(e,t){t.overrideMaterial=this.depthMaterial,this.floor.visible=!1;const n=e.xr.enabled;e.xr.enabled=!1;const i=e.getRenderTarget();e.setRenderTarget(this.renderTarget);const s=e.getClearAlpha();e.setClearAlpha(0);const a=e.state;a!=null&&(a.buffers.color.setMask(!0),a.buffers.depth.setMask(!0)),e.clear();const o=e.autoClear;e.autoClear=!1,e.render(t,this.camera),e.autoClear=o,t.overrideMaterial=null,this.floor.visible=!0,this.blurShadow(e),e.xr.enabled=n,e.setRenderTarget(i),e.setClearAlpha(s)}blurShadow(e){const{camera:t,horizontalBlurMaterial:n,verticalBlurMaterial:i,renderTarget:s,renderTargetBlur:a,blurPlane:o}=this;o.visible=!0,o.material=n,n.uniforms.h.value=1/this.renderTarget.width,n.uniforms.tDiffuse.value=this.renderTarget.texture,e.setRenderTarget(a),e.render(o,t),o.material=i,i.uniforms.v.value=1/this.renderTarget.height,i.uniforms.tDiffuse.value=this.renderTargetBlur.texture,e.setRenderTarget(s),e.render(o,t),o.visible=!1}dispose(){this.renderTarget!=null&&this.renderTarget.dispose(),this.renderTargetBlur!=null&&this.renderTargetBlur.dispose(),this.depthMaterial.dispose(),this.horizontalBlurMaterial.dispose(),this.verticalBlurMaterial.dispose(),this.floor.material.dispose(),this.floor.geometry.dispose(),this.blurPlane.geometry.dispose(),this.removeFromParent()}}const $m=10,Hu=100,zu=new R,Ym=new R,Jm=new R,qc=new qy,SB=new R,Ka=new pe;class CB extends ms{constructor({canvas:e,element:t,width:n,height:i}){super(),this.annotationRenderer=new a1,this.effectRenderer=null,this.schemaElement=document.createElement("script"),this.width=1,this.height=1,this.aspect=1,this.scaleStep=0,this.renderCount=0,this.externalRenderer=null,this.appendedAnimations=[],this.markedAnimations=[],this.camera=new Jt(45,1,.1,100),this.xrCamera=null,this.url=null,this.extraUrls=[],this.scenePivot=new ht,this.target=new ht,this.animationNames=[],this.boundingBox=new dn,this.boundingSphere=new zn,this.size=new R,this.idealAspect=0,this.framedFoVDeg=0,this.shadow=null,this.shadowIntensity=0,this.shadowSoftness=1,this.bakedShadows=new Set,this.exposure=1,this.toneMapping=ta,this.canScale=!0,this.isDirty=!1,this.goalTarget=new R,this.targetDamperX=new rn,this.targetDamperY=new rn,this.targetDamperZ=new rn,this._currentGLTFs=[],this._models=[],this.boundsAndShadowDirty=!1,this.mixers=[],this.mixerPausedStates=[],this.cancelPendingSourceChange=null,this.animationsByName=new Map,this.currentAnimationActions=[],this.groundedSkybox=new mB,this.name="ModelScene",this.element=t,this.canvas=e,this.camera=new Jt(45,1,.1,100),this.camera.name="MainCamera",this.add(this.scenePivot),this.scenePivot.name="Pivot",this.scenePivot.add(this.target),this.setSize(n,i),this.target.name="Target",this.mixers=[];const{domElement:s}=this.annotationRenderer,{style:a}=s;a.display="none",a.pointerEvents="none",a.position="absolute",a.top="0",this.element.shadowRoot.querySelector(".default").appendChild(s),this.schemaElement.setAttribute("type","application/ld+json")}get context(){return this.canvas.getContext("2d")}getCamera(){return this.xrCamera!=null?this.xrCamera:this.camera}queueRender(){this.isDirty=!0}shouldRender(){return this.isDirty}hasRendered(){this.isDirty=!1}forceRescale(){this.scaleStep=-1,this.queueRender()}async setObject(e){this.reset(),this._models=[e],this.target.add(e),await this.setupScene()}async setSource(e,t=[],n=()=>{}){if((!e||e===this.url)&&t.join(",")===this.extraUrls.join(",")){n(1);return}if(this.reset(),this.url=e,this.extraUrls=t,this.externalRenderer!=null){const c=await this.externalRenderer.load(n);this.boundingSphere.radius=c.framedRadius,this.idealAspect=c.fieldOfViewAspect;return}this.cancelPendingSourceChange!=null&&(this.cancelPendingSourceChange(),this.cancelPendingSourceChange=null);let i=[];try{const c=[];e&&c.push(e),t&&c.push(...t),c.length>0&&(i=await new Promise((l,h)=>{this.cancelPendingSourceChange=()=>h(),(async()=>{try{const u=await Promise.all(c.map(d=>this.element[ot].loader.load(d,this.element,n)));l(u)}catch(u){h(u)}})()}))}catch(c){if(c==null)return;throw c}this.cancelPendingSourceChange=null,this.reset(),this.url=e,this.extraUrls=t,this._currentGLTFs=i;for(const c of i)c!=null?(this._models.push(c.scene),this.target.add(c.scene),this.mixers.push(new mA(c.scene)),this.mixerPausedStates.push(!1),this.currentAnimationActions.push(null)):(this.mixers.push(new mA(this.target)),this.mixerPausedStates.push(!1),this.currentAnimationActions.push(null));const s=new Map,a=[],o=[];for(const c of i)for(const l of c.animations||[])s.set(l.name,l),a.push(l.name),o.push(l);this.animations=o,this.animationsByName=s,this.animationNames=a,await this.setupScene()}async setupScene(){this.applyTransform(),this.updateBoundingBox(),await this.updateFraming(),this.updateShadow(),this.setShadowIntensity(this.shadowIntensity),this.setGroundedSkybox()}updateModelTransforms(e,t,n,i){const s=this._models[e];if(s){if(t){const a=t.split(" ").map(o=>o.trim()).filter(o=>o.length>0).map(Number);a.length===3&&!a.some(isNaN)&&s.position.set(a[0],a[1],a[2])}if(i){const a=i.split(" ").map(o=>o.trim()).filter(o=>o.length>0).map(Number);a.length===1&&!isNaN(a[0])?s.scale.setScalar(a[0]):a.length===3&&!a.some(isNaN)&&s.scale.set(a[0],a[1],a[2])}s.updateMatrixWorld(!0),this.boundsAndShadowDirty=!0,this.queueRender()}}updateBoundingBoxAndShadowIfDirty(){this.boundsAndShadowDirty&&(this.boundsAndShadowDirty=!1,this.updateBoundingBox(),this.updateShadow())}reset(){this.url=null,this.renderCount=0,this.queueRender(),this.shadow!=null&&this.shadow.setIntensity(0),this.bakedShadows.clear();const{_models:e}=this;for(const n of e)n?.removeFromParent();this._models=[];const t=this._currentGLTFs;for(const n of t)n?.dispose();this._currentGLTFs=[];for(const n of this.currentAnimationActions)n?.stop();this.currentAnimationActions=[];for(const n of this.mixers)n.stopAllAction(),n.uncacheRoot(this);this.mixers=[],this.mixerPausedStates=[]}dispose(){this.reset(),this.shadow!=null&&(this.shadow.dispose(),this.shadow=null),this.element[dl]=null,this.element[fl]=null,this.element[Gs]=null}get currentGLTF(){return this._currentGLTFs[0]||null}get currentGLTFs(){return this._currentGLTFs}setSize(e,t){if(!(this.width===e&&this.height===t)){if(this.width=Math.max(e,1),this.height=Math.max(t,1),this.annotationRenderer.setSize(e,t),this.aspect=this.width/this.height,this.externalRenderer!=null){const n=window.devicePixelRatio;this.externalRenderer.resize(e*n,t*n)}this.queueRender()}}markBakedShadow(e){e.userData.noHit=!0,this.bakedShadows.add(e)}unmarkBakedShadow(e){e.userData.noHit=!1,e.visible=!0,this.bakedShadows.delete(e),this.boundingBox.expandByObject(e)}findBakedShadows(e){const t=new dn;e.traverse(n=>{const i=n;if(!i.material||!i.material.transparent)return;t.setFromObject(i);const a=t.getSize(SB),o=Math.min(a.x,a.y,a.z);Math.max(a.x,a.y,a.z)=t.x&&n.min.z<=e.z&&n.max.z>=t.z)&&(n.min.z=t.x&&n.min.y<=e.y&&n.max.y>=t.y||this.unmarkBakedShadow(i))}applyTransform(){const{models:e}=this;if(e.length===0)return;const t=Hi(this.element.orientation)[0].terms,n=Ai(t[0]).number,i=Ai(t[1]).number,s=Ai(t[2]).number,a=Hi(this.element.scale)[0].terms;for(const o of e)o.quaternion.setFromEuler(new Gn(i,s,n,"YXZ")),o.scale.set(a[0].number,a[1].number,a[2].number)}updateBoundingBox(){const{models:e}=this;if(e.length===0)return;for(const i of e)this.target.remove(i),this.findBakedShadows(i);const t=(i,s)=>i.expandByPoint(s);this.setBakedShadowVisibility(!1);let n=new dn;for(const i of e)n=Ic(i,t,n);if(this.boundingBox=n,this.boundingBox.isEmpty()){this.setBakedShadowVisibility(!0),this.bakedShadows.forEach(i=>this.unmarkBakedShadow(i)),n=new dn;for(const i of e)n=Ic(i,t,n);this.boundingBox=n}this.checkBakedShadows(),this.setBakedShadowVisibility(),this.boundingBox.getSize(this.size);for(const i of e)this.target.add(i)}async updateFraming(){const{models:e}=this;if(e.length===0)return;for(const o of e)this.target.remove(o);this.setBakedShadowVisibility(!1);const{center:t}=this.boundingSphere;this.element.requestUpdate("cameraTarget"),await this.element.updateComplete,t.copy(this.getTarget());const n=(o,c)=>Math.max(o,t.distanceToSquared(c));let i=0;for(const o of e)i=Math.max(i,Ic(o,n,0));this.boundingSphere.radius=Math.sqrt(i);const s=(o,c)=>{c.sub(t);const l=Math.sqrt(c.x*c.x+c.z*c.z);return Math.max(o,l/(this.idealCameraDistance()-Math.abs(c.y)))};let a=0;for(const o of e)a=Math.max(a,Ic(o,s,0));this.idealAspect=a/Math.tan(this.framedFoVDeg/2*Math.PI/180),this.setBakedShadowVisibility();for(const o of e)this.target.add(o)}setBakedShadowVisibility(e=this.shadowIntensity<=0){for(const t of this.bakedShadows)t.visible=e}idealCameraDistance(){const e=this.framedFoVDeg/2*Math.PI/180;return this.boundingSphere.radius/Math.sin(e)}adjustedFoV(e){const t=Math.tan(e/2*Math.PI/180)*Math.max(1,this.idealAspect/this.aspect);return 2*Math.atan(t)*180/Math.PI}getNDC(e,t){if(this.xrCamera!=null)Ka.set(e/window.screen.width,t/window.screen.height);else{const n=this.element.getBoundingClientRect();Ka.set((e-n.x)/this.width,(t-n.y)/this.height)}return Ka.multiplyScalar(2).subScalar(1),Ka.y*=-1,Ka}getSize(){return{width:this.width,height:this.height}}setEnvironmentAndSkybox(e,t){this.element[ot].arRenderer.presentedScene!==this&&(this.environment=e,this.setBackground(t),this.queueRender())}setBackground(e){this.groundedSkybox.map=e,this.groundedSkybox.isUsable()?(this.target.add(this.groundedSkybox),this.background=null):(this.target.remove(this.groundedSkybox),this.background=e)}farRadius(){return this.boundingSphere.radius*(this.groundedSkybox.parent!=null?$m:1)}setGroundedSkybox(){const e=Hi(this.element.skyboxHeight)[0].terms[0],t=Ai(e).number,n=$m*this.boundingSphere.radius;this.groundedSkybox.updateGeometry(t,n),this.groundedSkybox.position.y=t-(this.shadow?2*this.shadow.gap():0),this.setBackground(this.groundedSkybox.map)}setTarget(e,t,n){this.goalTarget.set(-e,-t,-n)}setTargetDamperDecayTime(e){this.targetDamperX.setDecayTime(e),this.targetDamperY.setDecayTime(e),this.targetDamperZ.setDecayTime(e)}getTarget(){return this.goalTarget.clone().multiplyScalar(-1)}getDynamicTarget(){return this.target.position.clone().multiplyScalar(-1)}jumpToGoal(){this.updateTarget(Bx)}updateTarget(e){const t=this.goalTarget,n=this.target.position;if(t.equals(n))return!1;{const i=this.boundingSphere.radius/10;let{x:s,y:a,z:o}=n;return s=this.targetDamperX.update(s,t.x,e,i),a=this.targetDamperY.update(a,t.y,e,i),o=this.targetDamperZ.update(o,t.z,e,i),this.groundedSkybox.position.x=-s,this.groundedSkybox.position.z=-o,this.target.position.set(s,a,o),this.target.updateMatrixWorld(),this.queueRender(),!0}}pointTowards(e,t){const{x:n,z:i}=this.position;this.yaw=Math.atan2(e-n,t-i)}get model(){return this._models[0]||null}get models(){return this._models}set yaw(e){this.scenePivot.rotation.y=e,this.groundedSkybox.rotation.y=-e,this.queueRender()}get yaw(){return this.scenePivot.rotation.y}set animationTime(e){for(const t of this.mixers)t.setTime(e);this.queueShadowRender()}get animationTime(){let e=0;for(const t of this.currentAnimationActions)if(t!=null){let n=t.time;const i=Math.max(t._loopCount,0);t.loop===wl&&(i&1)===1&&(n=(t.getClip()?t.getClip().duration:0)-t.time),n>e&&(e=n)}return e}set animationTimeScale(e){for(const t of this.mixers)t.timeScale=e}get animationTimeScale(){return this.mixers.length>0?this.mixers[0].timeScale:1}get duration(){let e=0;for(const t of this.currentAnimationActions)if(t!=null&&t.getClip()){const n=t.getClip().duration;n>e&&(e=n)}return e}get hasActiveAnimation(){return this.currentAnimationActions.some(e=>e!=null)}playAnimation(e=null,t=0,n=Xr,i=1/0,s=null){const a=s??0,o=s!=null?s+1:this._models.length;for(let c=a;c=0;d--)if(h[d].name===e){u=h[d];break}if(u==null){const d=parseInt(e);!isNaN(d)&&d>=0&&d0&&this.animationTime==this.duration&&(this.animationTime=0)),p.setLoop(n,i),p.enabled=!0,p.clampWhenFinished=!0,p.play()}catch(d){console.error(d)}}}appendAnimation(e="",t=Xr,n=1/0,i=1,s=1,a=!1,o=!1,c=!0,l=null,h=!1,u=null){if(this.currentGLTF==null||e===this.element.animationName)return;const{animations:d}=this;if(d==null||d.length===0)return;const f=e?this.animationsByName.get(e):null;if(f==null)return;if(typeof n=="string"?isNaN(parseFloat(n))?(n=1/0,console.warn(`Invalid repetitionCount value: ${n}. Using default: Infinity`)):(parseInt(n)<1&&console.warn(`Invalid repetitionCount value: ${n}. Using 1 as minimum.`),n=Math.max(parseInt(n),1)):typeof n=="number"&&n<1?(n=1,console.warn(`Invalid repetitionCount value: ${n}. Using 1 value as minimum.`)):console.warn(`Invalid repetitionCount value: ${n}. Using default: Infinity`),n===1&&t!==Ro&&(t=Ro),typeof i=="string"){const x=parseFloat(i);isNaN(x)||x<0||x>1?(i=1,console.warn(`Invalid weight value: ${i}. Using default: 1`)):i=x}if(typeof s=="string"){const x=parseFloat(s);isNaN(x)||x<0?(s=1,console.warn(`Invalid timeScale value: ${s}. Using default: 1`)):s=x}if(typeof l=="string"){const x=parseFloat(l);isNaN(x)?(l=null,console.warn(`Invalid time value: ${l}. Using default: 0 or previous time`)):l=x}const{shouldFade:p,duration:m}=this.parseFadeValue(a,!1,1.25),A=1.25;let g=!1,b=0;typeof o=="boolean"?(g=o,b=o?A:0):typeof o=="number"?(g=o>0,b=Math.max(o,0),o<0&&console.warn(`Invalid warp value: ${o}. Using default: false`)):typeof o=="string"&&(o.toLowerCase().trim()==="true"?(g=!0,b=A):o.toLowerCase().trim()==="false"?g=!1:isNaN(parseFloat(o))?console.warn(`Invalid warp value: ${o}. Using default: false`):(b=Math.max(parseFloat(o),0),g=b>0,b<=0&&console.warn(`Invalid warp value: ${o}. Using default: false`)));try{h&&this.appendedAnimations.includes(e)&&(this.markedAnimations.map(v=>v.name).includes(e)||this.markedAnimations.push({name:e,loopMode:t,repetitionCount:n}));const x=u??0,_=u!=null?u+1:this.mixers.length;for(let v=x;v<_;v++){const S=this.mixers[v],I=S.existingAction(f)||S.clipAction(f,this._models[v]||this),E=I.timeScale;typeof l=="number"&&(I.time=Math.min(Math.max(l,0),f.duration)),p?I.fadeIn(m):i>=0&&(I.weight=Math.min(Math.max(i,0),1)),g?I.warp(c?E:0,s,b):I.timeScale=s,I.isRunning()||(I.time==f.duration&&I.stop(),I.setLoop(t,n),I.paused=!1,I.enabled=!0,I.clampWhenFinished=!0,I.play())}this.appendedAnimations.includes(e)||this.element[J].appendedAnimations.push(e)}catch(x){console.error(x)}}parseFadeValue(e,t=!0,n=1.5){const i=s=>s.toLowerCase().trim();if(typeof e=="boolean")return{shouldFade:e,duration:e?n:0};if(typeof e=="number"){const s=Math.max(e,0);return{shouldFade:s>0,duration:s}}if(typeof e=="string"){const s=i(e);if(s==="true")return{shouldFade:!0,duration:n};if(s==="false")return{shouldFade:!1,duration:0};const a=parseFloat(s);if(!isNaN(a)){const o=Math.max(a,0);return{shouldFade:o>0,duration:o}}}return console.warn(`Invalid fade value: ${e}. Using default: ${t}`),{shouldFade:t,duration:t?n:0}}detachAnimation(e="",t=!0,n=null){if(this.currentGLTF==null||e===this.element.animationName)return;const{animations:i}=this;if(i==null||i.length===0)return;const s=e?this.animationsByName.get(e):null;if(s==null)return;const{shouldFade:a,duration:o}=this.parseFadeValue(t,!0,1.5);try{const c=n??0,l=n!=null?n+1:this.mixers.length;for(let h=c;hh!==e)}catch(c){console.error(c)}}updateAnimationLoop(e="",t=Xr,n=1/0,i=null){if(this.currentGLTF==null||e===this.element.animationName)return;const{animations:s}=this;if(s==null||s.length===0)return;let a=null;if(e&&(a=this.animationsByName.get(e)),a!=null)try{const o=i??0,c=i!=null?i+1:this.mixers.length;for(let l=o;le)}pauseAnimation(e=null){const t=e??0,n=e!=null?e+1:this.mixers.length;for(let i=t;in.object.visible&&!n.object.userData.noHit)}hitFromController(e,t=this){return qc.setFromXRController(e),this.getHit(t)}hitFromPoint(e,t=this){return qc.setFromCamera(e,this.getCamera()),this.getHit(t)}getModelIndexFromHit(e){let t=e.object;for(;t!=null;){const n=this.models.indexOf(t);if(n!==-1)return n;t=t.parent}return 0}positionAndNormalFromPoint(e,t=this){var n;const i=this.hitFromPoint(e,t);if(i==null)return null;const s=i.point,a=i.face!=null?i.face.normal.clone().applyNormalMatrix(new Qe().getNormalMatrix(i.object.matrixWorld)):qc.ray.direction.clone().multiplyScalar(-1),o=(n=i.uv)!==null&&n!==void 0?n:null,c=this.getModelIndexFromHit(i),l=this.models[c]||this.target,h=new Oe().copy(l.matrixWorld).invert();return{position:s,normal:a,uv:o,modelIndex:c,worldToModel:h}}surfaceFromPoint(e,t=this){var n;const i=this.hitFromPoint(e,t);if(i==null||i.face==null)return null;const s=this.getModelIndexFromHit(i),a=s===0?this.element.model:(n=this.element.extraModels)===null||n===void 0?void 0:n[s-1];if(a==null)return null;const o=a[af](i);if(o==null)return null;const{meshes:c,primitives:l}=o.mesh.userData.associations,h=new R,u=new R,d=new R,{a:f,b:p,c:m}=i.face,A=i.object;A.getVertexPosition(f,h),A.getVertexPosition(p,u),A.getVertexPosition(m,d);const g=new wn(h,u,d),b=new R;g.getBarycoord(A.worldToLocal(i.point),b),g.getBarycoord(A.worldToLocal(i.point),b);const x=`${c} ${l} ${f} ${p} ${m} ${b.x.toFixed(3)} ${b.y.toFixed(3)} ${b.z.toFixed(3)}`;return s===0?x:`${s} ${x}`}updateHotspotAttachment(e){const t=e.modelIndex!=null&&e.modelIndex>0&&this._models[e.modelIndex]?this._models[e.modelIndex]:this.target;e.parent!==t&&(t.add(e),e.updatePosition(e.position.toArray().join(" ")+"m"),e.updateMatrixWorld(!0))}addHotspot(e){this.updateHotspotAttachment(e),this.annotationRenderer.domElement.appendChild(e.element),this.updateSurfaceHotspot(e)}removeHotspot(e){e.parent&&e.parent.remove(e)}forHotspots(e){const t=[...this.target.children];for(let n=0,i=t.length;n=u||d.y>=u||d.z>=u){console.warn(e.surface+" vertex indices out of range in this glTF! Skipping this hotspot.");return}const f=new R(i[5+o].number,i[6+o].number,i[7+o].number);e.mesh=h.mesh,e.tri=d,e.bary=f,e.updateSurface()}animateSurfaceHotspots(){this.element.paused||this.forHotspots(e=>{e.updateSurface()})}updateHotspotsVisibility(e){this.forHotspots(t=>{zu.copy(e),Ym.setFromMatrixPosition(t.matrixWorld),zu.sub(Ym),Jm.copy(t.normal).transformDirection(this.target.matrixWorld),zu.dot(Jm)<0?t.hide():t.show()})}orientHotspots(e){this.forHotspots(t=>{t.orient(e)})}setHotspotsVisibility(e){this.forHotspots(t=>{t.visible=e})}updateSchema(e){var t;const{schemaElement:n,element:i}=this,{alt:s,poster:a,iosSrc:o}=i;if(e!=null){const c=[{"@type":"MediaObject",contentUrl:e,encodingFormat:((t=e.split(".").pop())===null||t===void 0?void 0:t.toLowerCase())==="gltf"?"model/gltf+json":"model/gltf-binary"}];o&&c.push({"@type":"MediaObject",contentUrl:o,encodingFormat:"model/vnd.usdz+zip"});const l={"@context":"http://schema.org/","@type":"3DModel",image:a??void 0,name:s??void 0,encoding:c};n.textContent=JSON.stringify(l),document.head.appendChild(n)}else n.parentElement!=null&&n.parentElement.removeChild(n)}}class MB extends EventTarget{constructor(){super(...arguments),this.ongoingActivities=new Set,this.totalProgress=0}get ongoingActivityCount(){return this.ongoingActivities.size}beginActivity(e){const t={progress:0,completed:!1};return this.ongoingActivities.add(t),this.ongoingActivityCount===1&&this.announceTotalProgress(t,0,e),n=>{let i;return i=Math.max(fi(n,0,1),t.progress),i!==t.progress&&this.announceTotalProgress(t,i,e),t.progress}}announceTotalProgress(e,t,n){let i=0,s=0;t==1&&(e.completed=!0);for(const c of this.ongoingActivities){const{progress:l}=c;i+=1-l,c.completed&&s++}const a=e.progress;e.progress=t,this.totalProgress+=(t-a)*(1-this.totalProgress)/i;const o=s===this.ongoingActivityCount?1:this.totalProgress;this.dispatchEvent(new CustomEvent("progress",{detail:{totalProgress:o,reason:n}})),s===this.ongoingActivityCount&&(this.totalProgress=0,this.ongoingActivities.clear())}}var ah=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var o=r.length-1;o>=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s},Zm,e0,t0,n0,i0,s0,r0,a0,o0,c0,l0,h0,u0,d0,f0;const IB=10,wB=50,TB=0,RB=300,BB=150,ps=document.createElement("canvas"),Vu=Symbol("fallbackResizeHandler"),p0=Symbol("defaultAriaLabel"),jc=Symbol("resizeObserver"),Fr=Symbol("clearModelTimeout"),Wu=Symbol("onContextLost"),Ls=Symbol("loaded"),qu=Symbol("status"),ju=Symbol("onFocus"),Xu=Symbol("onBlur"),Ku=Symbol("onSlotChange"),$u=Symbol("onExtraModelChanged"),Qr=Symbol("updateSize"),Xc=Symbol("intersectionObserver"),Hs=Symbol("isElementInViewport"),Ql=Symbol("announceModelVisibility"),Wr=Symbol("ariaLabel"),lf=Symbol("altDefaulted"),$a=Symbol("statusElement"),Gl=Symbol("updateStatus"),ho=Symbol("loadedTime"),cs=Symbol("updateSource"),A0=Symbol("markLoaded"),pl=Symbol("container"),$n=Symbol("input"),hf=Symbol("canvas"),J=Symbol("scene"),en=Symbol("needsRender"),gi=Symbol("tick"),mi=Symbol("onModelLoad"),Hl=Symbol("onResize"),ot=Symbol("renderer"),nr=Symbol("progressTracker"),g0=Symbol("getLoaded"),ir=Symbol("getModelIsVisible"),pa=Symbol("shouldAttemptPreload"),ls=r=>({x:r.x,y:r.y,z:r.z,toString(){return`${this.x}m ${this.y}m ${this.z}m`}}),uf=r=>({u:r.x,v:r.y,toString(){return`${this.u} ${this.v}`}});class Vo extends as{static get is(){return"model-viewer"}static set modelCacheSize(e){_n[rs].evictionThreshold=e}static get modelCacheSize(){return _n[rs].evictionThreshold}static set minimumRenderScale(e){e>1&&console.warn(" minimumRenderScale has been clamped to a maximum value of 1."),e<=0&&console.warn(" minimumRenderScale has been clamped to a minimum value of 0.25."),On.singleton.minScale=e}static get minimumRenderScale(){return On.singleton.minScale}get loaded(){return this[g0]()}get[(Zm=Hs,e0=Ls,t0=ho,n0=qu,i0=Fr,s0=Ku,r0=$u,a0=Vu,o0=Ql,c0=jc,l0=Xc,h0=nr,ot)](){return On.singleton}get modelIsVisible(){return this[ir]()}constructor(){super(),this.alt=null,this.src=null,this.withCredentials=!1,this.generateSchema=!1,this[Zm]=!1,this[e0]=!1,this[t0]=0,this[n0]="",this[i0]=null,this[s0]=()=>{if(!this[J])return;const i=Array.from(this.querySelectorAll("extra-model")),s=i.map(o=>o.src).filter(o=>o!=null),a=this[J].extraUrls||[];(s.join(",")!==a.join(",")||i.length!==a.length)&&this[cs]()},this[r0]=i=>{const s=i,a=s.target,c=Array.from(this.querySelectorAll("extra-model")).indexOf(a);if(console.log(`[onExtraModelChanged] childIndex: ${c} srcChanged: ${s.detail.srcChanged} offset: ${s.detail.offset}`),c===-1)return;const l=this.src?c+1:c;s.detail.srcChanged?(this[Ls]=!1,this[cs]()):this[J]&&this[J].updateModelTransforms(l,s.detail.offset,s.detail.orientation,s.detail.scale)},this[a0]=jA(()=>{const i=this.getBoundingClientRect();this[Qr](i)},wB),this[o0]=jA(i=>{const s=this.modelIsVisible;s!==i&&this.dispatchEvent(new CustomEvent("model-visibility",{detail:{visible:s}}))},TB),this[c0]=null,this[l0]=null,this[h0]=new MB,this[u0]=()=>{this[$a].textContent=this[qu]},this[d0]=()=>{this[$a].textContent=""},this[f0]=i=>{this.dispatchEvent(new CustomEvent("error",{detail:{type:"webglcontextlost",sourceError:i.sourceEvent}}))},this.attachShadow({mode:"open"});const e=this.shadowRoot;iT(e),this[pl]=e.querySelector(".container"),this[$n]=e.querySelector(".userInput"),this[hf]=e.querySelector("canvas"),this[$a]=e.querySelector("#status"),this[p0]=this[$n].getAttribute("aria-label");let t,n;if(this.isConnected){const i=this.getBoundingClientRect();t=i.width,n=i.height}else t=RB,n=BB;this[J]=new CB({canvas:this[hf],element:this,width:t,height:n}),Promise.resolve().then(()=>{this[Qr](this.getBoundingClientRect())}),Kh&&(this[jc]=new ResizeObserver(i=>{if(!this[ot].isPresenting)for(let s of i)s.target===this&&this[Qr](s.contentRect)})),$h?this[Xc]=new IntersectionObserver(i=>{for(let s of i)if(s.target===this){const a=this.modelIsVisible;this[Hs]=s.isIntersecting,this[Ql](a),console.log(`IntersectionObserver fired! isIntersecting: ${s.isIntersecting}`),this[Hs]&&!this.loaded&&this[cs]()}},{root:null,rootMargin:"0px",threshold:1e-5}):this[Hs]=!0}connectedCallback(){super.connectedCallback&&super.connectedCallback(),Kh?this[jc].observe(this):self.addEventListener("resize",this[Vu]),$h&&this[Xc].observe(this),this.addEventListener("focus",this[ju]),this.addEventListener("blur",this[Xu]),this.addEventListener("extra-model-changed",this[$u]);const e=this.shadowRoot.querySelector(".slot.default slot");e&&e.addEventListener("slotchange",this[Ku]);const t=this[ot];t.addEventListener("contextlost",this[Wu]),t.registerScene(this[J]),this[Fr]!=null&&(self.clearTimeout(this[Fr]),this[Fr]=null,this.requestUpdate("src",null))}disconnectedCallback(){super.disconnectedCallback&&super.disconnectedCallback(),Kh?this[jc].unobserve(this):self.removeEventListener("resize",this[Vu]),$h&&this[Xc].unobserve(this),this.removeEventListener("focus",this[ju]),this.removeEventListener("blur",this[Xu]),this.removeEventListener("extra-model-changed",this[$u]);const e=this.shadowRoot.querySelector(".slot.default slot");e&&e.removeEventListener("slotchange",this[Ku]);const t=this[ot];t.removeEventListener("contextlost",this[Wu]),t.unregisterScene(this[J]),this[Fr]=self.setTimeout(()=>{this[J].dispose(),this[Fr]=null},IB)}updated(e){if(super.updated(e),e.has("src")){const t=Array.from(this.querySelectorAll("extra-model")),i=t.map(s=>s.src).filter(s=>s!=null).join(",")===(this[J].extraUrls||[]).join(",");this.src==null&&t.length===0?(this[Ls]=!1,this[ho]=0,this[J].reset()):(this.src!==this[J].url||!i)&&(this[Ls]=!1,this[ho]=0,this[cs]())}if(e.has("alt")&&this[$n].setAttribute("aria-label",this[Wr]),e.has("generateSchema"))if(this.generateSchema){const n=Array.from(this.querySelectorAll("extra-model")).map(s=>s.src).filter(s=>s!=null),i=this.src||n[0]||null;this[J].updateSchema(i)}else this[J].updateSchema(null)}toDataURL(e,t){return this[ot].displayCanvas(this[J]).toDataURL(e,t)}async toBlob(e){const t=e?e.mimeType:void 0,n=e?e.qualityArgument:void 0,i=e?e.idealAspect:void 0,{width:s,height:a,idealAspect:o,aspect:c}=this[J],{dpr:l,scaleFactor:h}=this[ot];let u=s*h*l,d=a*h*l,f=0,p=0;if(i===!0)if(o>c){const m=d;d=Math.round(u/o),p=(m-d)/2}else{const m=u;u=Math.round(d*o),f=(m-u)/2}ps.width=u,ps.height=d;try{return new Promise(async(m,A)=>{ps.getContext("2d").drawImage(this[ot].displayCanvas(this[J]),f,p,u,d,0,0,u,d),ps.toBlob(g=>{if(!g)return A(new Error("Unable to retrieve canvas blob"));m(g)},t,n)})}finally{this[Qr]({width:s,height:a})}}registerEffectComposer(e){e.setRenderer(this[ot].threeRenderer),e.setMainCamera(this[J].getCamera()),e.setMainScene(this[J]),this[J].effectRenderer=e}unregisterEffectComposer(){this[J].effectRenderer=null}registerRenderer(e){this[J].externalRenderer=e}unregisterRenderer(){this[J].externalRenderer=null}get[Wr](){return this[lf]}get[lf](){return this.alt==null||this.alt==="null"?this[p0]:this.alt}[g0](){return this[Ls]}[ir](){return this.loaded&&this[Hs]}[pa](){const e=Array.from(this.querySelectorAll("extra-model"));return!!(this.src||e.length>0)&&this[Hs]}[Qr]({width:e,height:t}){e===0||t===0||(this[pl].style.width=`${e}px`,this[pl].style.height=`${t}px`,this[Hl]({width:e,height:t}))}[gi](e,t){var n;(n=this[J].effectRenderer)===null||n===void 0||n.beforeRender(e,t)}[A0](){this[Ls]||(this[Ls]=!0,this[ho]=performance.now())}[en](){this[J].queueRender()}[mi](){}[Gl](e){this[qu]=e;const t=this.getRootNode();t!=null&&t.activeElement===this&&this[$a].textContent!=e&&(this[$a].textContent=e)}[(u0=ju,d0=Xu,Hl)](e){this[J].setSize(e.width,e.height)}async[(f0=Wu,cs)](){const e=this[J],n=Array.from(this.querySelectorAll("extra-model")).map(c=>c.src).filter(c=>c!=null),i=n.join(",")===(e.extraUrls||[]).join(",");if(console.log(`[$updateSource] called! +src: ${this.src} +extraUrls: ${n.join(",")} +loaded: ${this.loaded}`),this.loaded||!this[pa]()||this.src===e.url&&i){console.log("[$updateSource] BAILING OUT EARLY!");return}const s=this.src,a=s||n[0]||null;this.generateSchema&&e.updateSchema(a),this[Gl]("Loading"),e.stopAnimation();const o=this[nr].beginActivity("model-load");try{const c=e.setSource(s,n,u=>o(fi(u,0,1)*.95)),l=this[Ul]();await Promise.all([c,l]),Array.from(this.querySelectorAll("extra-model")).forEach((u,d)=>{const f=this.src?d+1:d;this[J].updateModelTransforms(f,u.offset,u.orientation,u.scale)}),this[A0](),this[mi](),this.updateComplete.then(()=>{this.dispatchEvent(new CustomEvent("before-render"))}),await new Promise(u=>{const d=setTimeout(()=>{console.warn("rAF timed out in updateSource"),u()},500);requestAnimationFrame(()=>{requestAnimationFrame(()=>{clearTimeout(d),u()})})}),this.dispatchEvent(new CustomEvent("load",{detail:{url:a}}))}catch(c){this.dispatchEvent(new CustomEvent("error",{detail:{type:"loadfailure",sourceError:c}}))}finally{o(1)}}}ah([Re({type:String})],Vo.prototype,"alt",void 0);ah([Re({type:String})],Vo.prototype,"src",void 0);ah([Re({type:Boolean,attribute:"with-credentials"})],Vo.prototype,"withCredentials",void 0);ah([Re({type:Boolean,attribute:"generate-schema"})],Vo.prototype,"generateSchema",void 0);var Yu=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var o=r.length-1;o>=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};const m0=1e3,Kc=Symbol("changeAnimation"),b0=Symbol("appendAnimation"),x0=Symbol("detachAnimation"),Ps=Symbol("paused"),DB={repetitions:1/0,pingpong:!1},LB={pingpong:!1,repetitions:null,weight:1,timeScale:1,fade:!1,warp:!1,relativeWarp:!0,time:null},PB={fade:!0},FB=r=>{var e;class t extends r{constructor(...i){super(i),this.autoplay=!1,this.animationName=void 0,this.animationCrossfadeDuration=300,this[e]=!0,this[J].subscribeMixerEvent("loop",s=>{const a=s.action._loopCount,o=s.action._clip.name,c=s.action._clip.uuid,l=this[J].markedAnimations.find(h=>h.name===o);if(l){this[J].updateAnimationLoop(l.name,l.loopMode,l.repetitionCount);const h=this[J].markedAnimations.filter(u=>u.name!==o);this[J].markedAnimations=h}this.dispatchEvent(new CustomEvent("loop",{detail:{count:a,name:o,uuid:c}}))}),this[J].subscribeMixerEvent("finished",s=>{if(!this[J].appendedAnimations.includes(s.action._clip.name))this[Ps]=!0;else{const a=this[J].appendedAnimations.filter(o=>o!==s.action._clip.name);this[J].appendedAnimations=a}this.dispatchEvent(new CustomEvent("finished"))})}get availableAnimations(){return this.loaded?this[J].animationNames:[]}get duration(){return this[J].duration}get paused(){return this[J].isAllAnimationsPaused()}get currentTime(){return this[J].animationTime}get appendedAnimations(){return this[J].appendedAnimations}set currentTime(i){this[J].animationTime=i,this[en]()}get timeScale(){return this[J].animationTimeScale}set timeScale(i){this[J].animationTimeScale=i}pause(i){var s;if(i?.modelIndex==null&&this.paused)return;const a=(s=i?.modelIndex)!==null&&s!==void 0?s:null;this[J].pauseAnimation(a),this.dispatchEvent(new CustomEvent("pause"))}play(i){var s;if(this.availableAnimations.length>0){const a=(s=i?.modelIndex)!==null&&s!==void 0?s:null;this[J].unpauseAnimation(a),this[Kc](i),this.dispatchEvent(new CustomEvent("play"))}}appendAnimation(i,s){var a;this.availableAnimations.length>0&&(this[Ps]=!1,this[J].unpauseAnimation((a=s?.modelIndex)!==null&&a!==void 0?a:null),this[b0](i,s),this.dispatchEvent(new CustomEvent("append-animation")))}detachAnimation(i,s){var a;this.availableAnimations.length>0&&(this[Ps]=!1,this[J].unpauseAnimation((a=s?.modelIndex)!==null&&a!==void 0?a:null),this[x0](i,s),this.dispatchEvent(new CustomEvent("detach-animation")))}[(e=Ps,mi)](){super[mi](),this[J].pauseAnimation(),this.animationName!=null&&this[Kc](),this.autoplay&&this.play()}[gi](i,s){super[gi](i,s),!(this.paused||!this[ir]()&&!this[ot].isPresenting)&&(this[J].updateAnimation(s/m0),this[en]())}updated(i){super.updated(i),i.has("autoplay")&&this.autoplay&&this.play(),i.has("animationName")&&this[Kc]()}[Kc](i=DB){var s;const a=(s=i.repetitions)!==null&&s!==void 0?s:1/0,o=i.pingpong?wl:a===1?Ro:Xr;this[J].playAnimation(this.animationName,this.animationCrossfadeDuration/m0,o,a,i.modelIndex),this[Ps]&&(this[J].updateAnimation(0),this[en]())}[b0](i="",s={}){var a;const o=Object.assign(Object.assign({},LB),s),c=(a=o.repetitions)!==null&&a!==void 0?a:1/0,l=o.pingpong?wl:c===1?Ro:Xr,h=!!s.repetitions||"pingpong"in s;this[J].appendAnimation(i||this.animationName,l,c,o.weight,o.timeScale,o.fade,o.warp,o.relativeWarp,o.time,h,o.modelIndex),this[Ps]&&(this[J].updateAnimation(0),this[en]())}[x0](i="",s={}){const a=Object.assign(Object.assign({},PB),s);this[J].detachAnimation(i||this.animationName,a.fade,a.modelIndex),this[Ps]&&(this[J].updateAnimation(0),this[en]())}}return Yu([Re({type:Boolean})],t.prototype,"autoplay",void 0),Yu([Re({type:String,attribute:"animation-name"})],t.prototype,"animationName",void 0),Yu([Re({type:Number,attribute:"animation-crossfade-duration"})],t.prototype,"animationCrossfadeDuration",void 0),t};const Fs=Symbol("hotspotMap"),Ju=Symbol("mutationCallback"),Ya=Symbol("observer"),Zu=Symbol("addHotspot"),E0=Symbol("removeHotspot"),NB=r=>{var e,t,n;class i extends r{constructor(){super(...arguments),this[e]=new Map,this[t]=a=>{a.forEach(o=>{(!(o instanceof MutationRecord)||o.type==="childList")&&(o.addedNodes.forEach(c=>{this[Zu](c)}),o.removedNodes.forEach(c=>{this[E0](c)}),this[en]())})},this[n]=new MutationObserver(this[Ju])}connectedCallback(){super.connectedCallback();for(let o=0;o{a.updateHotspotAttachment(o),a.updateSurfaceHotspot(o)})}[gi](a,o){super[gi](a,o);const c=this[J],{annotationRenderer:l}=c,h=c.getCamera();c.shouldRender()&&(c.animateSurfaceHotspots(),c.updateHotspotsVisibility(h.position),l.domElement.style.display="",l.render(c,h))}updateHotspot(a){const o=this[Fs].get(a.name);o!=null&&(o.updatePosition(a.position),o.updateNormal(a.normal),o.surface=a.surface,a.modelIndex!==void 0&&a.modelIndex!==null&&(o.modelIndex=a.modelIndex),this[J].updateSurfaceHotspot(o),this[en]())}queryHotspot(a){const o=this[Fs].get(a);if(o==null)return null;const c=ls(o.position),l=ls(o.normal),h=o.facingCamera,u=this[J],d=u.getCamera(),f=new R;f.setFromMatrixPosition(o.matrixWorld),f.project(d);const p=u.width/2,m=u.height/2;f.x=f.x*p+p,f.y=-(f.y*m)+m;const A=ls(new R(f.x,f.y,f.z));return!Number.isFinite(A.x)||!Number.isFinite(A.y)?null:{position:c,normal:l,canvasPosition:A,facingCamera:h}}positionAndNormalFromPoint(a,o){const c=this[J],l=c.getNDC(a,o),h=c.positionAndNormalFromPoint(l);if(h==null)return null;const u=h.worldToModel,d=ls(h.position.applyMatrix4(u)),f=ls(h.normal.transformDirection(u));let p=null;return h.uv!=null&&(p=uf(h.uv)),{position:d,normal:f,uv:p,modelIndex:h.modelIndex}}surfaceFromPoint(a,o){const c=this[J],l=c.getNDC(a,o);return c.surfaceFromPoint(l)}[Zu](a){if(!(a instanceof HTMLElement&&a.slot.indexOf("hotspot")===0))return;let o=this[Fs].get(a.slot);if(o!=null){o.increment();const c=a.dataset.visibilityAttribute;if(c!=null){const l=`data-${c}`;a.toggleAttribute(l,o.facingCamera)}a.dispatchEvent(new CustomEvent("hotspot-visibility",{detail:{visible:o.facingCamera}}))}else o=new cf({name:a.slot,position:a.dataset.position,normal:a.dataset.normal,surface:a.dataset.surface,modelIndex:a.dataset.modelIndex!=null?parseInt(a.dataset.modelIndex):null}),this[Fs].set(a.slot,o),this[J].addHotspot(o);this[J].queueRender()}[E0](a){if(!(a instanceof HTMLElement))return;const o=this[Fs].get(a.slot);o&&(o.decrement()&&(this[J].removeHotspot(o),this[Fs].delete(a.slot)),this[J].queueRender())}}return i};var mn=Uint8Array,Bn=Uint16Array,Jf=Int32Array,Zf=new mn([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),ep=new mn([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),_0=new mn([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),aE=function(r,e){for(var t=new Bn(31),n=0;n<31;++n)t[n]=e+=1<>1|(wt&21845)<<1;is=(is&52428)>>2|(is&13107)<<2,is=(is&61680)>>4|(is&3855)<<4,ff[wt]=((is&65280)>>8|(is&255)<<8)>>1}var _o=(function(r,e,t){for(var n=r.length,i=0,s=new Bn(e);i>c]=l}else for(o=new Bn(n),i=0;i>15-r[i]);return o}),sr=new mn(288);for(var wt=0;wt<144;++wt)sr[wt]=8;for(var wt=144;wt<256;++wt)sr[wt]=9;for(var wt=256;wt<280;++wt)sr[wt]=7;for(var wt=280;wt<288;++wt)sr[wt]=8;var zl=new mn(32);for(var wt=0;wt<32;++wt)zl[wt]=5;var kB=_o(sr,9,0),QB=_o(zl,5,0),cE=function(r){return(r+7)/8|0},lE=function(r,e,t){return(t==null||t>r.length)&&(t=r.length),new mn(r.subarray(e,t))},GB=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],oh=function(r,e,t){var n=new Error(e||GB[r]);if(n.code=r,Error.captureStackTrace&&Error.captureStackTrace(n,oh),!t)throw n;return n},Pi=function(r,e,t){t<<=e&7;var n=e/8|0;r[n]|=t,r[n+1]|=t>>8},Ja=function(r,e,t){t<<=e&7;var n=e/8|0;r[n]|=t,r[n+1]|=t>>8,r[n+2]|=t>>16},ed=function(r,e){for(var t=[],n=0;nd&&(d=s[n].s);var f=new Bn(d+1),p=pf(t[h-1],f,0);if(p>e){var n=0,m=0,A=p-e,g=1<e)m+=g-(1<>=A;m>0;){var x=s[n].s;f[x]=0&&m;--n){var _=s[n].s;f[_]==e&&(--f[_],++m)}p=e}return{t:new mn(f),l:p}},pf=function(r,e,t){return r.s==-1?Math.max(pf(r.l,e,t+1),pf(r.r,e,t+1)):e[r.s]=t},y0=function(r){for(var e=r.length;e&&!r[--e];);for(var t=new Bn(++e),n=0,i=r[0],s=1,a=function(c){t[n++]=c},o=1;o<=e;++o)if(r[o]==i&&o!=e)++s;else{if(!i&&s>2){for(;s>138;s-=138)a(32754);s>2&&(a(s>10?s-11<<5|28690:s-3<<5|12305),s=0)}else if(s>3){for(a(i),--s;s>6;s-=6)a(8304);s>2&&(a(s-3<<5|8208),s=0)}for(;s--;)a(i);s=1,i=r[o]}return{c:t.subarray(0,n),n:e}},Za=function(r,e){for(var t=0,n=0;n>8,r[i+2]=r[i]^255,r[i+3]=r[i+1]^255;for(var s=0;s4&&!D[_0[L-1]];--L);var U=l+5<<3,P=Za(i,sr)+Za(s,zl)+a,N=Za(i,d)+Za(s,m)+a+14+3*L+Za(I,D)+2*I[16]+3*I[17]+7*I[18];if(c>=0&&U<=P&&U<=N)return hE(e,h,r.subarray(c,c+l));var F,k,$,q;if(Pi(e,h,1+(N15&&(Pi(e,h,fe[E]>>5&127),h+=fe[E]>>12)}}else F=kB,k=sr,$=QB,q=zl;for(var E=0;E255){var Ge=ze>>18&31;Ja(e,h,F[Ge+257]),h+=k[Ge+257],Ge>7&&(Pi(e,h,ze>>23&31),h+=Zf[Ge]);var X=ze&31;Ja(e,h,$[X]),h+=q[X],X>3&&(Ja(e,h,ze>>5&8191),h+=ep[X])}else Ja(e,h,F[ze]),h+=k[ze]}return Ja(e,h,F[256]),h+k[256]},HB=new Jf([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),uE=new mn(0),zB=function(r,e,t,n,i,s){var a=s.z||r.length,o=new mn(n+a+5*(1+Math.ceil(a/7e3))+i),c=o.subarray(n,o.length-i),l=s.l,h=(s.r||0)&7;if(e){h&&(c[0]=s.r>>3);for(var u=HB[e-1],d=u>>13,f=u&8191,p=(1<7e3||D>24576)&&(F>423||!l)){h=S0(r,c,0,_,v,S,E,D,L,C-L,h),D=I=E=0,L=C;for(var k=0;k<286;++k)v[k]=0;for(var k=0;k<30;++k)S[k]=0}var $=2,q=0,te=f,Z=P-N&32767;if(F>2&&U==x(C-Z))for(var Y=Math.min(d,F)-1,fe=Math.min(32767,C),Ge=Math.min(258,F);Z<=fe&&--te&&P!=N;){if(r[C+$]==r[C+$-Z]){for(var ze=0;ze$){if($=ze,q=Z,ze>Y)break;for(var X=Math.min(Z,ze-2),se=0,k=0;kse&&(se=De,N=oe)}}}P=N,N=m[P],Z+=P-N&32767}if(q){_[D++]=268435456|df[$]<<18|v0[q];var Fe=df[$]&31,Ot=v0[q]&31;E+=Zf[Fe]+ep[Ot],++v[257+Fe],++S[Ot],w=C+$,++I}else _[D++]=r[C],++v[r[C]]}}for(C=Math.max(C,w);C=a&&(c[h/8|0]=l,Ze=a),h=hE(c,h+1,r.subarray(C,Ze))}s.i=a}return lE(o,0,n+cE(h)+i)},VB=(function(){for(var r=new Int32Array(256),e=0;e<256;++e){for(var t=e,n=9;--n;)t=(t&1&&-306674912)^t>>>1;r[e]=t}return r})(),WB=function(){var r=-1;return{p:function(e){for(var t=r,n=0;n>>8;r=t},d:function(){return~r}}},qB=function(r,e,t,n,i){if(!i&&(i={l:1},e.dictionary)){var s=e.dictionary.subarray(-32768),a=new mn(s.length+r.length);a.set(s),a.set(r,s.length),r=a,i.w=s.length}return zB(r,e.level==null?6:e.level,e.mem==null?i.l?Math.ceil(Math.max(8,Math.min(13,Math.log(r.length)))*1.5):20:12+e.mem,t,n,i)},dE=function(r,e){var t={};for(var n in r)t[n]=r[n];for(var n in e)t[n]=e[n];return t},sn=function(r,e,t){for(;t;++e)r[e]=t,t>>>=8};function jB(r,e){return qB(r,e||{},0,0)}var fE=function(r,e,t,n){for(var i in r){var s=r[i],a=e+i,o=n;Array.isArray(s)&&(o=dE(n,s[1]),s=s[0]),s instanceof mn?t[a]=[s,o]:(t[a+="/"]=[new mn(0),o],fE(s,a,t,n))}},C0=typeof TextEncoder<"u"&&new TextEncoder,XB=typeof TextDecoder<"u"&&new TextDecoder,KB=0;try{XB.decode(uE,{stream:!0}),KB=1}catch{}function Vl(r,e){var t;if(C0)return C0.encode(r);for(var n=r.length,i=new mn(r.length+(r.length>>1)),s=0,a=function(l){i[s++]=l},t=0;ti.length){var o=new mn(s+8+(n-t<<1));o.set(i),i=o}var c=r.charCodeAt(t);c<128||e?a(c):c<2048?(a(192|c>>6),a(128|c&63)):c>55295&&c<57344?(c=65536+(c&1047552)|r.charCodeAt(++t)&1023,a(240|c>>18),a(128|c>>12&63),a(128|c>>6&63),a(128|c&63)):(a(224|c>>12),a(128|c>>6&63),a(128|c&63))}return lE(i,0,s)}var Af=function(r){var e=0;if(r)for(var t in r){var n=r[t].length;n>65535&&oh(9),e+=n+4}return e},M0=function(r,e,t,n,i,s,a,o){var c=n.length,l=t.extra,h=o&&o.length,u=Af(l);sn(r,e,a!=null?33639248:67324752),e+=4,a!=null&&(r[e++]=20,r[e++]=t.os),r[e]=20,e+=2,r[e++]=t.flag<<1|(s<0&&8),r[e++]=i&&8,r[e++]=t.compression&255,r[e++]=t.compression>>8;var d=new Date(t.mtime==null?Date.now():t.mtime),f=d.getFullYear()-1980;if((f<0||f>119)&&oh(10),sn(r,e,f<<25|d.getMonth()+1<<21|d.getDate()<<16|d.getHours()<<11|d.getMinutes()<<5|d.getSeconds()>>1),e+=4,s!=-1&&(sn(r,e,t.crc),sn(r,e+4,s<0?-s-2:s),sn(r,e+8,t.size)),sn(r,e+12,c),sn(r,e+14,u),e+=16,a!=null&&(sn(r,e,h),sn(r,e+6,t.attrs),sn(r,e+10,a),e+=14),r.set(n,e),e+=c,u)for(var p in l){var m=l[p],A=m.length;sn(r,e,+p),sn(r,e+2,A),r.set(m,e+4),e+=4+A}return h&&(r.set(o,e),e+=h),e},$B=function(r,e,t,n,i){sn(r,e,101010256),sn(r,e+8,t),sn(r,e+10,t),sn(r,e+12,n),sn(r,e+16,i)};function YB(r,e){e||(e={});var t={},n=[];fE(r,"",t,e);var i=0,s=0;for(var a in t){var o=t[a],c=o[0],l=o[1],h=l.level==0?0:8,u=Vl(a),d=u.length,f=l.comment,p=f&&Vl(f),m=p&&p.length,A=Af(l.extra);d>65535&&oh(11);var g=h?jB(c,l):c,b=g.length,x=WB();x.p(c),n.push(dE(l,{size:c.length,crc:x.d(),c:g,f:u,m:p,u:d!=a.length||p&&f.length!=m,o:i,compression:h})),i+=30+d+A+b,s+=76+2*(d+A)+(m||0)+b}for(var _=new mn(s+22),v=i,S=s-i,I=0;I{const u=h.key,d=h.value;if(Array.isArray(d)){const f=[];return f.push(`${u} = {`),d.forEach(p=>{f.push(`${t} ${p}`)}),f.push(`${t} }`),f.join(` +`)}else return`${u} = ${d}`}),i=n.length?` ( +${n.map(h=>`${t} ${h}`).join(` +`)} +${t})`:"",s=this.properties.map(h=>{const u=h.property,d=h.metadata.length?` ( +${h.metadata.map(f=>`${t} ${f}`).join(` +`)} +${t} )`:"";return`${t} ${u}${d}`}),a=this.children.map(h=>h.toString(e+1)),o=[];if(s.length>0&&o.push(...s),a.length>0){s.length>0&&o.push("");for(let h=0;hg.toBlob(x,"image/png",1));i[`textures/Texture_${m}.png`]=new Uint8Array(await b.arrayBuffer())}let p=0;for(const m in i){const A=i[m],g=34+m.length;p+=g;const b=p&63;if(b!==4){const x=64-b,_=new Uint8Array(x);i[m]=[A,{extra:{12345:_}}]}p=A.length}return YB(i,{level:0})}}function pE(r,e){let t=r.name;return t=t.replace(/[^A-Za-z0-9_]/g,""),/^[0-9]/.test(t)&&(t="_"+t),t===""&&(r.isCamera?t="Camera":t="Object"),e.has(t)&&(t=t+"_"+r.id),e.add(t),t}function ZB(r,e,t){if(typeof HTMLImageElement<"u"&&r instanceof HTMLImageElement||typeof HTMLCanvasElement<"u"&&r instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&r instanceof OffscreenCanvas||typeof ImageBitmap<"u"&&r instanceof ImageBitmap){const n=t/Math.max(r.width,r.height),i=document.createElement("canvas");i.width=r.width*Math.min(1,n),i.height=r.height*Math.min(1,n);const s=i.getContext("2d");return e===!0&&(s.translate(0,i.height),s.scale(1,-1)),s.drawImage(r,0,0,i.width,i.height),i}else throw new Error("THREE.USDZExporter: No valid image data found. Unable to process texture.")}const Et=7;function AE(){return`#usda 1.0 +( + customLayerData = { + string creator = "Three.js USDZExporter" + } + defaultPrim = "Root" + metersPerUnit = 1 + upAxis = "Y" +) +`}function gE(r,e,t,n,i,s){for(let a=0,o=r.children.length;a`),i.addMetadata("prepend apiSchemas",'["MaterialBindingAPI"]'),i.addProperty(`rel material:binding = `),i}function bE(r){const e=r.elements;return`( ${$c(e,0)}, ${$c(e,4)}, ${$c(e,8)}, ${$c(e,12)} )`}function $c(r,e){return`(${r[e+0]}, ${r[e+1]}, ${r[e+2]}, ${r[e+3]})`}function tD(r){const e=new Tn("Geometry"),t=nD(r);return e.addChild(t),e}function nD(r){const e="Geometry",t=r.attributes,n=t.position.count,i=new Tn(e,"Mesh");i.addProperty(`int[] faceVertexCounts = [${iD(r)}]`),i.addProperty(`int[] faceVertexIndices = [${sD(r)}]`),i.addProperty(`normal3f[] normals = [${td(t.normal,n)}]`,['interpolation = "vertex"']),i.addProperty(`point3f[] points = [${td(t.position,n)}]`);for(let a=0;a<4;a++){const o=a>0?a:"",c=t["uv"+o];c!==void 0&&i.addProperty(`texCoord2f[] primvars:st${o} = [${rD(c)}]`,['interpolation = "vertex"'])}const s=t.color;return s!==void 0&&i.addProperty(`color3f[] primvars:displayColor = [${td(s,n)}]`,['interpolation = "vertex"']),i.addProperty('uniform token subdivisionScheme = "none"'),i}function iD(r){const e=r.index!==null?r.index.count:r.attributes.position.count;return Array(e/3).fill(3).join(", ")}function sD(r){const e=r.index,t=[];if(e!==null)for(let n=0;n0?"st"+a.channel:"st",u={1e3:"repeat",1001:"clamp",1002:"mirror"},d=a.repeat.clone(),f=a.offset.clone(),p=a.rotation,m=Math.sin(p),A=Math.cos(p);f.y=1-f.y-d.y,t?(f.x=f.x/d.x,f.y=f.y/d.y,f.x+=m/d.x,f.y+=A-1):(f.x+=m*d.x,f.y+=(1-A)*d.y);const g=new Tn(`PrimvarReader_${o}`,"Shader");g.addProperty('uniform token info:id = "UsdPrimvarReader_float2"'),g.addProperty("float2 inputs:fallback = (0.0, 0.0)"),g.addProperty(`string inputs:varname = "${h}"`),g.addProperty("float2 outputs:result");const b=new Tn(`Transform2d_${o}`,"Shader");b.addProperty('uniform token info:id = "UsdTransform2d"'),b.addProperty(`float2 inputs:in.connect = `),b.addProperty(`float inputs:rotation = ${(p*(180/Math.PI)).toFixed(Et)}`),b.addProperty(`float2 inputs:scale = ${w0(d)}`),b.addProperty(`float2 inputs:translation = ${w0(f)}`),b.addProperty("float2 outputs:result");const x=new Tn(`Texture_${a.id}_${o}`,"Shader");return x.addProperty('uniform token info:id = "UsdUVTexture"'),x.addProperty(`asset inputs:file = @textures/Texture_${l}.png@`),x.addProperty(`float2 inputs:st.connect = `),c!==void 0&&x.addProperty(`float4 inputs:scale = ${cD(c)}`),o==="normal"&&(x.addProperty("float4 inputs:scale = (2, 2, 2, 1)"),x.addProperty("float4 inputs:bias = (-1, -1, -1, 0)")),x.addProperty(`token inputs:sourceColorSpace = "${a.colorSpace===Nn?"raw":"sRGB"}"`),x.addProperty(`token inputs:wrapS = "${u[a.wrapS]}"`),x.addProperty(`token inputs:wrapT = "${u[a.wrapT]}"`),x.addProperty("float outputs:r"),x.addProperty("float outputs:g"),x.addProperty("float outputs:b"),x.addProperty("float3 outputs:rgb"),(r.transparent||r.alphaTest>0)&&x.addProperty("float outputs:a"),[g,b,x]}r.side===Wt&&console.warn("THREE.USDZExporter: USDZ does not support double sided materials",r);const s=new Tn("PreviewSurface","Shader");if(s.addProperty('uniform token info:id = "UsdPreviewSurface"'),r.map!==null?(s.addProperty(`color3f inputs:diffuseColor.connect = `),r.transparent?s.addProperty(`float inputs:opacity.connect = `):r.alphaTest>0&&(s.addProperty(`float inputs:opacity.connect = `),s.addProperty(`float inputs:opacityThreshold = ${r.alphaTest}`)),i(r.map,"diffuse",r.color).forEach(o=>n.addChild(o))):s.addProperty(`color3f inputs:diffuseColor = ${I0(r.color)}`),r.emissiveMap!==null){s.addProperty(`color3f inputs:emissiveColor.connect = `);const a=new Me(r.emissive.r*r.emissiveIntensity,r.emissive.g*r.emissiveIntensity,r.emissive.b*r.emissiveIntensity);i(r.emissiveMap,"emissive",a).forEach(c=>n.addChild(c))}else r.emissive.getHex()>0&&s.addProperty(`color3f inputs:emissiveColor = ${I0(r.emissive)}`);if(r.normalMap!==null&&(s.addProperty(`normal3f inputs:normal.connect = `),i(r.normalMap,"normal").forEach(o=>n.addChild(o))),r.aoMap!==null){s.addProperty(`float inputs:occlusion.connect = `);const a=new Me(r.aoMapIntensity,r.aoMapIntensity,r.aoMapIntensity);i(r.aoMap,"occlusion",a).forEach(c=>n.addChild(c))}if(r.roughnessMap!==null){s.addProperty(`float inputs:roughness.connect = `);const a=new Me(r.roughness,r.roughness,r.roughness);i(r.roughnessMap,"roughness",a).forEach(c=>n.addChild(c))}else s.addProperty(`float inputs:roughness = ${r.roughness}`);if(r.metalnessMap!==null){s.addProperty(`float inputs:metallic.connect = `);const a=new Me(r.metalness,r.metalness,r.metalness);i(r.metalnessMap,"metallic",a).forEach(c=>n.addChild(c))}else s.addProperty(`float inputs:metallic = ${r.metalness}`);if(r.alphaMap!==null?(s.addProperty(`float inputs:opacity.connect = `),s.addProperty("float inputs:opacityThreshold = 0.0001"),i(r.alphaMap,"opacity").forEach(o=>n.addChild(o))):s.addProperty(`float inputs:opacity = ${r.opacity}`),r.isMeshPhysicalMaterial){if(r.clearcoatMap!==null){s.addProperty(`float inputs:clearcoat.connect = `);const a=new Me(r.clearcoat,r.clearcoat,r.clearcoat);i(r.clearcoatMap,"clearcoat",a).forEach(c=>n.addChild(c))}else s.addProperty(`float inputs:clearcoat = ${r.clearcoat}`);if(r.clearcoatRoughnessMap!==null){s.addProperty(`float inputs:clearcoatRoughness.connect = `);const a=new Me(r.clearcoatRoughness,r.clearcoatRoughness,r.clearcoatRoughness);i(r.clearcoatRoughnessMap,"clearcoatRoughness",a).forEach(c=>n.addChild(c))}else s.addProperty(`float inputs:clearcoatRoughness = ${r.clearcoatRoughness}`);s.addProperty(`float inputs:ior = ${r.ior}`)}return s.addProperty("int inputs:useSpecularWorkflow = 0"),s.addProperty("token outputs:surface"),n.addChild(s),n.addProperty(`token outputs:surface.connect = `),n}function I0(r){return`(${r.r}, ${r.g}, ${r.b})`}function cD(r){return`(${r.r}, ${r.g}, ${r.b}, 1.0)`}function w0(r){return`(${r.x}, ${r.y})`}function lD(r,e){const t=pE(r,e),n=bE(r.matrix);r.matrix.determinant()<0&&console.warn("THREE.USDZExporter: USDZ does not support negative scales",r);const i=new Tn(t,"Camera");i.addProperty(`matrix4d xformOp:transform = ${n}`),i.addProperty('uniform token[] xformOpOrder = ["xformOp:transform"]');const s=r.isOrthographicCamera?"orthographic":"perspective";i.addProperty(`token projection = "${s}"`);const a=`(${r.near.toPrecision(Et)}, ${r.far.toPrecision(Et)})`;i.addProperty(`float2 clippingRange = ${a}`);let o;r.isOrthographicCamera?o=((Math.abs(r.left)+Math.abs(r.right))*10).toPrecision(Et):o=r.getFilmWidth().toPrecision(Et),i.addProperty(`float horizontalAperture = ${o}`);let c;if(r.isOrthographicCamera?c=((Math.abs(r.top)+Math.abs(r.bottom))*10).toPrecision(Et):c=r.getFilmHeight().toPrecision(Et),i.addProperty(`float verticalAperture = ${c}`),r.isPerspectiveCamera){const l=r.getFocalLength().toPrecision(Et);i.addProperty(`float focalLength = ${l}`);const h=r.focus.toPrecision(Et);i.addProperty(`float focusDistance = ${h}`)}return i}const hD=r=>e=>{try{const t=Hi(e),n=(t.length?t[0].terms:[]).filter(i=>i&&i.type==="ident").map(i=>i.value).filter(i=>r.indexOf(i)>-1);return new Set(n)}catch{}return new Set};var Ns=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var o=r.length-1;o>=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};let T0=!1,R0=!1;const B0="#model-viewer-no-ar-fallback",uD=hD(["quick-look","scene-viewer","webxr","none"]),dD="webxr scene-viewer quick-look",Ln={QUICK_LOOK:"quick-look",SCENE_VIEWER:"scene-viewer",WEBXR:"webxr",NONE:"none"},Fi=Symbol("arButtonContainer"),D0=Symbol("enterARWithWebXR"),L0=Symbol("openSceneViewer"),P0=Symbol("openIOSARQuickLook"),fD=Symbol("canActivateAR"),Yc=Symbol("arMode"),nd=Symbol("arModes"),Nr=Symbol("arAnchor"),Jc=Symbol("preload"),Zc=Symbol("onARButtonContainerClick"),id=Symbol("onARStatus"),sd=Symbol("onARTracking"),rd=Symbol("onARTap"),eo=Symbol("selectARMode"),ad=Symbol("triggerLoad"),pD=r=>{var e,t,n,i,s,a,o,c,l,h;class u extends r{constructor(){super(...arguments),this.ar=!1,this.arScale="auto",this.arUsdzMaxTextureSize="auto",this.arPlacement="floor",this.arModes=dD,this.iosSrc=null,this.xrEnvironment=!1,this[e]=!1,this[t]=this.shadowRoot.querySelector(".ar-button"),this[n]=document.createElement("a"),this[i]=new Set,this[s]=Ln.NONE,this[a]=!1,this[o]=f=>{f.preventDefault(),this.activateAR()},this[c]=({status:f})=>{(f===Qi.NOT_PRESENTING||this[ot].arRenderer.presentedScene===this[J])&&(this.setAttribute("ar-status",f),this.dispatchEvent(new CustomEvent("ar-status",{detail:{status:f}})),f===Qi.NOT_PRESENTING?this.removeAttribute("ar-tracking"):f===Qi.SESSION_STARTED&&this.setAttribute("ar-tracking",tf.TRACKING))},this[l]=({status:f})=>{this.setAttribute("ar-tracking",f),this.dispatchEvent(new CustomEvent("ar-tracking",{detail:{status:f}}))},this[h]=f=>{f.data=="_apple_ar_quicklook_button_tapped"&&this.dispatchEvent(new CustomEvent("quick-look-button-tapped"))}}get canActivateAR(){return this[Yc]!==Ln.NONE}connectedCallback(){super.connectedCallback(),this[ot].arRenderer!=null&&(this[ot].arRenderer.addEventListener("status",this[id]),this.setAttribute("ar-status",Qi.NOT_PRESENTING),this[ot].arRenderer.addEventListener("tracking",this[sd])),this[Nr].addEventListener("message",this[rd])}disconnectedCallback(){super.disconnectedCallback(),this[ot].arRenderer!=null&&(this[ot].arRenderer.removeEventListener("status",this[id]),this[ot].arRenderer.removeEventListener("tracking",this[sd])),this[Nr].removeEventListener("message",this[rd])}update(f){super.update(f),f.has("arScale")&&(this[J].canScale=this.arScale!=="fixed"),f.has("arPlacement")&&(this[J].updateShadow(),this[en]()),f.has("arModes")&&(this[nd]=uD(this.arModes)),(f.has("ar")||f.has("arModes")||f.has("src")||f.has("iosSrc")||f.has("arUsdzMaxTextureSize"))&&this[eo]()}async activateAR(){switch(this[Yc]){case Ln.QUICK_LOOK:await this[P0]();break;case Ln.WEBXR:await this[D0]();break;case Ln.SCENE_VIEWER:await this[L0]();break;default:console.warn("No AR Mode can be activated. This is probably due to missing configuration or device capabilities");break}}async[(e=fD,t=Fi,n=Nr,i=nd,s=Yc,a=Jc,o=Zc,c=id,l=sd,h=rd,eo)](){var f;let p=Ln.NONE;if(this.ar){if(this.src!=null)for(const m of this[nd]){if(m==="webxr"&&Pb&&!T0&&await this[ot].arRenderer.supportsPresentation()){p=Ln.WEBXR;break}if(m==="scene-viewer"&&!R0&&(zw||navigator.userAgentData&&navigator.userAgentData.getHighEntropyValues&&(!((f=(await navigator.userAgentData.getHighEntropyValues(["formFactor"])).formFactor)===null||f===void 0)&&f.includes("XR")))){p=Ln.SCENE_VIEWER;break}if(m==="quick-look"&&WA&&!VA&&(!Fb||this.iosSrc!=null)){p=Ln.QUICK_LOOK;break}}p===Ln.NONE&&this.iosSrc!=null&&WA&&!VA&&(p=Ln.QUICK_LOOK)}if(p!==Ln.NONE)this[Fi].classList.add("enabled"),this[Fi].addEventListener("click",this[Zc]);else if(this[Fi].classList.contains("enabled")){this[Fi].removeEventListener("click",this[Zc]),this[Fi].classList.remove("enabled");const m=Qi.FAILED;this.setAttribute("ar-status",m),this.dispatchEvent(new CustomEvent("ar-status",{detail:{status:m}}))}this[Yc]=p}async[D0](){console.log("Attempting to present in AR with WebXR..."),await this[ad]();try{this[Fi].removeEventListener("click",this[Zc]);const{arRenderer:f}=this[ot];f.placeOnWall=this.arPlacement==="wall",await f.present(this[J],this.xrEnvironment)}catch(f){console.warn("Error while trying to present in AR with WebXR"),console.error(f),await this[ot].arRenderer.stopPresenting(),T0=!0,console.warn("Falling back to next ar-mode"),await this[eo](),this.activateAR()}finally{this[eo]()}}async[ad](){this.loaded||(this[Jc]=!0,this[cs](),await jw(this,"load"),this[Jc]=!1)}[pa](){return super[pa]()||this[Jc]}async[L0](){const f=self.location.toString(),p=new URL(f),A=Array.from(this.querySelectorAll("extra-model")).map(S=>S.src).filter(S=>S!=null),g=this.src||A[0]||null;if(!g){console.warn("No src or extra-model provided for Scene Viewer fallback.");return}let b=new URL(g,f);b.hash&&(b.hash="");const x=new URLSearchParams(b.search);if(p.hash=B0,x.set("mode","ar_preferred"),x.has("disable_occlusion")||x.set("disable_occlusion","true"),this.arScale==="fixed"&&x.set("resizable","false"),this.arPlacement==="wall"&&x.set("enable_vertical_placement","true"),x.has("sound")){const S=new URL(x.get("sound"),f);x.set("sound",S.toString())}if(x.has("link")){const S=new URL(x.get("link"),f);x.set("link",S.toString())}const _=`intent://arvr.google.com/scene-viewer/1.2?${x.toString()+"&file="+encodeURIComponent(b.toString())}#Intent;scheme=https;package=com.google.android.googlequicksearchbox;action=android.intent.action.VIEW;S.browser_fallback_url=${encodeURIComponent(p.toString())};end;`,v=()=>{self.location.hash===B0&&(R0=!0,self.history.back(),console.warn("Error while trying to present in AR with Scene Viewer"),console.warn("Falling back to next ar-mode"),this[eo]())};self.addEventListener("hashchange",v,{once:!0}),this[Nr].setAttribute("href",_),console.log("Attempting to present in AR with Scene Viewer..."),this[Nr].click()}async[P0](){const f=!this.iosSrc;this[Fi].classList.remove("enabled");const p=f?await this.prepareUSDZ():this.iosSrc,m=new URL(p,self.location.toString());if(f){const b=self.location.toString(),x=new URL(b),v=Array.from(this.querySelectorAll("extra-model")).map(I=>I.src).filter(I=>I!=null),S=this.src||v[0]||null;if(S){const I=new URL(S,x);I.hash&&(m.hash=I.hash)}}this.arScale==="fixed"&&(m.hash&&(m.hash+="&"),m.hash+="allowsContentScaling=0");const A=this[Nr];A.setAttribute("rel","ar");const g=document.createElement("img");A.appendChild(g),A.setAttribute("href",m.toString()),f&&A.setAttribute("download","model.usdz"),A.style.display="none",A.isConnected||this.shadowRoot.appendChild(A),console.log("Attempting to present in AR with Quick Look..."),A.click(),A.removeChild(g),f&&URL.revokeObjectURL(p),this[Fi].classList.add("enabled")}async prepareUSDZ(){const f=this[nr].beginActivity("usdz-conversion");await this[ad]();const{models:p,shadow:m,target:A}=this[J];if(p.length===0||p[0]==null)return"";let g=!1;m!=null&&(g=m.visible,m.visible=!1),f(.2);const b=new JB,x=new ht;x.position.copy(A.position);for(const I of p)A.remove(I),x.add(I);x.updateWorldMatrix(!1,!0);const _=await b.parseAsync(x,{maxTextureSize:isNaN(this.arUsdzMaxTextureSize)?1/0:Math.max(parseInt(this.arUsdzMaxTextureSize),16)});for(const I of p)x.remove(I),A.add(I);const v=new Blob([_],{type:"model/vnd.usdz+zip"}),S=URL.createObjectURL(v);return f(1),m!=null&&(m.visible=g),S}}return Ns([Re({type:Boolean,attribute:"ar"})],u.prototype,"ar",void 0),Ns([Re({type:String,attribute:"ar-scale"})],u.prototype,"arScale",void 0),Ns([Re({type:String,attribute:"ar-usdz-max-texture-size"})],u.prototype,"arUsdzMaxTextureSize",void 0),Ns([Re({type:String,attribute:"ar-placement"})],u.prototype,"arPlacement",void 0),Ns([Re({type:String,attribute:"ar-modes"})],u.prototype,"arModes",void 0),Ns([Re({type:String,attribute:"ios-src"})],u.prototype,"iosSrc",void 0),Ns([Re({type:Boolean,attribute:"xr-environment"})],u.prototype,"xrEnvironment",void 0),u};var od=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var o=r.length-1;o>=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};const AD=100,gD="https://www.gstatic.com/draco/versioned/decoders/1.5.6/",mD="https://www.gstatic.com/basis-universal/versioned/2021-04-15-ba1c3e4/",bD="https://cdn.jsdelivr.net/npm/three@0.149.0/examples/jsm/loaders/LottieLoader.js",cd={AUTO:"auto"},F0={AUTO:"auto",EAGER:"eager"},Ur=Symbol("defaultProgressBarElement"),ld=Symbol("posterContainerElement"),Or=Symbol("defaultPosterElement"),to=Symbol("shouldDismissPoster"),hd=Symbol("hidePoster"),el=Symbol("modelIsRevealed"),ud=Symbol("updateProgressBar"),xD=Symbol("ariaLabelCallToAction"),dd=Symbol("onProgress"),ED=r=>{var e,t,n,i,s,a,o,c;class l extends r{static set dracoDecoderLocation(u){_n.setDRACODecoderLocation(u)}static get dracoDecoderLocation(){return _n.getDRACODecoderLocation()}static set ktx2TranscoderLocation(u){_n.setKTX2TranscoderLocation(u)}static get ktx2TranscoderLocation(){return _n.getKTX2TranscoderLocation()}static set meshoptDecoderLocation(u){_n.setMeshoptDecoderLocation(u)}static get meshoptDecoderLocation(){return _n.getMeshoptDecoderLocation()}static set lottieLoaderLocation(u){On.singleton.textureUtils.lottieLoaderUrl=u}static get lottieLoaderLocation(){return On.singleton.textureUtils.lottieLoaderUrl}static mapURLs(u){On.singleton.loader[Os].manager.setURLModifier(u)}dismissPoster(){this.loaded?this[hd]():(this[to]=!0,this[cs]())}showPoster(){const u=this[ld];if(u.classList.contains("show"))return;u.classList.add("show"),this[$n].classList.remove("show");const d=this[Or];d.removeAttribute("tabindex"),d.removeAttribute("aria-hidden");const f=this.modelIsVisible;this[el]=!1,this[Ql](f)}getDimensions(){return this[J].updateBoundingBoxAndShadowIfDirty(),ls(this[J].size)}getBoundingBoxCenter(){return this[J].updateBoundingBoxAndShadowIfDirty(),ls(this[J].boundingBox.getCenter(new R))}constructor(...u){super(...u),this.poster=null,this.reveal=cd.AUTO,this.loading=F0.AUTO,this[e]=!1,this[t]=!1,this[n]=this.shadowRoot.querySelector(".slot.poster"),this[i]=this.shadowRoot.querySelector("#default-poster"),this[s]=this.shadowRoot.querySelector("#default-progress-bar > .bar"),this[a]=this[Or].getAttribute("aria-label"),this[o]=Ww(A=>{const g=this[Ur].parentNode;requestAnimationFrame(()=>{this[Ur].style.transform=`scaleX(${A})`,A===0&&(g.removeChild(this[Ur]),g.appendChild(this[Ur])),this[Ur].classList.toggle("hide",A===1)})},AD),this[c]=A=>{const g=A.detail.totalProgress,b=A.detail.reason;g===1&&(this[ud].flush(),this.loaded&&(this[to]||this.reveal===cd.AUTO)&&this[hd]()),this[ud](g),this.dispatchEvent(new CustomEvent("progress",{detail:{totalProgress:g,reason:b}}))};const d=self.ModelViewerElement||{},f=d.dracoDecoderLocation||gD;_n.setDRACODecoderLocation(f);const p=d.ktx2TranscoderLocation||mD;_n.setKTX2TranscoderLocation(p),d.meshoptDecoderLocation&&_n.setMeshoptDecoderLocation(d.meshoptDecoderLocation);const m=d.lottieLoaderLocation||bD;On.singleton.textureUtils!=null&&(On.singleton.textureUtils.lottieLoaderUrl=m)}connectedCallback(){super.connectedCallback(),this.loaded||this.showPoster(),this[nr].addEventListener("progress",this[dd])}disconnectedCallback(){super.disconnectedCallback(),this[nr].removeEventListener("progress",this[dd])}async updated(u){super.updated(u),u.has("poster")&&this.poster!=null&&(this[Or].style.backgroundImage=`url(${this.poster})`),u.has("alt")&&this[Or].setAttribute("aria-label",this[lf]),(u.has("reveal")||u.has("loading"))&&this[cs]()}[(e=el,t=to,n=ld,i=Or,s=Ur,a=xD,o=ud,c=dd,pa)](){const u=Array.from(this.querySelectorAll("extra-model"));return!!(this.src||u.length>0)&&(this[to]||this.loading===F0.EAGER||this.reveal===cd.AUTO&&this[Hs])}[hd](){this[to]=!1;const u=this[ld];if(!u.classList.contains("show"))return;u.classList.remove("show"),this[$n].classList.add("show");const d=this.modelIsVisible;this[el]=!0,this[Ql](d);const f=this.getRootNode();f&&f.activeElement===this&&this[$n].focus();const p=this[Or];p.setAttribute("aria-hidden","true"),p.tabIndex=-1,this.dispatchEvent(new CustomEvent("poster-dismissed"))}[ir](){return super[ir]()&&this[el]}}return od([Re({type:String})],l.prototype,"poster",void 0),od([Re({type:String})],l.prototype,"reveal",void 0),od([Re({type:String})],l.prototype,"loading",void 0),l};var fd=function(r,e,t,n){var i=arguments.length,s=i<3?e:n===null?n=Object.getOwnPropertyDescriptor(e,t):n,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")s=Reflect.decorate(r,e,t,n);else for(var o=r.length-1;o>=0;o--)(a=r[o])&&(s=(i<3?a(s):i>3?a(e,t,s):a(e,t))||s);return i>3&&s&&Object.defineProperty(e,t,s),s};const _D=Math.PI/32,vD=3e3,yD={basis:[rh(An(_D,"rad"))],keywords:{auto:[null]}},kr=Symbol("autoRotateStartTime"),pd=Symbol("radiansPerSecond"),N0=Symbol("syncRotationRate"),Ad=Symbol("onCameraChange"),SD=r=>{var e,t,n;class i extends r{constructor(){super(...arguments),this.autoRotate=!1,this.autoRotateDelay=vD,this.rotationPerSecond="auto",this[e]=performance.now(),this[t]=0,this[n]=a=>{this.autoRotate&&a.detail.source==="user-interaction"&&(this[kr]=performance.now())}}connectedCallback(){super.connectedCallback(),this.addEventListener("camera-change",this[Ad]),this[kr]=performance.now()}disconnectedCallback(){super.disconnectedCallback(),this.removeEventListener("camera-change",this[Ad]),this[kr]=performance.now()}updated(a){super.updated(a),a.has("autoRotate")&&(this[kr]=performance.now())}[(e=kr,t=pd,N0)](a){this[pd]=a[0]}[gi](a,o){if(super[gi](a,o),!this.autoRotate||!this[ir]()||this[ot].isPresenting)return;const c=Math.min(o,a-this[kr]-this.autoRotateDelay);c>0&&(this[J].yaw=this.turntableRotation+this[pd]*c*.001)}get turntableRotation(){return this[J].yaw}resetTurntableRotation(a=0){this[J].yaw=a}}return n=Ad,fd([Re({type:Boolean,attribute:"auto-rotate"})],i.prototype,"autoRotate",void 0),fd([Re({type:Number,attribute:"auto-rotate-delay"})],i.prototype,"autoRotateDelay",void 0),fd([ss({intrinsics:yD,updateHandler:N0}),Re({type:String,attribute:"rotation-per-second"})],i.prototype,"rotationPerSecond",void 0),i};const CD=NB(gB(SD(Jw(pR(pD(ED(FB(Vo))))))));customElements.define("model-viewer",CD);export{Nl as CanvasTexture,Vi as FileLoader,Ei as Loader,CD as ModelViewerElement,St as NearestFilter}; diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..d777c4b --- /dev/null +++ b/dist/index.html @@ -0,0 +1,13 @@ + + + + + + img2glb + + + + +
+ + diff --git a/index.html b/index.html new file mode 100644 index 0000000..575744c --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + img2glb + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0c72103 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2018 @@ +{ + "name": "img2glb-app", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "img2glb-app", + "dependencies": { + "@google/model-viewer": "^4.1.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-router": "^7.9.0" + }, + "devDependencies": { + "@types/node": "^22.18.0", + "@types/react": "^19.1.0", + "@types/react-dom": "^19.1.0", + "@vitejs/plugin-react": "^5.0.0", + "typescript": "~5.9.0", + "vite": "^7.1.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@google/model-viewer": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@google/model-viewer/-/model-viewer-4.3.1.tgz", + "integrity": "sha512-GP+inXhAtY31E8rILVmByA6z8CZZjdlNajddppyI1/j1eIaSQiZcMRaUqTFe7+jv4mzRzwKIOiKBud0apiv+WQ==", + "license": "Apache-2.0", + "dependencies": { + "@monogrid/gainmap-js": "^3.1.0", + "lit": "^3.2.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "three": "^0.183.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.6.0.tgz", + "integrity": "sha512-VHb0ALPMTlgKjM6yIxxoQNnpKyUKLD04VzeQdsiXkMqkvYlAHxq9glGLmgbb889/1GsohSOAjvQYoiBppXFqrQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@lit/reactive-element": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.1.2.tgz", + "integrity": "sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.5.0" + } + }, + "node_modules/@monogrid/gainmap-js": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.4.0.tgz", + "integrity": "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg==", + "license": "MIT", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.4.tgz", + "integrity": "sha512-I+BSHzTAhKN2n7ZwGZsegGcZjDpLqFOMAtJz/u6uFGe0pUFbq56dEHjqJV/ZUdRJtNXNxA+hREUatZBvMR3Oiw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.4.tgz", + "integrity": "sha512-pu3BdjS2LtEzRu2elmGzS3fIeWSZy4BMDIaLNwjorO76+k2d0LMluijhsDx3KQyQBQ/lLUZCQA9/s6csvUfuhw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.4.tgz", + "integrity": "sha512-xfSrj9MHnWK9GaSqT9U0ImHtH/N8WZlHLx4cZHiuLcqs640hvZ3hLPd5UR2AZS57FaE8HrRUSpltbZdWRxHiDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.4.tgz", + "integrity": "sha512-bqU99PLJb/dqb3S0GIMdeuyAEETSUgZBoqXYd3Sd+WCsV+MmPhnN6JrotWyir31+QgH7EvvE5/mwGJlEoci8Fw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.4.tgz", + "integrity": "sha512-JinsFZ5G40oXQb+sUuiA5x689vhr6dDYK0H0NL+rwKdL6CqnmYN8PE4ZwfRSoIjrCxqTQG/SLfTtSvHeGxoVlw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.4.tgz", + "integrity": "sha512-GAdA4UxpiNm27cLHr2GqXBpAD0x9FqwYBY7/YSP0Ss0/PNi4k8gbviqpIpYbVSRBaS2ZcegXEzgTQMbRNCwxCw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.4.tgz", + "integrity": "sha512-qDd6NoA1znaLjp4jR5U/KWCdLAKDJNB8W9ChbbDaKbo0xA+Atln5HK6LFCZ4oJQpemtRZA288DCirFRjrspptw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.4.tgz", + "integrity": "sha512-WtB5Tz5KTNINb8ZA+8sQ7bmjuS1JrRT7YverYIhUGdWWDlpzVWmIwuZE+jidkEXUn1l0zrEkaIMa8dHF3NGcsA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.4.tgz", + "integrity": "sha512-VcQ3L1tjnkKzWjryAVaFhHEWcqOfICX9uxVVoDzm2t0DpgKRHd2zOpVrJc0xsWeBZcBFyYROCIBdyR/fS174pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.4.tgz", + "integrity": "sha512-6+ZQX6P5s0cMDN2Ypb8Lbm2+/sZYmZjdaYny992ujUU9UKi/4CWoJWsl1pNvjWJHNHGK51m+jKGLlh1ylb2ifQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.4.tgz", + "integrity": "sha512-D72ZnvkFkBXOfzMMQLcwfPLyGkKb7HZ9/mf97B7v6/P5Lbv4oFOtSY/uHbS8lH6uKUOxoKiuokdb50XZSzzbJw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.4.tgz", + "integrity": "sha512-piU6BxeqA3O9KSu3kRCIQQtNqFFaTu21SEV4FwaRZowpnj3bLaWPZHw+xFqCs0XlJ+aOH3PTRWGoglH+mKA/OA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.4.tgz", + "integrity": "sha512-/5PGpHwqt2EEEOUs1XwzubE/ucr0dWDQ+to3zqi4Ds7EWpwtQ79wXc4JBoxqj/OwpawTsKWzJxHfSuBOq3DrWA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.4.tgz", + "integrity": "sha512-cX3beZDLWt7G2oJF+nhChiT+qtaihs+S2xi7ziGmVB+2pwPng6D0Ed0HmElQOgv2UsUmSJJLGwpBao/3TDx3VA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.4.tgz", + "integrity": "sha512-1uz2mGWHyptR7DgHHrlbdRAjXK7v7elGZ9lMja910/RP+ZYbX6xAmCiU9UZSX4hqmgtHMv6lr5l3kq1HIOpcag==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.4.tgz", + "integrity": "sha512-nLS8topojxyz7SRpKR2IODRpQ0XPZ+xaOXvT3+hqK/Uy8Lo5HFgkkIBiIrCu5tL5YqzTvgovGw55PwpahTAGig==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.4.tgz", + "integrity": "sha512-gs7DRKotr3l3q+jGPQBjH0ng1FjlEDm5ueQrkw5JtQvtLyEIcLASqAEaor56BhkKRzk+IcQzrcanBdb/bBQn8g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.4.tgz", + "integrity": "sha512-791ET7W17NnScOZM7h4dX5hYspxE28htPFsb1awY/NRR8+PRNkS53e475rDdxXXDrP+kwnCcNWg9CX5ztn/Aqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.4.tgz", + "integrity": "sha512-iwZQRcmj7g88g3tzefIrQY7qvmuA/cfYwhrDtTBhsmukO4U2huVO5W+86XacUMRvdSFVAc6kZUZy21JaRwiB9w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.4.tgz", + "integrity": "sha512-dVHFp9gRWrdTpnqQuGfCwd7hOQDatK1VCP2iWhLY/cGrOQs/ucFzJ6A5SRqbXX12ZDI8EUuejSM5kwg+ja7Png==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.4.tgz", + "integrity": "sha512-t3NlauOW6gxZVVFcBEnO62Cb4wbyDFL416gTg1uFI/2tgqYQlf69FbSE115Ajre9I+c26Lk4mcmdFUsS/DGifQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.4.tgz", + "integrity": "sha512-xWuIaSye5FWZF8+UYtVEcHtRJDN5kN9Kfgxx3Kq8XIov9KSKbc1fiqQCm90SKrgQbUXZelbnUhnlUJmfSE7P9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.4.tgz", + "integrity": "sha512-9ALJJUOg/ZflMJepVo2PlgsGxSaxN7SQ4Z8GoZfVlarWr6r3rkHUNsd/zAio7p4YMtChSMXPionxej4Hkf6CXQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.4.tgz", + "integrity": "sha512-blj9z5qx/Pv4WU0W1NMFDB97e0JH5ed+aZGywW8WCvp/NhWX/4PFAq5uu6Q0AebNn+Vo6KzUYDT++JzTT5ojlQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.4.tgz", + "integrity": "sha512-Erx822VRBwLa124shbj+wNXe//BOgMEctDV0m1aqTQdNO1S69DgNUCFKC1RCeZfixs1J31l6igk1ziyXErbigQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.20.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.4.tgz", + "integrity": "sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.2.0.tgz", + "integrity": "sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.25", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.25.tgz", + "integrity": "sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.29.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.0.tgz", + "integrity": "sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.23", + "caniuse-lite": "^1.0.30001810", + "electron-to-chromium": "^1.5.427", + "node-releases": "^2.0.55", + "update-browserslist-db": "^1.3.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.438", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.438.tgz", + "integrity": "sha512-AN9xMU1hJiT65LkCUPL1DZm5TCbOPb2Qsm5pYwFLEXp6/qj9SdT4yMiqs7Qqstwvkn1zF7l36SRGt+s6XcJ0FA==", + "dev": true, + "license": "ISC" + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lit": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit/-/lit-3.3.3.tgz", + "integrity": "sha512-fycuvZg/hkpozL00lm1pEJH5nN/lr9ZXd6mJI2HSN4+Bzc+LDNdEApJ6HFbPkdFNHLvOplIIuJvxkS4XUxqirw==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit/reactive-element": "^2.1.0", + "lit-element": "^4.2.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-element": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.2.2.tgz", + "integrity": "sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==", + "license": "BSD-3-Clause", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.5.0", + "@lit/reactive-element": "^2.1.0", + "lit-html": "^3.3.0" + } + }, + "node_modules/lit-html": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.3.3.tgz", + "integrity": "sha512-el8M6jK2o3RXBnrSHX3ZKrsN8zEV63pSExTO1wYJz7QndGYZ8353e2a5PPX+qHe2aGayfnchQmkAojaWAREOIA==", + "license": "BSD-3-Clause", + "dependencies": { + "@types/trusted-types": "^2.0.2" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.57", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.57.tgz", + "integrity": "sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/promise-worker-transferable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz", + "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==", + "license": "Apache-2.0", + "dependencies": { + "is-promise": "^2.1.0", + "lie": "^3.0.2" + } + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.18.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.18.4.tgz", + "integrity": "sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/rollup": { + "version": "4.63.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.4.tgz", + "integrity": "sha512-4U0liVayNIoLp3GFl1FcI8561WepLnZ1rqfraGh7S9B3Ur5F9S283y8Futii7RUU2C/97tOBmBy7nYvhoiOpbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.63.4", + "@rollup/rollup-android-arm64": "4.63.4", + "@rollup/rollup-darwin-arm64": "4.63.4", + "@rollup/rollup-darwin-x64": "4.63.4", + "@rollup/rollup-freebsd-arm64": "4.63.4", + "@rollup/rollup-freebsd-x64": "4.63.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.63.4", + "@rollup/rollup-linux-arm-musleabihf": "4.63.4", + "@rollup/rollup-linux-arm64-gnu": "4.63.4", + "@rollup/rollup-linux-arm64-musl": "4.63.4", + "@rollup/rollup-linux-loong64-gnu": "4.63.4", + "@rollup/rollup-linux-loong64-musl": "4.63.4", + "@rollup/rollup-linux-ppc64-gnu": "4.63.4", + "@rollup/rollup-linux-ppc64-musl": "4.63.4", + "@rollup/rollup-linux-riscv64-gnu": "4.63.4", + "@rollup/rollup-linux-riscv64-musl": "4.63.4", + "@rollup/rollup-linux-s390x-gnu": "4.63.4", + "@rollup/rollup-linux-x64-gnu": "4.63.4", + "@rollup/rollup-linux-x64-musl": "4.63.4", + "@rollup/rollup-openbsd-x64": "4.63.4", + "@rollup/rollup-openharmony-arm64": "4.63.4", + "@rollup/rollup-win32-arm64-msvc": "4.63.4", + "@rollup/rollup-win32-ia32-msvc": "4.63.4", + "@rollup/rollup-win32-x64-gnu": "4.63.4", + "@rollup/rollup-win32-x64-msvc": "4.63.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/three": { + "version": "0.183.2", + "resolved": "https://registry.npmjs.org/three/-/three-0.183.2.tgz", + "integrity": "sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==", + "license": "MIT", + "peer": true + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.3.tgz", + "integrity": "sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0 || ^0.28.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f384088 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "img2glb-app", + "private": true, + "type": "module", + "scripts": { + "dev": "node scripts/dev.ts", + "build": "tsc -b && vite build", + "typecheck": "tsc -b", + "start": "node --disable-warning=ExperimentalWarning server/index.ts" + }, + "dependencies": { + "@google/model-viewer": "^4.1.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-router": "^7.9.0" + }, + "devDependencies": { + "@types/node": "^22.18.0", + "@types/react": "^19.1.0", + "@types/react-dom": "^19.1.0", + "@vitejs/plugin-react": "^5.0.0", + "typescript": "~5.9.0", + "vite": "^7.1.0" + } +} diff --git a/scripts/dev.ts b/scripts/dev.ts new file mode 100644 index 0000000..97321d5 --- /dev/null +++ b/scripts/dev.ts @@ -0,0 +1,22 @@ +// Разработка одной командой: API-сервер (с перезапуском при изменениях) + Vite, который проксирует на него /api. +// API в режиме разработки слушает свой порт (по умолчанию 7010), чтобы не мешать рабочему серверу на 7000. +import { spawn, type ChildProcess } from 'node:child_process'; +import path from 'node:path'; + +const root = path.join(import.meta.dirname, '..'); +const env = { ...process.env, API_PORT: process.env.API_PORT ?? '7010' }; + +const children: ChildProcess[] = [ + spawn(process.execPath, ['--disable-warning=ExperimentalWarning', '--watch', 'server/index.ts'], + { cwd: root, stdio: 'inherit', env: { ...env, PORT: env.API_PORT, HOST: '127.0.0.1' } }), + spawn(process.execPath, [path.join(root, 'node_modules', 'vite', 'bin', 'vite.js')], + { cwd: root, stdio: 'inherit', env }), +]; + +function stop(code = 0) { + children.forEach(c => { if (c.exitCode === null) c.kill(); }); + process.exit(code); +} +children.forEach(c => c.on('exit', code => stop(code ?? 0))); +process.on('SIGINT', () => stop()); +process.on('SIGTERM', () => stop()); diff --git a/server/comfy.ts b/server/comfy.ts new file mode 100644 index 0000000..5976545 --- /dev/null +++ b/server/comfy.ts @@ -0,0 +1,54 @@ +// Клиент ComfyUI API. +import { COMFY } from './config.ts'; + +export class ComfyError extends Error {} + +export async function comfyJson(pathname: string, body?: unknown): Promise { + let r: Response; + try { + r = await fetch(new URL(pathname, COMFY), body === undefined ? undefined : { + method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), + }); + } catch { + throw new ComfyError('ComfyUI недоступен по адресу ' + COMFY.origin); + } + const text = await r.text(); + let json: { error?: { message?: string } | string } | undefined; + try { json = JSON.parse(text); } catch { /* не JSON */ } + if (!r.ok) { + const e = json?.error; + throw new ComfyError(typeof e === 'string' ? e : e?.message ?? JSON.stringify(json ?? text)); + } + return json as T; +} + +/** Ставит граф в очередь, возвращает prompt_id. */ +export async function queuePrompt(graph: object): Promise { + const r = await comfyJson<{ prompt_id: string }>('/prompt', { prompt: graph }); + return r.prompt_id; +} + +/** Загрузка картинки в ComfyUI/input/. При совпадении имени ComfyUI сам даёт новое имя. */ +export async function uploadImage(name: string, data: Blob, subfolder: string) { + const form = new FormData(); + form.append('image', data, name); + form.append('subfolder', subfolder); + let r: Response; + try { + r = await fetch(new URL('/upload/image', COMFY), { method: 'POST', body: form }); + } catch { + throw new ComfyError('ComfyUI недоступен'); + } + if (!r.ok) throw new ComfyError('ComfyUI не принял файл: ' + await r.text()); + const j = await r.json() as { name: string; subfolder?: string; type?: string }; + return { filename: j.name, subfolder: j.subfolder ?? '', type: j.type ?? 'input' }; +} + +/** GET /view — файл из папок ComfyUI как есть (Response для потоковой отдачи). */ +export async function view(params: URLSearchParams): Promise { + try { + return await fetch(new URL('/view?' + params, COMFY)); + } catch { + throw new ComfyError('ComfyUI недоступен'); + } +} diff --git a/server/config.ts b/server/config.ts new file mode 100644 index 0000000..fc358d0 --- /dev/null +++ b/server/config.ts @@ -0,0 +1,11 @@ +import path from 'node:path'; + +export const PORT = Number(process.env.PORT ?? 7000); +export const HOST = process.env.HOST ?? '0.0.0.0'; +export const COMFY = new URL(process.env.COMFY ?? 'http://127.0.0.1:8188'); +/** Папка output ComfyUI — для списка файлов на странице «Прогоны». */ +export const COMFY_OUTPUT = process.env.COMFY_OUTPUT ?? 'D:\\AI\\ComfyUI-0.37.0\\ComfyUI\\output'; +/** База SQLite с историей задач и значениями полей форм. */ +export const DB_PATH = process.env.DB_PATH ?? path.join(import.meta.dirname, '..', 'data', 'img2glb.sqlite'); +/** Собранный фронтенд (npm run build). */ +export const DIST = path.join(import.meta.dirname, '..', 'dist'); diff --git a/server/db.ts b/server/db.ts new file mode 100644 index 0000000..620d20c --- /dev/null +++ b/server/db.ts @@ -0,0 +1,452 @@ +// SQLite (встроенный node:sqlite): задачи ComfyUI, батчи картинок и их источники, значения полей форм. +import fs from 'node:fs'; +import path from 'node:path'; +import { DatabaseSync } from 'node:sqlite'; +import type { + BatchImage, BatchState, FileRef, ImageBatch, Job, JobState, Project, SettingsPage, Text2ImgInput, +} from '../shared/api.ts'; +import { DB_PATH } from './config.ts'; +import { glbTriangles } from './glb.ts'; + +fs.mkdirSync(path.dirname(DB_PATH), { recursive: true }); +const db = new DatabaseSync(DB_PATH); +db.exec(` + PRAGMA journal_mode = WAL; + PRAGMA foreign_keys = ON; + + -- задачи ComfyUI (все типы); отслеживаются трекером + CREATE TABLE IF NOT EXISTS jobs ( + id TEXT PRIMARY KEY, -- prompt_id ComfyUI + type TEXT NOT NULL, -- text2img | cleanup | model + created INTEGER NOT NULL, -- мс + state TEXT NOT NULL, -- pending | done | error + error TEXT, + source TEXT, -- JSON FileRef исходника + params TEXT NOT NULL, -- JSON параметров + images TEXT NOT NULL DEFAULT '[]', -- JSON FileRef[] + models TEXT NOT NULL DEFAULT '[]' -- JSON FileRef[] + ); + CREATE INDEX IF NOT EXISTS jobs_type_created ON jobs (type, created DESC); + CREATE INDEX IF NOT EXISTS jobs_state ON jobs (state); + + -- значения полей форм страниц + CREATE TABLE IF NOT EXISTS settings ( + page TEXT PRIMARY KEY, + value TEXT NOT NULL + ); + + -- батч картинок: результат одного запуска text2img или одной загрузки файлов + CREATE TABLE IF NOT EXISTS ImageBatches ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created INTEGER NOT NULL, -- мс + updated INTEGER NOT NULL, + sourceType TEXT NOT NULL, -- text | upload + sourceId INTEGER NOT NULL, -- ImageBatchTextSources.id | ImageBatchUploadSources.id (по sourceType) + state TEXT NOT NULL, -- draft | pending | done | error + error TEXT, + jobId TEXT, -- text: prompt_id последнего запуска в ComfyUI + seedUsed INTEGER, -- text: фактический seed последнего запуска + prompt TEXT, -- text: итоговый позитивный промпт последнего запуска + clonedFrom INTEGER REFERENCES ImageBatches(id) ON DELETE SET NULL + ); + CREATE INDEX IF NOT EXISTS ImageBatches_created ON ImageBatches (created DESC); + + -- пользовательский ввод text2img — всё, что нужно, чтобы повторить запуск + CREATE TABLE IF NOT EXISTS ImageBatchTextSources ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + shape TEXT NOT NULL, + colors TEXT NOT NULL, + template TEXT NOT NULL, -- как ввёл пользователь; пусто — шаблон по умолчанию + negative TEXT NOT NULL, + batchSize INTEGER NOT NULL, + seed TEXT NOT NULL -- как введено; пусто — случайный + ); + + -- загрузка файлов пользователем (один или несколько файлов за раз) + CREATE TABLE IF NOT EXISTS ImageBatchUploadSources ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + files TEXT NOT NULL -- JSON: исходные имена файлов + ); + + -- картинки батчей (сгенерированные и загруженные) + CREATE TABLE IF NOT EXISTS Images ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + batchId INTEGER NOT NULL REFERENCES ImageBatches(id) ON DELETE CASCADE, + filename TEXT NOT NULL, + subfolder TEXT NOT NULL, + type TEXT NOT NULL, -- input | output + UNIQUE (type, subfolder, filename) + ); + CREATE INDEX IF NOT EXISTS Images_batchId ON Images (batchId); + + -- проект: работа над одной картинкой из батча (из одной картинки — только один проект) + CREATE TABLE IF NOT EXISTS Projects ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + created INTEGER NOT NULL, -- мс + imageId INTEGER NOT NULL UNIQUE REFERENCES Images(id) ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS meta ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL + ); +`); + +// Столбцы, добавленные позже: в существующих базах — ALTER TABLE. +function addColumns(table: string, columns: Record) { + const have = new Set((db.prepare(`PRAGMA table_info(${table})`).all() as { name: string }[]).map(c => c.name)); + for (const [name, def] of Object.entries(columns)) if (!have.has(name)) db.exec(`ALTER TABLE ${table} ADD COLUMN ${name} ${def}`); +} +// последняя очищенная картинка проекта (история очисток не хранится) +addColumns('Projects', { + clean: 'TEXT', // JSON FileRef последней очищенной картинки + cleanUpdated: 'INTEGER', // мс + cleanJobId: 'TEXT', // prompt_id идущей очистки + cleanError: 'TEXT', // ошибка последней очистки +}); +// последняя 3D-модель проекта из очищенной картинки (история не хранится) +addColumns('Projects', { + model: 'TEXT', // JSON FileRef GLB + modelPreview: 'TEXT', // JSON FileRef PNG-превью + modelUpdated: 'INTEGER', // мс + modelJobId: 'TEXT', // prompt_id идущей генерации + modelError: 'TEXT', // ошибка последней генерации + modelFaces: 'INTEGER', // число треугольников в GLB (из файла) +}); +// истории очисток и 3D-моделей не хранятся (результат — в проекте) — завершённые задачи удаляются +db.exec(`DELETE FROM jobs WHERE type IN ('cleanup', 'model') AND state <> 'pending'`); + +/** Несколько записей одной транзакцией. */ +export function transaction(fn: () => T): T { + db.exec('BEGIN'); + try { + const res = fn(); + db.exec('COMMIT'); + return res; + } catch (e) { + db.exec('ROLLBACK'); + throw e; + } +} + +// ---------- jobs ---------- + +interface JobRow { + id: string; type: string; created: number; state: string; error: string | null; + source: string | null; params: string; images: string; models: string; +} + +function toJob(row: JobRow): Job { + return { + id: row.id, type: row.type, created: row.created, state: row.state, ...(row.error ? { error: row.error } : {}), + source: row.source ? JSON.parse(row.source) : null, params: JSON.parse(row.params), + images: JSON.parse(row.images), models: JSON.parse(row.models), + } as Job; +} + +const jq = { + insert: db.prepare(`INSERT OR IGNORE INTO jobs (id, type, created, state, error, source, params, images, models) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`), + pending: db.prepare(`SELECT * FROM jobs WHERE state = 'pending'`), + finish: db.prepare('UPDATE jobs SET state = ?, error = ?, images = ?, models = ? WHERE id = ?'), +}; + +export function insertJob(j: Job) { + jq.insert.run(j.id, j.type, j.created, j.state, j.error ?? null, j.source ? JSON.stringify(j.source) : null, + JSON.stringify(j.params), JSON.stringify(j.images), JSON.stringify(j.models)); +} + +export function pendingJobs(): Job[] { + return (jq.pending.all() as unknown as JobRow[]).map(toJob); +} + +export function finishJob(id: string, state: Exclude, result: { error?: string; images?: FileRef[]; models?: FileRef[] }) { + jq.finish.run(state, result.error ?? null, JSON.stringify(result.images ?? []), JSON.stringify(result.models ?? []), id); +} + + +// ---------- settings, meta ---------- + +const sq = { + get: db.prepare('SELECT value FROM settings WHERE page = ?'), + put: db.prepare('INSERT INTO settings (page, value) VALUES (?, ?) ON CONFLICT(page) DO UPDATE SET value = excluded.value'), + getMeta: db.prepare('SELECT value FROM meta WHERE key = ?'), + setMeta: db.prepare('INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value'), +}; + +export function getSettings(page: SettingsPage): object { + const row = sq.get.get(page) as { value: string } | undefined; + return row ? JSON.parse(row.value) : {}; +} + +export function putSettings(page: SettingsPage, value: object) { + sq.put.run(page, JSON.stringify(value)); +} + +export function getMeta(key: string): string | null { + return (sq.getMeta.get(key) as { value: string } | undefined)?.value ?? null; +} + +export function setMeta(key: string, value: string) { + sq.setMeta.run(key, value); +} + +// ---------- ImageBatches + источники + Images ---------- + +interface BatchRow { + id: number; created: number; updated: number; sourceType: string; sourceId: number; state: string; error: string | null; + jobId: string | null; seedUsed: number | null; prompt: string | null; clonedFrom: number | null; + // из ImageBatchTextSources + shape: string | null; colors: string | null; template: string | null; negative: string | null; batchSize: number | null; seed: string | null; + // из ImageBatchUploadSources + files: string | null; +} + +interface ImageRow { id: number; batchId: number; filename: string; subfolder: string; type: string; projectId: number | null } + +/** Картинки с id и проектом (если из картинки создан проект). */ +const SELECT_IMAGES = ` + SELECT i.id, i.batchId, i.filename, i.subfolder, i.type, p.id AS projectId + FROM Images i LEFT JOIN Projects p ON p.imageId = i.id`; + +const SELECT_BATCH = ` + SELECT b.*, t.shape, t.colors, t.template, t.negative, t.batchSize, t.seed, u.files + FROM ImageBatches b + LEFT JOIN ImageBatchTextSources t ON b.sourceType = 'text' AND t.id = b.sourceId + LEFT JOIN ImageBatchUploadSources u ON b.sourceType = 'upload' AND u.id = b.sourceId`; + +const bq = { + get: db.prepare(SELECT_BATCH + ' WHERE b.id = ?'), + list: db.prepare(SELECT_BATCH + ' ORDER BY b.created DESC, b.id DESC LIMIT ?'), + byJob: db.prepare('SELECT id FROM ImageBatches WHERE jobId = ?'), + insertBatch: db.prepare(`INSERT INTO ImageBatches (created, updated, sourceType, sourceId, state, seedUsed, prompt, clonedFrom) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)`), + insertText: db.prepare(`INSERT INTO ImageBatchTextSources (shape, colors, template, negative, batchSize, seed) + VALUES (?, ?, ?, ?, ?, ?)`), + updateText: db.prepare(`UPDATE ImageBatchTextSources SET shape = ?, colors = ?, template = ?, negative = ?, batchSize = ?, seed = ? + WHERE id = ?`), + insertUpload: db.prepare('INSERT INTO ImageBatchUploadSources (files) VALUES (?)'), + touch: db.prepare('UPDATE ImageBatches SET updated = ? WHERE id = ?'), + start: db.prepare(`UPDATE ImageBatches SET state = 'pending', error = NULL, jobId = ?, seedUsed = ?, prompt = ?, updated = ? WHERE id = ?`), + finish: db.prepare('UPDATE ImageBatches SET state = ?, error = ?, updated = ? WHERE id = ?'), + removeBatch: db.prepare('DELETE FROM ImageBatches WHERE id = ?'), + removeText: db.prepare('DELETE FROM ImageBatchTextSources WHERE id = ?'), + removeUpload: db.prepare('DELETE FROM ImageBatchUploadSources WHERE id = ?'), + images: db.prepare(SELECT_IMAGES + ' WHERE i.batchId = ? ORDER BY i.id'), + listImages: db.prepare(SELECT_IMAGES + ` + WHERE i.batchId IN (SELECT id FROM ImageBatches ORDER BY created DESC, id DESC LIMIT ?) ORDER BY i.id`), + image: db.prepare(SELECT_IMAGES + ' WHERE i.id = ?'), + attach: db.prepare('INSERT OR IGNORE INTO Images (batchId, filename, subfolder, type) VALUES (?, ?, ?, ?)'), + imageBatch: db.prepare('SELECT batchId FROM Images WHERE type = ? AND subfolder = ? AND filename = ?'), +}; + +const ref = (i: ImageRow): BatchImage => ({ + id: i.id, filename: i.filename, subfolder: i.subfolder, type: i.type, projectId: i.projectId, +}); + +function toBatch(row: BatchRow, images: BatchImage[]): ImageBatch { + const base = { + id: row.id, created: row.created, updated: row.updated, sourceId: row.sourceId, state: row.state as BatchState, + ...(row.error ? { error: row.error } : {}), clonedFrom: row.clonedFrom, images, + }; + if (row.sourceType === 'upload') { + return { ...base, sourceType: 'upload', source: { id: row.sourceId, files: row.files ? JSON.parse(row.files) : [] } }; + } + return { + ...base, sourceType: 'text', jobId: row.jobId, seedUsed: row.seedUsed, prompt: row.prompt ?? '', + source: { + id: row.sourceId, + input: { shape: row.shape ?? '', colors: row.colors ?? '', template: row.template ?? '', negative: row.negative ?? '', + batch: row.batchSize ?? 1, seed: row.seed ?? '' }, + }, + }; +} + +export function getBatch(id: number): ImageBatch | null { + const row = bq.get.get(id) as BatchRow | undefined; + return row ? toBatch(row, (bq.images.all(id) as unknown as ImageRow[]).map(ref)) : null; +} + +export function listBatches(limit = 1000): ImageBatch[] { + const byBatch = new Map(); + for (const i of bq.listImages.all(limit) as unknown as ImageRow[]) byBatch.set(i.batchId, [...(byBatch.get(i.batchId) ?? []), ref(i)]); + return (bq.list.all(limit) as unknown as BatchRow[]).map(row => toBatch(row, byBatch.get(row.id) ?? [])); +} + +export function batchByJob(jobId: string): number | null { + return (bq.byJob.get(jobId) as { id: number } | undefined)?.id ?? null; +} + +/** В каком батче картинка (или null). */ +export function batchOfImage(i: FileRef): number | null { + return (bq.imageBatch.get(i.type, i.subfolder, i.filename) as { batchId: number } | undefined)?.batchId ?? null; +} + +/** Новый text-батч с источником. Без transaction — вызывать внутри неё, если нужно вместе с другими записями. */ +export function insertTextBatch(input: Text2ImgInput, o: { created?: number; state?: BatchState; clonedFrom?: number | null; + seedUsed?: number | null; prompt?: string | null } = {}): number { + const src = bq.insertText.run(input.shape, input.colors, input.template, input.negative, input.batch, input.seed); + const now = Date.now(); + const res = bq.insertBatch.run(o.created ?? now, now, 'text', Number(src.lastInsertRowid), o.state ?? 'draft', + o.seedUsed ?? null, o.prompt ?? null, o.clonedFrom ?? null); + return Number(res.lastInsertRowid); +} + +export function createTextBatch(input: Text2ImgInput, clonedFrom: number | null = null): number { + return transaction(() => insertTextBatch(input, { clonedFrom })); +} + +/** Новый upload-батч с загруженными картинками (одна загрузка — один батч). */ +export function createUploadBatch(originalNames: string[], images: FileRef[]): number { + return transaction(() => { + const src = bq.insertUpload.run(JSON.stringify(originalNames)); + const now = Date.now(); + const id = Number(bq.insertBatch.run(now, now, 'upload', Number(src.lastInsertRowid), 'done', null, null, null).lastInsertRowid); + attachImages(id, images); + return id; + }); +} + +export function updateTextInput(batch: ImageBatch, input: Text2ImgInput) { + transaction(() => { + bq.updateText.run(input.shape, input.colors, input.template, input.negative, input.batch, input.seed, batch.sourceId); + bq.touch.run(Date.now(), batch.id); + }); +} + +export function startBatch(id: number, jobId: string, seedUsed: number, prompt: string) { + bq.start.run(jobId, seedUsed, prompt, Date.now(), id); +} + +/** Прикрепить картинки к батчу (без своей транзакции). */ +export function attachImages(id: number, images: FileRef[]) { + for (const i of images) bq.attach.run(id, i.filename, i.subfolder, i.type); +} + +/** Завершение запуска: картинки к батчу + состояние (без своей транзакции — трекер вызывает внутри своей). */ +export function finishBatch(id: number, state: 'done' | 'error', images: FileRef[], error?: string) { + attachImages(id, images); + bq.finish.run(state, error ?? null, Date.now(), id); +} + +export function deleteBatch(b: ImageBatch) { + transaction(() => { + bq.removeBatch.run(b.id); + (b.sourceType === 'text' ? bq.removeText : bq.removeUpload).run(b.sourceId); + }); +} + +// ---------- Projects ---------- + +const SELECT_PROJECT = ` + SELECT p.id, p.created, p.clean, p.cleanUpdated, p.cleanJobId, p.cleanError, + p.model, p.modelPreview, p.modelUpdated, p.modelJobId, p.modelError, p.modelFaces, + i.id AS imageId, i.batchId, i.filename, i.subfolder, i.type + FROM Projects p JOIN Images i ON i.id = p.imageId`; + +const pq = { + insert: db.prepare('INSERT OR IGNORE INTO Projects (created, imageId) VALUES (?, ?)'), + byImage: db.prepare('SELECT id FROM Projects WHERE imageId = ?'), + get: db.prepare(SELECT_PROJECT + ' WHERE p.id = ?'), + list: db.prepare(SELECT_PROJECT + ' ORDER BY p.created DESC, p.id DESC LIMIT ?'), + byCleanJob: db.prepare('SELECT id FROM Projects WHERE cleanJobId = ?'), + startClean: db.prepare('UPDATE Projects SET cleanJobId = ?, cleanError = NULL WHERE id = ?'), + finishClean: db.prepare('UPDATE Projects SET clean = COALESCE(?, clean), cleanUpdated = ?, cleanError = ?, cleanJobId = NULL WHERE id = ?'), + clearClean: db.prepare('UPDATE Projects SET clean = NULL, cleanUpdated = NULL, cleanError = NULL WHERE id = ?'), + byModelJob: db.prepare('SELECT id FROM Projects WHERE modelJobId = ?'), + startModel: db.prepare('UPDATE Projects SET modelJobId = ?, modelError = NULL WHERE id = ?'), + finishModel: db.prepare(`UPDATE Projects SET model = COALESCE(?, model), modelPreview = COALESCE(?, modelPreview), + modelFaces = COALESCE(?, modelFaces), modelUpdated = ?, modelError = ?, modelJobId = NULL WHERE id = ?`), + clearModel: db.prepare(`UPDATE Projects SET model = NULL, modelPreview = NULL, modelFaces = NULL, modelUpdated = NULL, modelError = NULL + WHERE id = ?`), + setModelFaces: db.prepare('UPDATE Projects SET modelFaces = ? WHERE id = ?'), +}; + +/** Генерация 3D-модели проекта поставлена в очередь. */ +export function startProjectModel(id: number, jobId: string) { + pq.startModel.run(jobId, id); +} + +export function projectByModelJob(jobId: string): number | null { + return (pq.byModelJob.get(jobId) as { id: number } | undefined)?.id ?? null; +} + +/** Генерация завершена: новая модель заменяет прежнюю (при ошибке прежняя остаётся). */ +export function finishProjectModel(id: number, model: FileRef | null, preview: FileRef | null, error?: string) { + pq.finishModel.run(model ? JSON.stringify(model) : null, preview ? JSON.stringify(preview) : null, + model ? glbTriangles(model) : null, Date.now(), error ?? null, id); +} + +/** Убрать 3D-модель из проекта (файлы в ComfyUI/output остаются). */ +export function clearProjectModel(id: number) { + pq.clearModel.run(id); +} + +/** Убрать очищенную картинку из проекта (файл в ComfyUI/output остаётся). */ +export function clearProjectClean(id: number) { + pq.clearClean.run(id); +} + +interface ProjectRow { + id: number; created: number; clean: string | null; cleanUpdated: number | null; cleanJobId: string | null; cleanError: string | null; + model: string | null; modelPreview: string | null; modelUpdated: number | null; modelJobId: string | null; modelError: string | null; + modelFaces: number | null; + imageId: number; batchId: number; filename: string; subfolder: string; type: string; +} + +const json = (s: string | null) => (s ? JSON.parse(s) : null); + +function toProject(r: ProjectRow): Project { + // модели, прикреплённые до появления modelFaces, — число полигонов считается из файла один раз + if (r.model && r.modelFaces == null) { + r.modelFaces = glbTriangles(JSON.parse(r.model)); + if (r.modelFaces != null) pq.setModelFaces.run(r.modelFaces, r.id); + } + return { + id: r.id, created: r.created, batchId: r.batchId, + image: { id: r.imageId, filename: r.filename, subfolder: r.subfolder, type: r.type, projectId: r.id }, + clean: json(r.clean), cleanUpdated: r.cleanUpdated, + cleanJobId: r.cleanJobId, ...(r.cleanError ? { cleanError: r.cleanError } : {}), + model: json(r.model), modelPreview: json(r.modelPreview), modelUpdated: r.modelUpdated, + modelFaces: r.modelFaces, modelJobId: r.modelJobId, ...(r.modelError ? { modelError: r.modelError } : {}), + }; +} + +export function listProjects(limit = 1000): Project[] { + return (pq.list.all(limit) as unknown as ProjectRow[]).map(toProject); +} + +/** Очистка исходника проекта поставлена в очередь. */ +export function startProjectClean(id: number, jobId: string) { + pq.startClean.run(jobId, id); +} + +export function projectByCleanJob(jobId: string): number | null { + return (pq.byCleanJob.get(jobId) as { id: number } | undefined)?.id ?? null; +} + +/** Очистка завершена: результат заменяет прежнюю очищенную картинку (при ошибке прежняя остаётся). */ +export function finishProjectClean(id: number, clean: FileRef | null, error?: string) { + pq.finishClean.run(clean ? JSON.stringify(clean) : null, Date.now(), error ?? null, id); +} + +export function getImage(id: number): (BatchImage & { batchId: number }) | null { + const row = bq.image.get(id) as ImageRow | undefined; + return row ? { ...ref(row), batchId: row.batchId } : null; +} + +/** Проект из картинки: из одной картинки — только один проект; если уже есть, возвращается он. */ +export function projectForImage(imageId: number): number { + pq.insert.run(Date.now(), imageId); + return (pq.byImage.get(imageId) as { id: number }).id; +} + +export function getProject(id: number): Project | null { + const row = pq.get.get(id) as ProjectRow | undefined; + return row ? toProject(row) : null; +} + +/** Удаление задачи (история очисток не хранится). */ +export function deleteJob(id: string) { + db.prepare('DELETE FROM jobs WHERE id = ?').run(id); +} diff --git a/server/glb.ts b/server/glb.ts new file mode 100644 index 0000000..48cdfa5 --- /dev/null +++ b/server/glb.ts @@ -0,0 +1,69 @@ +// Сведения о GLB-файле из его JSON-чанка (без загрузки геометрии). +import fs from 'node:fs'; +import path from 'node:path'; +import type { FileRef } from '../shared/api.ts'; +import { COMFY_OUTPUT } from './config.ts'; + +interface Gltf { + meshes?: { primitives?: { indices?: number; mode?: number; attributes?: { POSITION?: number } }[] }[]; + accessors?: { count?: number }[]; +} + +/** Путь к файлу в ComfyUI/output или null (не output или выход за папку). */ +export function outputPath(ref: FileRef): string | null { + if (ref.type !== 'output') return null; + const file = path.resolve(COMFY_OUTPUT, ref.subfolder, ref.filename); + return file.startsWith(path.resolve(COMFY_OUTPUT) + path.sep) ? file : null; +} + +/** + * Тот же GLB без нормалей — для просмотра «без сглаживания»: по спецификации glTF при отсутствии NORMAL + * просмотрщик считает плоские нормали (three.js в model-viewer включает flatShading). Геометрия не меняется, + * переписывается только JSON-чанк. + */ +export function glbWithoutNormals(glb: Buffer): Buffer { + if (glb.toString('latin1', 0, 4) !== 'glTF' || glb.toString('latin1', 16, 20) !== 'JSON') throw new Error('не GLB'); + const jsonLen = glb.readUInt32LE(12); + const gltf = JSON.parse(glb.toString('utf8', 20, 20 + jsonLen)) as Gltf; + for (const mesh of gltf.meshes ?? []) for (const prim of mesh.primitives ?? []) delete (prim.attributes as Record)?.NORMAL; + let json = Buffer.from(JSON.stringify(gltf), 'utf8'); + if (json.length % 4) json = Buffer.concat([json, Buffer.alloc(4 - (json.length % 4), 0x20)]); // выравнивание пробелами + const rest = glb.subarray(20 + jsonLen); // BIN-чанк как есть + const head = Buffer.alloc(20); + head.write('glTF', 0, 'latin1'); + head.writeUInt32LE(2, 4); + head.writeUInt32LE(20 + json.length + rest.length, 8); + head.writeUInt32LE(json.length, 12); + head.write('JSON', 16, 'latin1'); + return Buffer.concat([head, json, rest]); +} + +/** Число треугольников в GLB из ComfyUI/output (или null, если файла нет или формат не тот). */ +export function glbTriangles(ref: FileRef): number | null { + const file = outputPath(ref); + if (!file) return null; + let fd: number | undefined; + try { + fd = fs.openSync(file, 'r'); + // заголовок GLB (12 байт) + заголовок первого чанка (8 байт): длина и тип 'JSON' + const head = Buffer.alloc(20); + fs.readSync(fd, head, 0, 20, 0); + if (head.toString('latin1', 0, 4) !== 'glTF' || head.toString('latin1', 16, 20) !== 'JSON') return null; + const json = Buffer.alloc(head.readUInt32LE(12)); + fs.readSync(fd, json, 0, json.length, 20); + const gltf = JSON.parse(json.toString('utf8')) as Gltf; + let triangles = 0; + for (const mesh of gltf.meshes ?? []) { + for (const prim of mesh.primitives ?? []) { + if ((prim.mode ?? 4) !== 4) continue; // только TRIANGLES + const acc = prim.indices ?? prim.attributes?.POSITION; + triangles += Math.floor((gltf.accessors?.[acc ?? -1]?.count ?? 0) / 3); + } + } + return triangles; + } catch { + return null; + } finally { + if (fd !== undefined) fs.closeSync(fd); + } +} diff --git a/server/index.ts b/server/index.ts new file mode 100644 index 0000000..8737fcc --- /dev/null +++ b/server/index.ts @@ -0,0 +1,411 @@ +// Сервер img2glb: API поверх ComfyUI, история в SQLite, раздача собранного фронтенда (dist). +// Запуск: node server/index.ts (PORT, HOST, COMFY, COMFY_OUTPUT, DB_PATH — переменные окружения) +// При первом запуске старые прогоны text2img переносятся в ImageBatches из метаданных PNG (migrate.ts). +import http from 'node:http'; +import fs from 'node:fs'; +import path from 'node:path'; +import { Readable } from 'node:stream'; +import type { ReadableStream as WebStream } from 'node:stream/web'; +import type { + CleanupJob, CleanupRequest, FileRef, ImageBatch, ImportRequest, ModelJob, Project, ProjectModelRequest, QueueInfo, + SettingsPage, Text2ImgInput, Text2ImgJob, +} from '../shared/api.ts'; +import { DEFAULT_TEMPLATE, isLocked } from '../shared/api.ts'; +import { COMFY, DB_PATH, DIST, HOST, PORT } from './config.ts'; +import { ComfyError, comfyJson, queuePrompt, uploadImage, view } from './comfy.ts'; +import { + clearProjectClean, clearProjectModel, createTextBatch, createUploadBatch, deleteBatch, getBatch, getImage, getProject, + getSettings, insertJob, listBatches, listProjects, projectForImage, putSettings, startBatch, startProjectClean, + startProjectModel, transaction, updateTextInput, +} from './db.ts'; +import { glbWithoutNormals, outputPath } from './glb.ts'; +import { migrateOldRuns } from './migrate.ts'; +import { liveStatus, startTracker } from './tracker.ts'; +import { cleanupGraph, escapeTemplate, kindOf, modelGraph, renderTemplate, text2imgGraph } from './workflows.ts'; + +class BadRequest extends Error {} +class NotFound extends Error {} +class Conflict extends Error {} + +/** Подпапка ComfyUI/input для загруженных пользователем картинок. */ +const UPLOAD_DIR = 'img2glb_upload'; + +type Req = http.IncomingMessage; +type Res = http.ServerResponse; + +const SETTINGS_PAGES: SettingsPage[] = ['text2img', 'cleanup', 'model']; + +function send(res: Res, code: number, obj: unknown) { + res.writeHead(code, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-store' }); + res.end(JSON.stringify(obj)); +} + +async function readBuffer(req: Req): Promise { + const chunks: Buffer[] = []; + for await (const c of req) chunks.push(c as Buffer); + return Buffer.concat(chunks); +} + +async function readJson(req: Req): Promise> { + try { + return JSON.parse((await readBuffer(req)).toString() || '{}'); + } catch { + throw new BadRequest('некорректный JSON'); + } +} + +function clamp(v: unknown, min: number, max: number, def: number): number { + const n = v === '' || v == null ? NaN : Number(v); + return Number.isFinite(n) ? Math.min(Math.max(n, min), max) : def; +} + +/** Пустое значение — случайный seed. */ +function parseSeed(v: unknown): number { + if (v === '' || v == null) return Math.floor(Math.random() * 2 ** 48); + const seed = parseInt(String(v), 10); + if (!Number.isFinite(seed) || seed < 0) throw new BadRequest('seed должен быть целым числом ≥ 0'); + return seed; +} + +function safeName(s: string): string { + return s.replace(/[^\p{L}\p{N}._-]+/gu, '_'); +} + +/** FileRef → имя для LoadImage с аннотацией папки: "img2glb_src/x.png [output]". Выход за папку проверяет ComfyUI. */ +function sourceImage(src: Partial | undefined) { + const filename = String(src?.filename ?? ''); + if (!filename) throw new BadRequest('не указана картинка'); + if (!['input', 'output', 'temp'].includes(String(src?.type))) throw new BadRequest('неверный type картинки'); + const ref: FileRef = { filename, subfolder: String(src?.subfolder ?? ''), type: String(src?.type) }; + return { + ref, + image: (ref.subfolder ? ref.subfolder + '/' : '') + filename + ' [' + ref.type + ']', + stem: safeName(path.basename(filename, path.extname(filename))), + }; +} + +// ---------- батчи картинок ---------- + +function batchIdOf(v: string): number { + const id = Number(v); + if (!Number.isInteger(id) || id <= 0) throw new BadRequest('неверный id батча'); + return id; +} + +function batchOrThrow(id: number): ImageBatch { + const b = getBatch(id); + if (!b) throw new NotFound('батч не найден'); + return b; +} + +function withLiveBatch(b: ImageBatch): ImageBatch { + const live = b.sourceType === 'text' && b.state === 'pending' && b.jobId ? liveStatus(b.jobId) : undefined; + return live ? { ...b, live } : b; +} + +const LOCKED = 'у батча уже есть картинки или он в работе — его можно только продублировать'; + +/** Ввод text2img из запроса: обрезка пробелов и точек в конце, проверка seed. */ +function parseInput(v: Partial | undefined): Text2ImgInput { + const seed = String(v?.seed ?? '').trim(); + if (seed !== '' && !/^\d+$/.test(seed)) throw new BadRequest('seed должен быть целым числом ≥ 0 или пустым'); + return { + shape: String(v?.shape ?? '').trim().replace(/\.+$/, ''), + colors: String(v?.colors ?? '').trim().replace(/\.+$/, ''), + template: String(v?.template ?? ''), + negative: String(v?.negative ?? ''), + batch: Math.round(clamp(v?.batch, 1, 8, 1)), + seed, + }; +} + +/** Запуск text-батча: граф в очередь ComfyUI, задача в jobs, батч → pending. */ +async function runBatch(b: ImageBatch): Promise { + if (b.sourceType !== 'text') throw new Conflict('загруженные картинки нельзя запустить'); + if (isLocked(b)) throw new Conflict(LOCKED); + const { shape, colors, negative, batch } = b.source.input; + const template = b.source.input.template.trim() || DEFAULT_TEMPLATE; + if (template.includes('{a}') && !shape) throw new BadRequest('Заполните поле «Форма персонажа»'); + const seed = parseSeed(b.source.input.seed); + const fString = escapeTemplate(template); + const prompt = renderTemplate(fString, { a: shape, b: colors }); + const id = await queuePrompt(text2imgGraph({ template: fString, shape, colors, negative, batch, seed })); + transaction(() => { + insertJob({ + id, type: 'text2img', created: Date.now(), state: 'pending', source: null, images: [], models: [], + params: { batchId: b.id, shape, colors, template, negative, batch, seed, prompt }, + } satisfies Text2ImgJob); + startBatch(b.id, id, seed, prompt); + }); + return batchOrThrow(b.id); +} + +/** Новый text-батч; run — сразу запустить. */ +async function createBatch(req: Req, res: Res) { + const body = await readJson<{ input: Text2ImgInput; run: boolean }>(req); + const b = batchOrThrow(createTextBatch(parseInput(body.input))); + send(res, 200, withLiveBatch(body.run ? await runBatch(b) : b)); +} + +async function editBatch(req: Req, res: Res, id: number) { + const b = batchOrThrow(id); + if (b.sourceType !== 'text') throw new Conflict('у загруженных картинок нет промпта'); + if (isLocked(b)) throw new Conflict(LOCKED); + updateTextInput(b, parseInput((await readJson<{ input: Text2ImgInput }>(req)).input)); + send(res, 200, batchOrThrow(id)); +} + +/** Клон text-батча: тот же ввод, без картинок, можно править и запускать. */ +function duplicateBatch(res: Res, id: number) { + const b = batchOrThrow(id); + if (b.sourceType !== 'text') throw new Conflict('загруженные картинки нельзя продублировать'); + send(res, 200, batchOrThrow(createTextBatch(b.source.input, b.id))); +} + +function removeBatch(res: Res, id: number) { + const b = batchOrThrow(id); + if (isLocked(b)) throw new Conflict('батч с картинками или в работе удалить нельзя'); + deleteBatch(b); + send(res, 200, {}); +} + +/** Загрузка файлов (multipart, поле files): сохраняются в ComfyUI/input/img2glb_upload, одна загрузка — один батч. */ +async function uploadBatch(req: Req, res: Res) { + let form: FormData; + try { + form = await new Request('http://local/', { + method: 'POST', headers: { 'content-type': String(req.headers['content-type'] ?? '') }, + body: Readable.toWeb(req) as ReadableStream, duplex: 'half', + } as RequestInit).formData(); + } catch { + throw new BadRequest('ожидается multipart/form-data с полем files'); + } + type Entry = ReturnType; + const files = form.getAll('files').filter((f): f is Exclude => typeof f !== 'string' && f.size > 0); + if (!files.length) throw new BadRequest('нет файлов'); + const bad = files.find(f => !f.type.startsWith('image/')); + if (bad) throw new BadRequest('не картинка: ' + bad.name); + const images: FileRef[] = []; + for (const f of files) images.push(await uploadImage(safeName(path.basename(f.name)) || 'upload.png', f, UPLOAD_DIR)); + send(res, 200, batchOrThrow(createUploadBatch(files.map(f => f.name), images))); +} + +// ---------- проекты ---------- + +/** Проект из картинки батча: создаёт новый или возвращает уже созданный из этой картинки. */ +async function createProject(req: Req, res: Res) { + const imageId = Number((await readJson<{ imageId: number }>(req)).imageId); + if (!Number.isInteger(imageId) || !getImage(imageId)) throw new NotFound('картинка не найдена'); + send(res, 200, withLiveProject(projectOrThrow(projectForImage(imageId)))); +} + +function projectOrThrow(id: number): Project { + const p = getProject(id); + if (!p) throw new NotFound('проект не найден'); + return p; +} + +function withLiveProject(p: Project): Project { + const live = p.cleanJobId ? liveStatus(p.cleanJobId) : undefined; + const modelLive = p.modelJobId ? liveStatus(p.modelJobId) : undefined; + return { ...p, ...(live ? { live } : {}), ...(modelLive ? { modelLive } : {}) }; +} + +/** + * 3D-модель проекта из его очищенной картинки (Hunyuan3D-2 mini) + PNG-превью. + * Новая модель заменяет прежнюю; история не хранится. + */ +async function projectModel(req: Req, res: Res, projectId: number) { + const p = projectOrThrow(projectId); + if (!p.clean) throw new Conflict('сначала почистите исходник'); + if (p.modelJobId) throw new Conflict('модель уже генерируется'); + const b = await readJson(req); + const src = sourceImage(p.clean); + const seed = parseSeed(b.seed); + const steps = Math.round(clamp(b.steps, 1, 100, 30)); + const octree = Math.round(clamp(b.octree, 64, 512, 380)); + const faces = Math.round(clamp(b.faces, 0, 2_000_000, 5000)); + const id = await queuePrompt(modelGraph({ image: src.image, prefix: 'img2glb_model/' + src.stem, seed, steps, octree, faces })); + transaction(() => { + // задача нужна трекеру только до завершения — потом удаляется + insertJob({ + id, type: 'model', created: Date.now(), state: 'pending', source: src.ref, images: [], models: [], + params: { projectId, seed, steps, octree, faces }, + } satisfies ModelJob); + startProjectModel(projectId, id); + }); + send(res, 200, withLiveProject(projectOrThrow(projectId))); +} + +/** Убрать 3D-модель из проекта — после этого можно сгенерировать заново. */ +function removeProjectModel(res: Res, id: number) { + const p = projectOrThrow(id); + if (p.modelJobId) throw new Conflict('идёт генерация модели'); + clearProjectModel(id); + send(res, 200, withLiveProject(projectOrThrow(id))); +} + +/** + * Очистка исходника проекта: удаление фона BiRefNet, кадрирование по маске в квадрат с отступом, заливка фона. + * Результат заменяет прежнюю очищенную картинку проекта; история очисток не хранится. + */ +async function projectCleanup(req: Req, res: Res, projectId: number) { + const p = projectOrThrow(projectId); + if (p.cleanJobId) throw new Conflict('очистка уже идёт'); + const b = await readJson(req); + const src = sourceImage(p.image); + const size = Math.round(clamp(b.size, 64, 4096, 1024) / 8) * 8; + // Объект вписывается по центру в квадрат (size - 2*margin). ImageCropToMask принимает pad_factor ≤ 2 → margin ≤ size/4. + const margin = Math.round(clamp(b.margin, 0, size / 4, 154)); + const grow = Math.round(clamp(b.grow, -32, 32, 0)); + const background = /^#[0-9a-fA-F]{6}$/.test(String(b.background)) ? String(b.background).toUpperCase() : '#FFFFFF'; + const id = await queuePrompt(cleanupGraph({ + image: src.image, prefix: 'img2glb_clean/' + src.stem, size, pad: size / (size - 2 * margin), grow, background, + })); + transaction(() => { + // задача нужна трекеру только до завершения — потом удаляется + insertJob({ + id, type: 'cleanup', created: Date.now(), state: 'pending', source: src.ref, images: [], models: [], + params: { projectId, size, margin, grow, background }, + } satisfies CleanupJob); + startProjectClean(projectId, id); + }); + send(res, 200, withLiveProject(projectOrThrow(projectId))); +} + +/** Убрать очищенную картинку из проекта — после этого можно почистить заново. */ +function removeProjectClean(res: Res, id: number) { + const p = projectOrThrow(id); + if (p.cleanJobId) throw new Conflict('идёт очистка'); + clearProjectClean(id); + send(res, 200, projectOrThrow(id)); +} + +// ---------- настройки ---------- + +function settingsPage(v: string): SettingsPage { + if (!SETTINGS_PAGES.includes(v as SettingsPage)) throw new BadRequest('неизвестная страница'); + return v as SettingsPage; +} + +async function saveSettings(req: Req, res: Res, page: SettingsPage) { + const value = await readJson(req); + if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new BadRequest('ожидается объект'); + putSettings(page, value); + send(res, 200, value); +} + +/** Однократный перенос значений полей из localStorage старой версии; уже сохранённые не перезаписываются. */ +async function importOld(req: Req, res: Res) { + const b = await readJson(req); + transaction(() => { + for (const page of SETTINGS_PAGES) { + const s = b.settings?.[page]; + if (s && typeof s === 'object' && !Object.keys(getSettings(page)).length) putSettings(page, s); + } + }); + send(res, 200, {}); +} + +// ---------- файлы и ComfyUI ---------- + +/** Очередь для индикатора. Элемент очереди ComfyUI: [номер, prompt_id, граф, extra_data, outputs]. */ +async function queue(res: Res) { + const q = await comfyJson<{ queue_running?: unknown[][]; queue_pending?: unknown[][] }>('/queue'); + const map = (list?: unknown[][]) => (list ?? []).map(x => ({ id: String(x[1]), kind: kindOf(x[2]) })); + send(res, 200, { running: map(q.queue_running), pending: map(q.queue_pending).reverse() } satisfies QueueInfo); +} + +/** Файл из ComfyUI (/view). preview=webp;70 — облегчённое превью для миниатюр. */ +async function image(res: Res, params: URLSearchParams) { + const q = new URLSearchParams({ + filename: params.get('filename') ?? '', subfolder: params.get('subfolder') ?? '', type: params.get('type') ?? 'output', + }); + const preview = params.get('preview') ?? ''; + if (/^(webp|jpeg);\d{1,3}$/.test(preview)) q.set('preview', preview); + const r = await view(q); + res.writeHead(r.status, { 'Content-Type': r.headers.get('content-type') ?? 'application/octet-stream', 'Cache-Control': 'max-age=86400' }); + if (r.body) Readable.fromWeb(r.body as WebStream).pipe(res); + else res.end(); +} + +/** GLB из ComfyUI/output без нормалей — просмотр «без сглаживания» (плоские грани). */ +function glbFlat(res: Res, params: URLSearchParams) { + const file = outputPath({ filename: params.get('filename') ?? '', subfolder: params.get('subfolder') ?? '', type: 'output' }); + if (!file || !/\.glb$/i.test(file) || !fs.existsSync(file)) throw new NotFound('модель не найдена'); + let body: Buffer; + try { body = glbWithoutNormals(fs.readFileSync(file)); } catch { throw new BadRequest('файл не GLB'); } + res.writeHead(200, { 'Content-Type': 'model/gltf-binary', 'Cache-Control': 'max-age=86400' }); + res.end(body); +} + +// ---------- фронтенд ---------- + +const MIME: Record = { + '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', + '.svg': 'image/svg+xml', '.png': 'image/png', '.ico': 'image/x-icon', '.json': 'application/json', '.wasm': 'application/wasm', +}; +/** Страницы приложения (маршруты React Router) — отдаётся index.html. */ +const isPage = (p: string) => ['/', '/projects', '/text2img', '/cleanup', '/img2model'].includes(p) + || /^\/(batch|project)\/\d+$/.test(p); + +function serveStatic(res: Res, pathname: string) { + const file = isPage(pathname) ? path.join(DIST, 'index.html') : path.join(DIST, path.normalize(pathname)); + if (!file.startsWith(DIST + path.sep) || !fs.existsSync(file) || !fs.statSync(file).isFile()) { + return send(res, 404, { error: isPage(pathname) ? 'фронтенд не собран: npm run build' : 'not found' }); + } + res.writeHead(200, { + 'Content-Type': MIME[path.extname(file)] ?? 'application/octet-stream', + // файлы в /assets/ с хешем в имени — кэшируются навсегда; страницы — всегда свежие + 'Cache-Control': pathname.startsWith('/assets/') ? 'max-age=31536000, immutable' : 'no-cache', + }); + fs.createReadStream(file).pipe(res); +} + +// ---------- маршруты ---------- + +http.createServer(async (req, res) => { + const u = new URL(req.url ?? '/', 'http://x'); + const route = req.method + ' ' + u.pathname; + const tail = (prefix: string) => decodeURIComponent(u.pathname.slice(prefix.length)); + try { + if (route === 'GET /api/batches') return send(res, 200, listBatches().map(withLiveBatch)); + if (route === 'POST /api/batches') return await createBatch(req, res); + if (route === 'POST /api/batches/upload') return await uploadBatch(req, res); + const bm = /^\/api\/batches\/(\d+)(?:\/(input|run|duplicate))?$/.exec(u.pathname); + if (bm) { + const id = batchIdOf(bm[1]); + if (req.method === 'GET' && !bm[2]) return send(res, 200, withLiveBatch(batchOrThrow(id))); + if (req.method === 'DELETE' && !bm[2]) return removeBatch(res, id); + if (req.method === 'PUT' && bm[2] === 'input') return await editBatch(req, res, id); + if (req.method === 'POST' && bm[2] === 'run') return send(res, 200, withLiveBatch(await runBatch(batchOrThrow(id)))); + if (req.method === 'POST' && bm[2] === 'duplicate') return duplicateBatch(res, id); + } + if (route === 'GET /api/projects') return send(res, 200, listProjects().map(withLiveProject)); + if (route === 'POST /api/projects') return await createProject(req, res); + const pm = /^\/api\/projects\/(\d+)(?:\/(cleanup|clean|model))?$/.exec(u.pathname); + if (pm && req.method === 'GET' && !pm[2]) return send(res, 200, withLiveProject(projectOrThrow(Number(pm[1])))); + if (pm && req.method === 'POST' && pm[2] === 'cleanup') return await projectCleanup(req, res, Number(pm[1])); + if (pm && req.method === 'DELETE' && pm[2] === 'clean') return removeProjectClean(res, Number(pm[1])); + if (pm && req.method === 'POST' && pm[2] === 'model') return await projectModel(req, res, Number(pm[1])); + if (pm && req.method === 'DELETE' && pm[2] === 'model') return removeProjectModel(res, Number(pm[1])); + if (req.method === 'GET' && u.pathname.startsWith('/api/settings/')) return send(res, 200, getSettings(settingsPage(tail('/api/settings/')))); + if (req.method === 'PUT' && u.pathname.startsWith('/api/settings/')) return await saveSettings(req, res, settingsPage(tail('/api/settings/'))); + if (route === 'POST /api/import') return await importOld(req, res); + if (route === 'GET /api/queue') return await queue(res); + if (route === 'GET /api/image') return await image(res, u.searchParams); + if (route === 'GET /api/glb-flat') return glbFlat(res, u.searchParams); + if (u.pathname.startsWith('/api/')) return send(res, 404, { error: 'not found' }); + if (req.method === 'GET') return serveStatic(res, u.pathname); + send(res, 405, { error: 'method not allowed' }); + } catch (e) { + const message = e instanceof Error ? e.message : String(e); + const code = e instanceof BadRequest ? 400 : e instanceof NotFound ? 404 : e instanceof Conflict ? 409 + : e instanceof ComfyError ? 502 : 500; + if (!res.headersSent) send(res, code, { error: message }); + else res.destroy(); + } +}).listen(PORT, HOST, () => console.log(`http://${HOST}:${PORT} (ComfyUI: ${COMFY.origin}, база: ${DB_PATH})`)); + +migrateOldRuns(); +startTracker(); diff --git a/server/migrate.ts b/server/migrate.ts new file mode 100644 index 0000000..1869993 --- /dev/null +++ b/server/migrate.ts @@ -0,0 +1,80 @@ +// Однократный перенос старых прогонов text2img в ImageBatches. +// ComfyUI (SaveImage) записывает в каждый PNG граф запуска (текстовый чанк "prompt") — из него +// восстанавливается пользовательский ввод; картинки одного батча — подряд идущие файлы с одинаковым графом. +import fs from 'node:fs'; +import path from 'node:path'; +import zlib from 'node:zlib'; +import { COMFY_OUTPUT } from './config.ts'; +import { attachImages, batchOfImage, getMeta, insertTextBatch, setMeta, transaction } from './db.ts'; +import { inputFromGraph } from './workflows.ts'; + +const KEY = 'migration.imageBatches.v1'; +const SRC_DIR = 'img2glb_src'; +/** Картинки одного батча сохраняются почти одновременно. */ +const SAME_BATCH_MS = 15_000; + +/** Текстовые чанки PNG (tEXt, iTXt, zTXt). */ +function pngTexts(file: string): Record { + const b = fs.readFileSync(file); + const out: Record = {}; + let o = 8; + while (o + 8 <= b.length) { + const len = b.readUInt32BE(o); + const type = b.toString('latin1', o + 4, o + 8); + const d = b.subarray(o + 8, o + 8 + len); + const nul = d.indexOf(0); + if (type === 'tEXt') { + out[d.toString('latin1', 0, nul)] = d.toString('latin1', nul + 1); + } else if (type === 'zTXt') { + out[d.toString('latin1', 0, nul)] = zlib.inflateSync(d.subarray(nul + 2)).toString('latin1'); + } else if (type === 'iTXt') { + const compressed = d[nul + 1] === 1; + let p = d.indexOf(0, nul + 3) + 1; // после языка + p = d.indexOf(0, p) + 1; // после переведённого ключа + const text = d.subarray(p); + out[d.toString('latin1', 0, nul)] = (compressed ? zlib.inflateSync(text) : text).toString('utf8'); + } else if (type === 'IEND') { + break; + } + o += 12 + len; + } + return out; +} + +export function migrateOldRuns() { + if (getMeta(KEY)) return; + const dir = path.join(COMFY_OUTPUT, SRC_DIR); + let names: string[] = []; + try { names = fs.readdirSync(dir).filter(n => /\.png$/i.test(n)); } catch { /* папки нет — переносить нечего */ } + + const files = names + .map(name => ({ name, mtime: fs.statSync(path.join(dir, name)).mtimeMs })) + .filter(f => batchOfImage({ filename: f.name, subfolder: SRC_DIR, type: 'output' }) == null) + .sort((a, b) => a.mtime - b.mtime || a.name.localeCompare(b.name)); + + // группировка: одинаковый граф, подряд, в пределах SAME_BATCH_MS от первой картинки + const groups: { graph: string; first: number; names: string[] }[] = []; + let skipped = 0; + for (const f of files) { + let graph: string | undefined; + try { graph = pngTexts(path.join(dir, f.name)).prompt; } catch { /* битый PNG */ } + if (!graph) { skipped++; continue; } + const last = groups[groups.length - 1]; + if (last && last.graph === graph && f.mtime - last.first <= SAME_BATCH_MS) last.names.push(f.name); + else groups.push({ graph, first: f.mtime, names: [f.name] }); + } + + let created = 0; + transaction(() => { + for (const g of groups) { + let parsed; + try { parsed = inputFromGraph(JSON.parse(g.graph)); } catch { parsed = null; } + if (!parsed) { skipped += g.names.length; continue; } + const id = insertTextBatch(parsed.input, { created: Math.round(g.first), state: 'done', seedUsed: parsed.seed, prompt: parsed.prompt }); + attachImages(id, g.names.map(filename => ({ filename, subfolder: SRC_DIR, type: 'output' }))); + created++; + } + setMeta(KEY, new Date().toISOString()); + }); + console.log(`Перенос старых прогонов: батчей ${created}, картинок ${files.length - skipped}` + (skipped ? `, пропущено ${skipped}` : '')); +} diff --git a/server/tracker.ts b/server/tracker.ts new file mode 100644 index 0000000..1c9587d --- /dev/null +++ b/server/tracker.ts @@ -0,0 +1,118 @@ +// Фоновое отслеживание незавершённых задач: результаты из ComfyUI записываются в базу, +// даже если ни одна страница не открыта. +import type { FileRef, Job, LiveStatus } from '../shared/api.ts'; +import { comfyJson } from './comfy.ts'; +import { + batchByJob, deleteJob, finishBatch, finishJob, finishProjectClean, finishProjectModel, pendingJobs, projectByCleanJob, + projectByModelJob, transaction, +} from './db.ts'; + +/** Сколько ждать задачу, которой нет ни в очереди, ни в истории ComfyUI (ComfyUI перезапускался). */ +const LOST_AFTER_MS = 30_000; + +const live = new Map(); +const missingSince = new Map(); + +/** Положение незавершённой задачи в очереди ComfyUI — для показа на страницах. */ +export function liveStatus(id: string): LiveStatus | undefined { + return live.get(id); +} + +interface HistoryEntry { + status?: { status_str?: string; completed?: boolean; messages?: [string, { exception_message?: string }][] }; + outputs?: Record>; +} + +/** Файлы из outputs истории: картинки (SaveImage) и GLB (SaveGLB кладёт их под другим ключом) — по расширению. */ +function outputFiles(h: HistoryEntry) { + const images: FileRef[] = []; + const models: FileRef[] = []; + for (const node of Object.values(h.outputs ?? {})) { + for (const list of Object.values(node)) { + if (!Array.isArray(list)) continue; + for (const i of list as FileRef[]) { + if (typeof i?.filename !== 'string') continue; + if (/\.glb$/i.test(i.filename)) models.push(i); + else if (/\.(png|webp|jpe?g)$/i.test(i.filename)) images.push(i); + } + } + } + return { images, models }; +} + +/** + * Завершение задачи. Картинки text2img прикрепляются к её батчу (Images.batchId); + * результат очистки и модель проекта заменяют прежние в проекте, а сама задача удаляется — история не хранится. + */ +function finish(job: Job, state: 'done' | 'error', result: { error?: string; images?: FileRef[]; models?: FileRef[] }) { + transaction(() => { + if (job.type === 'cleanup') { + const projectId = job.params.projectId ?? projectByCleanJob(job.id); + if (projectId != null) finishProjectClean(projectId, state === 'done' ? result.images?.[0] ?? null : null, result.error); + deleteJob(job.id); + return; + } + // модель проекта: GLB и превью — в проект, задача удаляется (история не хранится) + const modelProject = job.type === 'model' ? job.params.projectId ?? projectByModelJob(job.id) : null; + if (modelProject != null) { + const done = state === 'done'; + finishProjectModel(modelProject, done ? result.models?.[0] ?? null : null, done ? result.images?.[0] ?? null : null, result.error); + deleteJob(job.id); + return; + } + finishJob(job.id, state, result); + const batchId = job.type === 'text2img' ? job.params.batchId ?? batchByJob(job.id) : null; + if (batchId != null) finishBatch(batchId, state, result.images ?? [], result.error); + }); +} + +async function tick() { + const jobs = pendingJobs(); + if (!jobs.length) { + live.clear(); + missingSince.clear(); + return; + } + // ComfyUI недоступен — задачи остаются незавершёнными до его возвращения + const q = await comfyJson<{ queue_running?: unknown[][]; queue_pending?: unknown[][] }>('/queue'); + const running = new Set((q.queue_running ?? []).map(x => String(x[1]))); + const queued = (q.queue_pending ?? []).map(x => String(x[1])); + + for (const job of jobs) { + if (running.has(job.id)) { + live.set(job.id, { state: 'running' }); + missingSince.delete(job.id); + continue; + } + const pos = queued.indexOf(job.id); + if (pos >= 0) { + live.set(job.id, { state: 'queued', position: pos + 1 }); + missingSince.delete(job.id); + continue; + } + const h = (await comfyJson>('/history/' + encodeURIComponent(job.id)))[job.id]; + if (h?.status?.status_str === 'error') { + const err = (h.status.messages ?? []).find(m => m[0] === 'execution_error' || m[0] === 'execution_interrupted'); + finish(job, 'error', { error: err ? err[1].exception_message ?? 'прервано' : 'ошибка выполнения' }); + } else if (h) { + finish(job, 'done', outputFiles(h)); + } else { + // между постановкой в очередь и появлением в истории задачу может не быть видно — ждём + const since = missingSince.get(job.id) ?? Date.now(); + missingSince.set(job.id, since); + if (Date.now() - since < LOST_AFTER_MS) continue; + finish(job, 'error', { error: 'задача не найдена в ComfyUI (перезапускался?)' }); + } + live.delete(job.id); + missingSince.delete(job.id); + } +} + +let busy = false; +export function startTracker(intervalMs = 1500) { + setInterval(async () => { + if (busy) return; + busy = true; + try { await tick(); } catch { /* ComfyUI недоступен — попробуем на следующем шаге */ } finally { busy = false; } + }, intervalMs); +} diff --git a/server/workflows.ts b/server/workflows.ts new file mode 100644 index 0000000..e059cb1 --- /dev/null +++ b/server/workflows.ts @@ -0,0 +1,158 @@ +// Графы ComfyUI в API-формате. Только встроенные ноды ComfyUI 0.37. +import type { JobKind, Text2ImgInput } from '../shared/api.ts'; + +type Graph = Record }>; + +/** SDXL: промпт по шаблону (StringFormat, {a} — форма, {b} — цвета) → картинки в output/img2glb_src. */ +export function text2imgGraph(o: { + template: string; shape: string; colors: string; negative: string; batch: number; seed: number; +}): Graph { + return { + '1': { class_type: 'CheckpointLoaderSimple', inputs: { ckpt_name: 'sd_xl_base_1.0.safetensors' } }, + '2': { class_type: 'PrimitiveStringMultiline', inputs: { value: o.shape } }, + '3': { class_type: 'PrimitiveStringMultiline', inputs: { value: o.colors } }, + '4': { class_type: 'StringFormat', inputs: { 'values.a': ['2', 0], 'values.b': ['3', 0], f_string: o.template } }, + '5': { class_type: 'PrimitiveStringMultiline', inputs: { value: o.negative } }, + '6': { class_type: 'CLIPTextEncode', inputs: { text: ['4', 0], clip: ['1', 1] } }, + '7': { class_type: 'CLIPTextEncode', inputs: { text: ['5', 0], clip: ['1', 1] } }, + '8': { class_type: 'EmptyLatentImage', inputs: { width: 1024, height: 1024, batch_size: o.batch } }, + '9': { class_type: 'KSampler', inputs: { + model: ['1', 0], positive: ['6', 0], negative: ['7', 0], latent_image: ['8', 0], + seed: o.seed, steps: 25, cfg: 7.0, sampler_name: 'dpmpp_2m', scheduler: 'karras', denoise: 1.0 } }, + '10': { class_type: 'VAEDecode', inputs: { samples: ['9', 0], vae: ['1', 2] } }, + '11': { class_type: 'SaveImage', inputs: { images: ['10', 0], filename_prefix: 'img2glb_src/character' } }, + }; +} + +/** Подготовка для Hunyuan3D: удаление фона BiRefNet, кадрирование по маске в квадрат с отступом, заливка фона. */ +export function cleanupGraph(o: { + image: string; prefix: string; size: number; pad: number; grow: number; background: string; +}): Graph { + return { + '1': { class_type: 'LoadImage', inputs: { image: o.image } }, + '2': { class_type: 'LoadBackgroundRemovalModel', inputs: { bg_removal_name: 'BiRefNet-general.safetensors' } }, + '3': { class_type: 'RemoveBackground', inputs: { bg_removal_model: ['2', 0], image: ['1', 0] } }, + '4': { class_type: 'ImageCropToMask', inputs: { + images: ['1', 0], masks: ['3', 0], width: o.size, height: o.size, pad_factor: o.pad, grow_mask: o.grow, background: o.background } }, + '5': { class_type: 'SaveImage', inputs: { images: ['4', 0], filename_prefix: o.prefix } }, + }; +} + +/** Очищенная картинка → GLB через Hunyuan3D-2 mini + PNG-превью меша в ракурсе 3/4. */ +export function modelGraph(o: { + image: string; prefix: string; seed: number; steps: number; octree: number; faces: number; +}): Graph { + return { + '1': { class_type: 'LoadImage', inputs: { image: o.image } }, + '2': { class_type: 'ImageOnlyCheckpointLoader', inputs: { ckpt_name: 'hunyuan3d-dit-v2-mini_fp16.safetensors' } }, + '3': { class_type: 'CLIPVisionEncode', inputs: { clip_vision: ['2', 1], image: ['1', 0], crop: 'none' } }, + '4': { class_type: 'Hunyuan3Dv2Conditioning', inputs: { clip_vision_output: ['3', 0] } }, + '5': { class_type: 'ModelSamplingAuraFlow', inputs: { model: ['2', 0], shift: 1.0 } }, + '6': { class_type: 'EmptyLatentHunyuan3Dv2', inputs: { resolution: 512, batch_size: 1 } }, + '7': { class_type: 'KSampler', inputs: { + model: ['5', 0], positive: ['4', 0], negative: ['4', 1], latent_image: ['6', 0], + seed: o.seed, steps: o.steps, cfg: 5.0, sampler_name: 'euler', scheduler: 'normal', denoise: 1.0 } }, + '8': { class_type: 'VAEDecodeHunyuan3D', inputs: { vae: ['2', 2], samples: ['7', 0], num_chunks: 8000, octree_resolution: o.octree } }, + '9': { class_type: 'VoxelToMesh', inputs: { voxel: ['8', 0], algorithm: 'surface net', threshold: 0.6 } }, + '10': { class_type: 'DecimateMesh', inputs: { mesh: ['9', 0], target_face_count: o.faces, placement_mode: 'midpoint' } }, + '11': { class_type: 'MeshSmoothNormals', inputs: { mesh: ['10', 0], crease_angle: 180.0 } }, + '12': { class_type: 'SaveGLB', inputs: { mesh: ['11', 0], filename_prefix: o.prefix } }, + '13': { class_type: 'RotateMesh', inputs: { mesh: ['11', 0], mode: 'euler_xyz', 'mode.angle_x': 0, 'mode.angle_y': 35, 'mode.angle_z': 0 } }, + '14': { class_type: 'RenderMesh', inputs: { mesh: ['13', 0], mode: 'solid', width: 512, height: 512, background: '#E7E5E4' } }, + '15': { class_type: 'SaveImage', inputs: { images: ['14', 0], filename_prefix: o.prefix + '_preview' } }, + }; +} + +/** Что за задача в очереди — по нодам графа (работает и для задач, запущенных прямо в ComfyUI). */ +export function kindOf(graph: unknown): JobKind { + const types = Object.values((graph ?? {}) as Graph).map(n => n?.class_type); + if (types.includes('SaveGLB')) return '3D-модель'; + if (types.includes('RemoveBackground')) return 'очистка фона'; + if (types.includes('KSampler') && types.includes('CheckpointLoaderSimple')) return 'генерация'; + return 'другое'; +} + +/** То же, что Python str.format для {a}/{b}: {{ и }} превращаются в одиночные скобки. */ +export function renderTemplate(template: string, values: { a: string; b: string }): string { + return template.replace(/\{\{|\}\}|\{([ab])\}/g, (m, k: 'a' | 'b' | undefined) => (k ? values[k] : m[0])); +} + +/** + * Шаблон пользователя → f_string для StringFormat (Python str.format): все скобки, кроме {a} и {b}, удваиваются. + * Значения {a}/{b} format не разбирает — их не экранируем. + */ +export function escapeTemplate(template: string): string { + return template.split(/(\{[ab]\})/).map(p => /^\{[ab]\}$/.test(p) ? p : p.replace(/\{/g, '{{').replace(/\}/g, '}}')).join(''); +} + +/** Обратно к шаблону пользователя: {{ → {, }} → }. */ +export function unescapeTemplate(fString: string): string { + return fString.replace(/\{\{/g, '{').replace(/\}\}/g, '}'); +} + +// ---------- разбор графа text2img (из метаданных PNG) обратно в пользовательский ввод ---------- + +type Link = [string, number]; +const isLink = (v: unknown): v is Link => Array.isArray(v) && typeof v[0] === 'string'; + +/** Значение строкового входа: строка или ссылка на строковую ноду (Primitive, StringConcatenate, StringFormat). */ +function resolveString(graph: Graph, v: unknown, depth = 0): string | null { + if (typeof v === 'string') return v; + if (!isLink(v) || depth > 20) return null; + const node = graph[v[0]]; + if (!node) return null; + const i = node.inputs; + switch (node.class_type) { + case 'PrimitiveStringMultiline': + case 'PrimitiveString': + return resolveString(graph, i.value, depth + 1); + case 'StringConcatenate': { + const a = resolveString(graph, i.string_a, depth + 1); + const b = resolveString(graph, i.string_b, depth + 1); + return a == null || b == null ? null : a + String(i.delimiter ?? '') + b; + } + case 'StringFormat': { + const f = resolveString(graph, i.f_string, depth + 1); + if (f == null) return null; + return renderTemplate(f, { a: resolveString(graph, i['values.a'], depth + 1) ?? '', b: resolveString(graph, i['values.b'], depth + 1) ?? '' }); + } + default: + return null; + } +} + +/** + * Пользовательский ввод из графа text2img. Если промпт собран по шаблону (StringFormat) — форма, цвета и шаблон + * восстанавливаются как были; иначе итоговый текст промпта становится шаблоном без плейсхолдеров. + */ +export function inputFromGraph(graphJson: unknown): { input: Text2ImgInput; seed: number; prompt: string } | null { + const graph = graphJson as Graph; + if (!graph || typeof graph !== 'object') return null; + const ks = Object.values(graph).find(n => n?.class_type === 'KSampler'); + if (!ks || !isLink(ks.inputs.positive) || !isLink(ks.inputs.negative)) return null; + const pos = graph[ks.inputs.positive[0]]; + const neg = graph[ks.inputs.negative[0]]; + if (pos?.class_type !== 'CLIPTextEncode') return null; + const prompt = resolveString(graph, pos.inputs.text); + if (prompt == null) return null; + const latent = isLink(ks.inputs.latent_image) ? graph[ks.inputs.latent_image[0]] : undefined; + const seed = Number(ks.inputs.seed); + const base = { + negative: (neg?.class_type === 'CLIPTextEncode' ? resolveString(graph, neg.inputs.text) : null) ?? '', + batch: Number(latent?.inputs.batch_size ?? 1), + seed: String(seed), + }; + const textLink = pos.inputs.text; + const fmt = isLink(textLink) ? graph[textLink[0]] : undefined; + if (fmt?.class_type === 'StringFormat') { + return { + seed, prompt, input: { + ...base, + template: unescapeTemplate(resolveString(graph, fmt.inputs.f_string) ?? ''), + shape: resolveString(graph, fmt.inputs['values.a']) ?? '', + colors: resolveString(graph, fmt.inputs['values.b']) ?? '', + }, + }; + } + return { seed, prompt, input: { ...base, template: prompt, shape: '', colors: '' } }; +} diff --git a/shared/api.ts b/shared/api.ts new file mode 100644 index 0000000..15749eb --- /dev/null +++ b/shared/api.ts @@ -0,0 +1,240 @@ +// Типы API между страницами и сервером. + +/** Файл в папках ComfyUI (как в ответах ComfyUI и параметрах /view). */ +export interface FileRef { + filename: string; + subfolder: string; + type: string; // 'input' | 'output' | 'temp' +} + +export interface ApiError { + error: string; +} + +// ---------- батчи картинок (ImageBatches + источники + Images) ---------- +/** Пользовательский ввод text2img (ImageBatchTextSources) — всё, что нужно, чтобы повторить запуск. */ +export interface Text2ImgInput { + shape: string; + colors: string; + /** Шаблон как его ввёл пользователь: {a} — форма, {b} — цвета. Пусто — шаблон по умолчанию. */ + template: string; + negative: string; + /** Картинок в батче. */ + batch: number; + /** Как введено: пусто — случайный при каждом запуске. */ + seed: string; +} + +/** + * draft — можно править и запускать; pending — в работе; done / error — завершён. + * Батч с картинками, в работе или из загрузки заблокирован: text-батч можно только продублировать. + */ +export type BatchState = 'draft' | 'pending' | 'done' | 'error'; + +/** Картинка батча (Images): id и проект, если из неё создан проект. */ +export interface BatchImage extends FileRef { + id: number; + projectId: number | null; +} + +/** Проект — работа над одной картинкой из батча. */ +export interface Project { + id: number; + created: number; + /** батч, из которого картинка */ + batchId: number; + /** исходная картинка */ + image: BatchImage; + /** последняя очищенная картинка (история очисток не хранится) */ + clean: FileRef | null; + cleanUpdated: number | null; + /** идёт очистка: prompt_id в ComfyUI */ + cleanJobId: string | null; + /** ошибка последней очистки */ + cleanError?: string; + /** положение идущей очистки в очереди ComfyUI */ + live?: LiveStatus; + /** последняя 3D-модель из очищенной картинки: GLB и PNG-превью (история не хранится) */ + model: FileRef | null; + modelPreview: FileRef | null; + modelUpdated: number | null; + /** число треугольников в GLB (null — неизвестно) */ + modelFaces: number | null; + /** идёт генерация модели: prompt_id в ComfyUI */ + modelJobId: string | null; + modelError?: string; + /** положение идущей генерации модели в очереди ComfyUI */ + modelLive?: LiveStatus; +} + +/** Генерация 3D-модели проекта. */ +export interface ProjectModelRequest { + /** Пусто — случайный. */ + seed: number | string; + steps: number | string; + octree: number | string; + faces: number | string; +} + +interface BatchBase { + id: number; + created: number; + updated: number; + /** ImageBatchTextSources.id или ImageBatchUploadSources.id — по sourceType */ + sourceId: number; + state: BatchState; + error?: string; + /** Из какого батча продублирован. */ + clonedFrom: number | null; + /** Картинки батча (Images.batchId). */ + images: BatchImage[]; + live?: LiveStatus; +} + +export interface TextBatch extends BatchBase { + sourceType: 'text'; + source: { id: number; input: Text2ImgInput }; + /** prompt_id последнего запуска в ComfyUI. */ + jobId: string | null; + /** Фактический seed последнего запуска. */ + seedUsed: number | null; + /** Итоговый позитивный промпт последнего запуска. */ + prompt: string; +} + +export interface UploadBatch extends BatchBase { + sourceType: 'upload'; + /** Исходные имена загруженных файлов. */ + source: { id: number; files: string[] }; +} + +export type ImageBatch = TextBatch | UploadBatch; + +/** В батче есть картинка, из которой создан проект. */ +export function hasProject(b: ImageBatch): boolean { + return b.images.some(i => i.projectId != null); +} + +export function isLocked(b: ImageBatch): boolean { + return b.sourceType === 'upload' || b.state === 'pending' || b.images.length > 0; +} + +// ---------- запросы на запуск ---------- +/** Очистка исходника проекта. */ +export interface CleanupRequest { + size: number | string; + /** Отступ от объекта до края кадра, px с каждой стороны. */ + margin: number | string; + grow: number | string; + background: string; +} + +// ---------- задачи ComfyUI (таблица jobs; отслеживаются трекером) ---------- +export type JobType = 'text2img' | 'cleanup' | 'model'; +export type JobState = 'pending' | 'done' | 'error'; + +/** Состояние незавершённой задачи в очереди ComfyUI (не хранится, считается сервером на лету). */ +export type LiveStatus = { state: 'queued'; position: number } | { state: 'running' }; + +export interface Text2ImgParams { + /** батч (ImageBatches.id), к которому прикрепляются картинки */ + batchId: number; + shape: string; + colors: string; + template: string; + negative: string; + batch: number; + seed: number; + /** Итоговый позитивный промпт, как его увидит модель. */ + prompt: string; +} + +export interface CleanupParams { + /** проект, к которому прикрепляется результат */ + projectId: number; + size: number; + margin: number; + grow: number; + background: string; +} + +export interface ModelParams { + /** проект, к которому прикрепляется модель */ + projectId: number; + seed: number; + steps: number; + octree: number; + faces: number; +} + +interface JobOf { + /** prompt_id в ComfyUI */ + id: string; + type: T; + /** мс с эпохи */ + created: number; + state: JobState; + error?: string; + /** картинка-исходник (для cleanup и model) */ + source: FileRef | null; + params: P; + /** результаты-картинки (для model — PNG-превью) */ + images: FileRef[]; + /** GLB-файлы (только model) */ + models: FileRef[]; + live?: LiveStatus; +} + +export type Text2ImgJob = JobOf<'text2img', Text2ImgParams>; +export type CleanupJob = JobOf<'cleanup', CleanupParams>; +export type ModelJob = JobOf<'model', ModelParams>; +export type Job = Text2ImgJob | CleanupJob | ModelJob; + +// ---------- значения полей форм (тоже в SQLite) ---------- +export interface Text2ImgSettings { + shape: string; + colors: string; + template: string; + negative: string; + batch: string; + seed: string; + promptsOpen: boolean; +} + +export interface CleanupSettings { + size: string; + margin: string; + grow: string; + background: string; +} + +export interface ModelSettings { + seed: string; + steps: string; + octree: string; + faces: string; +} + +export type SettingsByPage = { text2img: Text2ImgSettings; cleanup: CleanupSettings; model: ModelSettings }; +export type SettingsPage = keyof SettingsByPage; + +// ---------- очередь ComfyUI ---------- +export type JobKind = 'генерация' | 'очистка фона' | '3D-модель' | 'другое'; + +export interface QueueItem { + id: string; + kind: JobKind; +} + +export interface QueueInfo { + running: QueueItem[]; + pending: QueueItem[]; +} + +// ---------- перенос из localStorage старой версии ---------- +export interface ImportRequest { + settings: Partial<{ [P in SettingsPage]: Partial }>; +} + +export const DEFAULT_TEMPLATE = + 'Game character. Full body visible. Empty arms. {a}, centered on white background. {b}. Game sprite aesthetic.'; diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..31ce706 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,44 @@ +import { Navigate, Route, Routes, useLocation, useSearchParams } from 'react-router'; +import { Nav } from './components/Nav.tsx'; +import { Batch } from './pages/Batch.tsx'; +import { Project } from './pages/Project.tsx'; +import { Projects } from './pages/Projects.tsx'; +import { Sources } from './pages/Sources.tsx'; + +function title(pathname: string) { + if (pathname.startsWith('/batch/')) return 'Батч #' + pathname.slice(7); + if (pathname.startsWith('/project/')) return 'Проект #' + pathname.slice(9); + return ({ '/': 'Исходники', '/projects': 'Проекты' } as Record)[pathname] ?? 'img2glb'; +} + +/** Старые ссылки /text2img?id=N → страница батча, /text2img → исходники. */ +function LegacyText2Img() { + const id = useSearchParams()[0].get('id'); + return ; +} + +/** Старые ссылки /cleanup?project=N → страница проекта (очистка теперь на ней). */ +function LegacyCleanup() { + const id = useSearchParams()[0].get('project'); + return ; +} + +export function App() { + const { pathname } = useLocation(); + document.title = title(pathname); + return ( +
+
+ ); +} diff --git a/src/components/BatchCard.tsx b/src/components/BatchCard.tsx new file mode 100644 index 0000000..e9fd9cd --- /dev/null +++ b/src/components/BatchCard.tsx @@ -0,0 +1,62 @@ +import { Link } from 'react-router'; +import type { ImageBatch } from '../../shared/api.ts'; +import { hasProject } from '../../shared/api.ts'; +import { thumbUrl } from '../lib/api.ts'; +import { previewPrompt } from './Text2ImgForm.tsx'; + +/** Текст состояния батча: «черновик», «в очереди: позиция 2 · 5 с», «генерация… 12 с», «ошибка: …». */ +export function batchStateText(b: ImageBatch): { text: string; error: boolean } | null { + if (b.state === 'draft') return { text: 'черновик', error: false }; + if (b.state === 'error') return { text: 'ошибка: ' + (b.error ?? ''), error: true }; + if (b.state !== 'pending') return null; + const sec = Math.max(0, Math.round((Date.now() - b.updated) / 1000)); + if (b.live?.state === 'queued') return { text: `в очереди: позиция ${b.live.position} · ${sec} с`, error: false }; + if (b.live?.state === 'running') return { text: `генерация… ${sec} с`, error: false }; + return { text: `ожидание… ${sec} с`, error: false }; +} + +/** «1 картинка», «3 картинки», «6 картинок». */ +function pictures(n: number): string { + const d = n % 10, dd = n % 100; + const word = d === 1 && dd !== 11 ? 'картинка' : d >= 2 && d <= 4 && (dd < 12 || dd > 14) ? 'картинки' : 'картинок'; + return `${n} ${word}`; +} + +/** + * Карточка батча (вся — ссылка на его страницу): картинки батча, под ними строки «форма» и «цвета» (text) + * или «Uploaded» (upload). У старых прогонов без формы и цветов (промпт без шаблона) — промпт целиком. + * Картинки, из которых созданы проекты, и батч с хотя бы одной такой картинкой — с обводкой. + * Показываются только прикреплённые картинки; у запущенного батча недостающие до запрошенного количества — + * пустые блоки с «…»; у черновика — один блок «черновик, N картинок». + */ +export function BatchCard({ batch: b }: { batch: ImageBatch }) { + const lines = b.sourceType === 'upload' ? ['Uploaded'] + : [b.source.input.shape, b.source.input.colors].filter(Boolean); + if (b.sourceType === 'text' && !lines.length) lines.push(b.prompt || previewPrompt(b.source.input)); + const draft = b.sourceType === 'text' && b.state === 'draft'; + // запущенный text-батч: недостающие до запрошенного количества картинки — пустые блоки с «…» + const missing = b.sourceType === 'text' && !draft ? Math.max(0, b.source.input.batch - b.images.length) : 0; + // подсказка: дата и (для text) промпт и негатив целиком + const tooltip = [ + new Date(b.created).toLocaleString(), + ...(b.sourceType === 'text' ? [ + b.prompt || previewPrompt(b.source.input), + ...(b.source.input.negative.trim() ? ['Негатив: ' + b.source.input.negative] : []), + ] : []), + ].join('\n'); + + return ( + +
+ {b.images.map(i => ( +
+ {i.filename} +
+ ))} + {Array.from({ length: missing }, (_, n) =>
…
)} + {draft &&
черновик
{pictures(b.source.input.batch)}
} +
+ {lines.map((line, n) =>
{line}
)} + + ); +} diff --git a/src/components/ModelView.tsx b/src/components/ModelView.tsx new file mode 100644 index 0000000..b49c263 --- /dev/null +++ b/src/components/ModelView.tsx @@ -0,0 +1,113 @@ +import { useEffect, useRef, useState, type ReactNode } from 'react'; +import type { FileRef } from '../../shared/api.ts'; +import { fileUrl } from '../lib/api.ts'; + +// (https://modelviewer.dev) — из node_modules, в сборку попадает отдельным чанком, интернет не нужен. +declare module 'react' { + namespace JSX { + interface IntrinsicElements { + 'model-viewer': DetailedHTMLProps, HTMLElement> & { + src?: string; alt?: string; loading?: string; 'camera-controls'?: string; 'camera-orbit'?: string; + 'shadow-intensity'?: string; 'environment-image'?: string; exposure?: string; + }; + } + } +} + +let loading: Promise | null = null; +function loadModelViewer() { + loading ??= import('@google/model-viewer'); + return loading; +} + +export type View = 'img' | '3d'; + +/** Переключатель из нескольких кнопок. */ +function Seg({ options, value, onChange }: { + options: readonly (readonly [T, string])[]; value: T; onChange: (v: T) => void; +}) { + return ( + e.stopPropagation()}> + {options.map(([v, text]) => ( + + ))} + + ); +} + +/** Переключатель «картинка / 3D». */ +export function ViewToggle({ value, onChange }: { value: View; onChange: (v: View) => void }) { + return ; +} + +/** + * Готовая модель: интерактивный GLB или PNG-превью. + * Пока GLB грузится (или если не загрузился) — вместо 3D показывается превью; что показывать вообще + * (модель или форму) решает вызывающий по записи в базе, а не по загрузке model-viewer. + */ +export function ModelView({ glb, preview, view, onOpen }: { + glb?: FileRef | null; preview?: FileRef | null; view: View; onOpen: (src: string, caption: string) => void; +}) { + const [ready, setReady] = useState(false); // скрипт model-viewer загружен + const [state, setState] = useState<'loading' | 'loaded' | 'error'>('loading'); // загрузка GLB + const [smooth, setSmooth] = useState(true); // «без сглаживания» — тот же GLB без нормалей (плоские грани) + const ref = useRef(null); + const src = !glb ? '' : smooth ? fileUrl(glb) + : '/api/glb-flat?' + new URLSearchParams({ filename: glb.filename, subfolder: glb.subfolder }); + + useEffect(() => { + if (view !== '3d' || !src) return; + let alive = true; + loadModelViewer().then(() => { if (alive) setReady(true); }, () => { if (alive) setState('error'); }); + return () => { alive = false; }; + }, [view, src]); + + useEffect(() => { setState('loading'); }, [src]); + + useEffect(() => { + const el = ref.current; + if (!el) return; + const onLoad = () => setState('loaded'); + const onError = () => setState('error'); + el.addEventListener('load', onLoad); + el.addEventListener('error', onError); + return () => { el.removeEventListener('load', onLoad); el.removeEventListener('error', onError); }; + }, [ready, src, view]); + + const previewImg = preview && ( + {preview.filename} onOpen(fileUrl(preview), preview.filename)} /> + ); + + if (view === '3d' && glb) { + return ( +
+ {ready && ( + + )} + {state !== 'loaded' && (previewImg || загрузка 3D…)} + {state === 'error' && 3D не загрузилась} + + setSmooth(v === 'smooth')} /> + +
+ ); + } + return previewImg || превью нет; +} + +/** Ссылки «GLB» и «PNG» для скачивания; before — ещё кнопки слева от них. */ +export function ModelLinks({ glb, preview, before }: { glb?: FileRef | null; preview?: FileRef | null; before?: ReactNode }) { + const items = [[glb, 'GLB', 'main'], [preview, 'PNG', '']] as const; + return ( +
+ {before} + {items.map(([i, text, cls]) => i && ( + e.stopPropagation()}>{text} + ))} +
+ ); +} diff --git a/src/components/Nav.tsx b/src/components/Nav.tsx new file mode 100644 index 0000000..b38ea6d --- /dev/null +++ b/src/components/Nav.tsx @@ -0,0 +1,57 @@ +import { useEffect, useState } from 'react'; +import { NavLink } from 'react-router'; +import type { QueueInfo, QueueItem } from '../../shared/api.ts'; +import { api } from '../lib/api.ts'; + +const LINKS = [ + ['/', 'Исходники'], + ['/projects', 'Проекты'], +] as const; + +export function Nav() { + return ( + + ); +} + +function counts(list: QueueItem[]): string { + const c = new Map(); + list.forEach(x => c.set(x.kind, (c.get(x.kind) ?? 0) + 1)); + return [...c].map(([k, n]) => k + (n > 1 ? ' ×' + n : '')).join(', '); +} + +/** Состояние очереди ComfyUI: свободен / чем занят и сколько ждёт / недоступен. Обновляется каждые 2 с. */ +function QueueIndicator() { + const [q, setQ] = useState(null); + const [error, setError] = useState(''); + + useEffect(() => { + let alive = true; + const update = async () => { + if (document.hidden) return; + try { + const info = await api('/api/queue'); + if (alive) { setQ(info); setError(''); } + } catch (e) { + if (alive) setError((e as Error).message); + } + }; + void update(); + const t = setInterval(update, 2000); + document.addEventListener('visibilitychange', update); + return () => { alive = false; clearInterval(t); document.removeEventListener('visibilitychange', update); }; + }, []); + + if (error) return ComfyUI недоступен; + if (!q) return ComfyUI…; + if (!q.running.length && !q.pending.length) return ComfyUI свободен; + return ( + + ComfyUI: {counts(q.running) || '—'} + {q.pending.length > 0 && <> · в очереди {q.pending.length}} + + ); +} diff --git a/src/components/Text2ImgForm.tsx b/src/components/Text2ImgForm.tsx new file mode 100644 index 0000000..8a2de66 --- /dev/null +++ b/src/components/Text2ImgForm.tsx @@ -0,0 +1,82 @@ +import type { CSSProperties, FormEvent, ReactNode } from 'react'; +import type { Text2ImgInput, Text2ImgSettings } from '../../shared/api.ts'; +import { DEFAULT_TEMPLATE } from '../../shared/api.ts'; + +export type Values = Text2ImgSettings; +export type SetValue = (k: K, v: Values[K]) => void; + +/** Значения полей для новой генерации, если сохранённых ещё нет. */ +export const DEFAULT_VALUES: Values = { + shape: 'A heavily armored fantasy knight', + colors: 'Deep navy plated armor with gold trim, red cape, glowing red eyes through the visor', + template: '', + negative: '(sprite sheet, character sheet, multiple views, front and back view, turnaround:1.5), (multiple characters, duplicate:1.4), ' + + '(cropped, feet out of frame:1.3), head out of frame, (weapon, sword, holding weapon:1.4), shield, busy background, scenery, ' + + 'cast shadow, text, watermark, signature, blurry, deformed, extra limbs', + batch: '4', + seed: '0', + promptsOpen: false, +}; + +export const toInput = (v: Values): Text2ImgInput => ({ + shape: v.shape, colors: v.colors, template: v.template, negative: v.negative, batch: Number(v.batch), seed: v.seed, +}); + +export const toValues = (i: Text2ImgInput, promptsOpen: boolean): Values => ({ ...i, batch: String(i.batch), promptsOpen }); + +/** Итоговый промпт, как его соберёт сервер (форма и цвета — без точек в конце). */ +export function previewPrompt(v: Pick) { + const clean = (s: string) => s.trim().replace(/\.+$/, ''); + const values: Record = { '{a}': clean(v.shape), '{b}': clean(v.colors) }; + return (v.template.trim() || DEFAULT_TEMPLATE).split(/(\{[ab]\})/).map(p => values[p] ?? p).join(''); +} + +/** + * Поля text2img. readOnly — поля недоступны (батч уже запущен), кнопка действия при этом работает. + * action — кнопка отправки формы («Сгенерировать» или «Дублировать»), extra — дополнительные кнопки рядом. + */ +export function Text2ImgForm({ values: v, set, readOnly, action, actionDisabled, onAction, extra }: { + values: Values; set: SetValue; readOnly: boolean; + action: string; actionDisabled: boolean; onAction: () => void; extra?: ReactNode; +}) { + return ( + { e.preventDefault(); onAction(); }}> +
+