@virtualdisplay.io/client 4.0.0-alpha.3 → 4.0.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +21 -1
  2. package/README.md +36 -161
  3. package/dist/browser-DbgxVbZp.js +1227 -0
  4. package/dist/browser-DiwLZG-y.cjs +8 -0
  5. package/dist/chunk-350yNsax.cjs +1 -0
  6. package/dist/chunk-efA98nb6.js +13 -0
  7. package/dist/src/attributes/attributes.d.ts.map +1 -1
  8. package/dist/src/camera/position.d.ts +16 -3
  9. package/dist/src/camera/position.d.ts.map +1 -1
  10. package/dist/src/client/client.d.ts +10 -47
  11. package/dist/src/client/client.d.ts.map +1 -1
  12. package/dist/src/client/error.d.ts.map +1 -1
  13. package/dist/src/client/iframe-builder.d.ts +11 -9
  14. package/dist/src/client/iframe-builder.d.ts.map +1 -1
  15. package/dist/src/client/options.d.ts +0 -6
  16. package/dist/src/client/options.d.ts.map +1 -1
  17. package/dist/src/client/ready-state-tracker.d.ts +2 -15
  18. package/dist/src/client/ready-state-tracker.d.ts.map +1 -1
  19. package/dist/src/client/types.d.ts +14 -0
  20. package/dist/src/client/types.d.ts.map +1 -1
  21. package/dist/src/index.d.ts +2 -2
  22. package/dist/src/index.d.ts.map +1 -1
  23. package/dist/src/ui/action-bar.d.ts +17 -0
  24. package/dist/src/ui/action-bar.d.ts.map +1 -0
  25. package/dist/src/ui/camera-controls.d.ts +8 -0
  26. package/dist/src/ui/camera-controls.d.ts.map +1 -0
  27. package/dist/src/ui/controls/attribute-group.d.ts +6 -0
  28. package/dist/src/ui/controls/attribute-group.d.ts.map +1 -0
  29. package/dist/src/ui/event-bus.d.ts +12 -0
  30. package/dist/src/ui/event-bus.d.ts.map +1 -0
  31. package/dist/src/ui/loading.d.ts +43 -0
  32. package/dist/src/ui/loading.d.ts.map +1 -0
  33. package/dist/src/ui/standard-interface.d.ts +35 -0
  34. package/dist/src/ui/standard-interface.d.ts.map +1 -0
  35. package/dist/src/ui/styles.d.ts +3 -0
  36. package/dist/src/ui/styles.d.ts.map +1 -0
  37. package/dist/src/ui/toolbar.d.ts +14 -0
  38. package/dist/src/ui/toolbar.d.ts.map +1 -0
  39. package/dist/virtualdisplay.client.cjs.js +225 -1
  40. package/dist/virtualdisplay.client.es.js +1384 -186
  41. package/dist/virtualdisplay.client.umd.js +232 -1
  42. package/package.json +1 -1
  43. package/dist/src/ui/viewer-config.d.ts +0 -63
  44. package/dist/src/ui/viewer-config.d.ts.map +0 -1
@@ -1 +1,225 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e={NO_MAPPING:`NO_MAPPING`,ATTRIBUTE_NOT_FOUND:`ATTRIBUTE_NOT_FOUND`,VALUE_NOT_FOUND:`VALUE_NOT_FOUND`,PARENT_NOT_FOUND:`PARENT_NOT_FOUND`,INVALID_PARAMETER:`INVALID_PARAMETER`,SNAPSHOT_FAILED:`SNAPSHOT_FAILED`},t=class t extends Error{code;constructor(e,n){super(e),this.name=`VirtualdisplayError`,this.code=n,Error.captureStackTrace?.(this,t)}static noMapping(){return new t(`No attributes available. Waiting for server metadata.`,e.NO_MAPPING)}static attributeNotFound(n){return new t(`Attribute "${n}" not found in mapping`,e.ATTRIBUTE_NOT_FOUND)}static valueNotFound(n,r){return new t(`Value "${r}" not found for attribute "${n}"`,e.VALUE_NOT_FOUND)}static parentNotFound(n){return new t(`Parent element not found: ${n}`,e.PARENT_NOT_FOUND)}static invalidParameter(n){return new t(n,e.INVALID_PARAMETER)}static snapshotFailed(n,r){return new t(`Snapshot failed for "${n}": ${r}`,e.SNAPSHOT_FAILED)}},n=class{defaultServer=`https://server.virtualdisplay.io`;options;constructor(e){this.options=e}create(){let e=this.createIframe();return this.attachToParent(e),e}createIframe(){let e=document.createElement(`iframe`);return e.src=this.buildUrl(),Object.assign(e.style,{width:`100%`,height:`100%`,border:`none`}),e.setAttribute(`allow`,`xr-spatial-tracking; fullscreen`),e}attachToParent(e){this.getParentElement().appendChild(e)}buildUrl(){let e=this.getServerUrl(),t=new URL(e);return t.searchParams.set(`license`,this.options.license),t.searchParams.set(`model`,this.options.model),this.options.debug===!0&&t.searchParams.set(`debug`,`true`),this.options.language!==void 0&&t.searchParams.set(`language`,this.options.language),t.toString()}getServerUrl(){return this.defaultServer}getParentElement(){if(typeof this.options.parent!=`string`)return this.options.parent;let e=document.querySelector(this.options.parent);if(e===null)throw t.parentNotFound(this.options.parent);return e}};function r(e){let t=new Date(e.timestamp).toLocaleTimeString(`en-GB`,{hour12:!1}),n=e.level.toUpperCase().padEnd(5),r=e.trace_id?.slice(0,8)??`--------`,i=e.msg,a=[`timestamp`,`level`,`msg`,`service`,`trace_id`,`span_id`],o=Object.entries(e).filter(([e])=>!a.includes(e)).map(([e,t])=>`${e}=${JSON.stringify(t)}`).join(` `);return`${t} ${n} [${r}] ${i}${o?` `+o:``}`}function i(e){return JSON.stringify(e)}function a(e,t){let n=t?r(e):i(e);e.level===`error`?console.error(n):e.level===`warn`?console.warn(n):console.log(n)}function o(){return new Date}function s(e){return e.toISOString()}var c=class e{constructor(e){this.config=e}log(e,t,n={}){let r=this.config.traceProvider?.()??{};a({timestamp:s(o()),level:e,msg:t,service:this.config.service,...r,...n},this.config.isDev)}debug(e,t){this.config.isDev&&this.log(`debug`,e,t)}info(e,t){this.log(`info`,e,t)}warn(e,t){this.log(`warn`,e,t)}error(e,t){this.log(`error`,e,t)}with(t){let n=new e(this.config);return n.log=((e,n,r={})=>{this.log(e,n,{...t,...r})}).bind(this),n}};function l(e,t){return new c({service:e,isDev:t?.isDev===void 0?typeof process<`u`?process.env.NODE_ENV!==`production`:!0:t.isDev,traceProvider:t?.traceProvider})}function u(e){if(e!==void 0)return typeof e==`object`&&e&&!Array.isArray(e)&&!(e instanceof Error)?e:e instanceof Error?{error:e.message}:{value:e}}function d(e){return{debug:(t,n)=>e.debug(t,u(n)),info:(t,n)=>e.info(t,u(n)),warn:(t,n)=>e.warn(t,u(n)),error:(t,n)=>e.error(t,u(n))}}var f=!1,p=d(l(`client`,{isDev:!1}));function m(){f=!0,p=d(l(`client`,{isDev:!0}))}function h(){return f}var g=class{ready=!1;onReady;constructor(e){this.onReady=e}handleMappingReceived(){this.markReady(`Mapping received from server`)}handleMutationResult(e){e.isInitial&&this.markReady(`Initial mutations processed`)}get isReady(){return this.ready}clear(){this.ready=!1}markReady(e){this.ready||(this.ready=!0,p.info(`${e} - client is now ready`),this.onReady?.())}},_=class{isSelectedValue=!1;constructor(e,t){this.value=e,this.attribute=t}get isSelected(){return this.isSelectedValue}setSelected(e){this.isSelectedValue=e}},v=class{name;defaultValue;values;onSelect;onChangeCallback;constructor(e){this.name=e.name,this.defaultValue=e.defaultValue,this.onSelect=e.onSelect,this.values=this.createValues(e.values)}select(e){if(!this.values.has(e))throw t.valueNotFound(this.name,e);this.onSelect(this.name,e)}getValues(){return Array.from(this.values.values())}getValue(e){return this.values.get(e)}onChange(e){this.onChangeCallback=e}handleResult(e){let t;for(let n of this.values.values()){let r=n.value===e;n.setSelected(r),r&&(t=n)}t!==void 0&&this.onChangeCallback!==void 0&&this.onChangeCallback(t)}createValues(e){let t=new Map;for(let n of e){let e=new _(n,this.name);n===this.defaultValue&&e.setSelected(!0),t.set(n,e)}return t}},y=class{attributes=new Map;constructor(e,t,n){for(let n of e){let e=this.buildOptions(n,t);this.attributes.set(n.name,new v(e))}this.onMutationFailed=n}onMutationFailed;get(e){return this.attributes.get(e)}defaults(){let e=[];for(let t of this.attributes.values())t.defaultValue!==void 0&&e.push({name:t.name,value:t.defaultValue});return e}handleResults(e){for(let t of e){if(!t.success){this.onMutationFailed?.(t.name,t.value);continue}this.get(t.name)?.handleResult(t.value)}}buildOptions(e,t){let n={name:e.name,values:e.values,onSelect:(e,n)=>{t([{name:e,value:n}],!1)}};return e.defaultValue===void 0?n:{...n,defaultValue:e.defaultValue}}},b={READY:`ready`,MUTATION:`mutation`,STATE:`state`,CONFIG:`config`,CAMERA:`camera`,SNAPSHOT:`snapshot`,MAPPING:`mapping`},x=new Set(Object.values(b));function S(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.target==`string`?!1:typeof t.type==`string`&&x.has(t.type)}function C(e){let t=O(e);return t!==null&&t.type===b.READY}function w(e){let t=O(e);return t!==null&&t.type===b.MUTATION&&Array.isArray(t.results)}function T(e){let t=O(e);return t!==null&&t.type===b.SNAPSHOT&&(`data`in t||`error`in t)}function E(e){let t=O(e);return t!==null&&t.type===b.CAMERA&&Array.isArray(t.transforms)}function D(e){let t=O(e);return t!==null&&t.type===b.MAPPING&&Array.isArray(t.attributes)}function O(e){return typeof e!=`object`||!e?null:e}var k=class{pending=[];isReady=!1;constructor(e){this.processor=e}enqueue(e){if(this.isReady){this.processor(e);return}this.pending.push(e)}markReady(){if(this.isReady||(this.isReady=!0,this.pending.length===0))return;let e=[...this.pending];this.pending.length=0;for(let t of e)this.processor(t)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(e){return this.pending.some(t=>t.type===e)}clear(){this.pending.length=0}},A=class{handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;constructor(e,t){this.getTarget=e,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.publisher=new k(e=>this.post(e)),this.consumer=new k(e=>this.routeToHandler(e)),this.shouldBuffer=t?.shouldBuffer??null,t?.bufferIncoming!==!0&&this.consumer.markReady()}on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}send(e){this.publisher.enqueue(e)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(e){return this.consumer.hasPending(e)}start(){this.listener===null&&(this.listener=e=>{let{data:t}=e;if(!S(t)||t._source===this.sourceId)return;let n=t;if(this.shouldBuffer!==null&&!this.shouldBuffer(n)){this.routeToHandler(n);return}this.consumer.enqueue(n)},window.addEventListener(`message`,this.listener))}destroy(){this.listener!==null&&(window.removeEventListener(`message`,this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(e){let t=this.getTarget();t!==null&&t.postMessage({...e,_source:this.sourceId},`*`)}routeToHandler(e){let t=this.handlers.get(e.type);if(t===void 0)return;let n=t(e);n instanceof Promise&&n.catch(t=>{let n=t instanceof Error?t.message:String(t);console.error(`Virtualdisplay: error handling ${e.type}: ${n}`)})}};new Set([b.CAMERA]);var j=class{registry;pendingCallbacks=[];constructor(e,t){this.send=e,this.onMutationFailed=t}handleMappingReceived(e){p.debug(`Initializing from server mapping`,{attributeCount:e.attributes.length}),this.registry=new y(e.attributes,(e,t)=>this.sendMutation(e,t),this.onMutationFailed);let t=this.registry.defaults();t.length>0&&this.sendMutation(t,!0),this.replayPendingCallbacks()}handleMutationResult(e){this.registry?.handleResults(e.results)}select(e,t){this.sendMutation([{name:e,value:t}],!1)}getValues(e){return this.registry?.get(e)?.getValues()??[]}getValue(e,t){return this.registry?.get(e)?.getValue(t)}onChange(e,t){if(this.registry===void 0){this.pendingCallbacks.push({name:e,callback:t});return}let n=this.registry.get(e);if(n===void 0){p.warn(`onChange: attribute "${e}" not found — callback will not fire`);return}n.onChange(t)}getAttribute(e){return this.registry?.get(e)}get hasMapping(){return this.registry!==void 0}sendMutation(e,t){let n={type:b.MUTATION,mutations:e,isInitial:t};this.send(n)}replayPendingCallbacks(){for(let{name:e,callback:t}of this.pendingCallbacks){let n=this.registry?.get(e);n===void 0&&p.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`),n?.onChange(t)}this.pendingCallbacks.length=0}},M=class{commands=[];constructor(e){this.send=e}rotate(e){return this.validateFiniteNumber(e,`rotate`),this.commands.push({action:`rotate`,value:e}),this}tilt(e){return this.validateFiniteNumber(e,`tilt`),this.commands.push({action:`tilt`,value:e}),this}zoom(e){return this.validateFiniteNumber(e,`zoom`),this.commands.push({action:`zoom`,value:e}),this}set(){if(this.commands.length===0)throw t.invalidParameter(`No camera commands to execute. Call rotate(), tilt(), or zoom() before set().`);let e={type:b.CAMERA,commands:this.commands};this.send(e),this.commands=[]}validateFiniteNumber(e,n){if(!Number.isFinite(e))throw t.invalidParameter(`${n}() requires a finite number, got ${String(e)}`)}reset(){let e={type:b.CAMERA,commands:[{action:`reset`}]};this.send(e)}},N=class{state;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:0}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(e){this.changeCallbacks.push(e)}handlePositionUpdate(e){this.update(e.transforms)}update(e){let t=!1;for(let n of e)switch(n.type){case`rotation`:this.state.rotation=n.value,t=!0;break;case`tilt`:this.state.tilt=n.value,t=!0;break;case`zoom`:this.state.zoom=n.value,t=!0;break;default:break}if(t){let e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(let t of this.changeCallbacks)t(e)}}},P=class{developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;constructor(e){this.filename=e}onDeveloped(e){return this.developed&&this.photoData!==null?(e(this.photoData),this):(this.developedCallbacks.add(e),this)}onError(e){return this.errorCallbacks.add(e),this}getFilename(){return this.filename}develop(e){this.developed||this.failed||(this.photoData=e,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(e){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(t=>{t(e)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}},F=class{validExtensions=[`.png`];pendingPhotos=new Map;constructor(e){this.send=e}take(e){this.validateFilename(e),p.debug(`Taking snapshot`,{filename:e});let t=new P(e);return this.pendingPhotos.set(t.getFilename(),t),this.send({type:b.SNAPSHOT,filename:e}),t}handleSnapshotResult(n){let r=this.pendingPhotos.get(n.filename);if(r===void 0){p.warn(`No pending photo found for filename`,{filename:n.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())});return}if(this.pendingPhotos.delete(n.filename),n.error!==void 0){r.fail(new t(n.error,e.SNAPSHOT_FAILED));return}n.data!==void 0&&r.develop({filename:n.filename,data:n.data})}validateFilename(n){if(n===``||typeof n!=`string`)throw new t(`Filename must be a non-empty string`,e.INVALID_PARAMETER);if(!this.validExtensions.some(e=>n.toLowerCase().endsWith(e)))throw new t(`Invalid filename: "${n}". Filename must end with one of: ${this.validExtensions.join(`, `)}`,e.INVALID_PARAMETER);if(n.includes(`..`)||n.includes(`/`)||n.includes(`\\`))throw new t(`Filename cannot contain path separators or ".."`,e.INVALID_PARAMETER)}},I=class{send;constructor(e){this.send=e}sendInitialConfig(e){let t=this.buildUIConfig(e),n=this.buildViewerConfig(t,e.camera);n!==void 0&&this.sendConfig(n)}buildUIConfig(e){let t=this.extractUIValues(e);if(Object.values(t).some(e=>e!==void 0))return{...t.arEnabled!==void 0&&{arEnabled:t.arEnabled},...t.fullscreenEnabled!==void 0&&{fullscreenEnabled:t.fullscreenEnabled},...t.loadingIndicatorEnabled!==void 0&&{loadingIndicatorEnabled:t.loadingIndicatorEnabled}}}extractUIValues(e){return{arEnabled:e.arEnabled??e.ui?.arEnabled,fullscreenEnabled:e.fullscreenEnabled??e.ui?.fullscreenEnabled,loadingIndicatorEnabled:e.loadingIndicatorEnabled??e.ui?.loadingIndicatorEnabled}}buildViewerConfig(e,t){if(!(e===void 0&&t===void 0))return{...e!==void 0&&{ui:e},...t!==void 0&&{camera:t}}}setArEnabled(e){p.debug(`Setting AR button enabled: ${e}`),this.updateUIConfig({arEnabled:e})}setFullscreenEnabled(e){p.debug(`Setting fullscreen button enabled: ${e}`),this.updateUIConfig({fullscreenEnabled:e})}setLoadingIndicatorEnabled(e){p.debug(`Setting loading indicator enabled: ${e}`),this.updateUIConfig({loadingIndicatorEnabled:e})}updateUIConfig(e){p.debug(`Updating UI configuration`,e),Object.keys(e).length>0&&this.sendConfig({ui:e})}hideAllUI(){p.debug(`Hiding all UI elements`),this.sendUIConfig({arEnabled:!1,fullscreenEnabled:!1,loadingIndicatorEnabled:!1})}showAllUI(){p.debug(`Showing all UI elements`),this.sendUIConfig({arEnabled:!0,fullscreenEnabled:!0,loadingIndicatorEnabled:!0})}sendUIConfig(e){this.sendConfig({ui:e})}sendConfig(e){let t={type:b.CONFIG,config:e};p.debug(`Sending config`,t),this.send(t)}},L=class{attributes;readyStateTracker;messenger;viewerService;cameraApi;cameraPositionApi;snapshotApi;options;iframe;readyCallbacks=[];mutationFailedCallbacks=[];constructor(e){this.options=e,this.initializeLogging(),this.messenger=new A(()=>this.iframe?.contentWindow??null);let t=e=>{this.messenger.send(e)};this.attributes=new j(t,(e,t)=>{for(let n of this.mutationFailedCallbacks)n({attribute:e,value:t})}),this.readyStateTracker=new g(()=>{let e=this.readyCallbacks;this.readyCallbacks=[];for(let t of e)t(this)}),this.viewerService=new I(t),this.cameraApi=new M(t),this.cameraPositionApi=new N,this.snapshotApi=new F(t),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.messenger.on(b.READY,e=>{C(e)&&(p.info(`Server ready — flushing publisher queue`),this.messenger.markReady(),this.viewerService.sendInitialConfig(this.options))}),this.messenger.on(b.MUTATION,e=>{w(e)&&(this.attributes.handleMutationResult(e),this.readyStateTracker.handleMutationResult(e))}),this.messenger.on(b.SNAPSHOT,e=>{T(e)&&this.snapshotApi.handleSnapshotResult(e)}),this.messenger.on(b.CAMERA,e=>{E(e)&&this.cameraPositionApi.handlePositionUpdate(e)}),this.messenger.on(b.MAPPING,e=>{D(e)&&(this.attributes.handleMappingReceived(e),this.readyStateTracker.handleMappingReceived())})}initializeLogging(){this.options.debug===!0&&m(),p.info(`Initializing Virtualdisplay client`,{model:this.options.model,debug:this.options.debug,language:this.options.language})}createAndConnectIframe(){p.debug(`Creating iframe for Virtualdisplay viewer`),this.iframe=new n(this.options).create(),p.debug(`Iframe created, waiting for server READY`)}select(e,t){this.attributes.select(e,t)}getValues(e){return this.attributes.getValues(e)}getValue(e,t){return this.attributes.getValue(e,t)}onChange(e,t){this.attributes.onChange(e,t)}getAttribute(e){return this.attributes.getAttribute(e)}get isReady(){return this.readyStateTracker.isReady}onReady(e){if(this.readyStateTracker.isReady){e(this);return}this.readyCallbacks.push(e)}onMutationFailed(e){this.mutationFailedCallbacks.push(e)}get viewer(){return this.viewerService}get camera(){return this.cameraApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}destroy(){p.info(`Destroying Virtualdisplay client`),this.readyStateTracker.clear(),this.readyCallbacks=[],this.messenger.destroy(),this.iframe?.parentElement!==null&&this.iframe?.parentElement!==void 0&&this.iframe.parentElement.removeChild(this.iframe),this.iframe=void 0,p.debug(`Virtualdisplay client destroyed`)}};exports.Attribute=v,exports.AttributeValue=_,exports.Camera=M,exports.ERROR_CODES=e,exports.Photo=P,exports.Snapshot=F,exports.VirtualdisplayClient=L,exports.VirtualdisplayError=t,exports.VirtualdisplayViewerService=I,exports.enableDebugMode=m,exports.isDebugMode=h,Object.defineProperty(exports,`logger`,{enumerable:!0,get:function(){return p}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-350yNsax.cjs`);var t={NO_MAPPING:`NO_MAPPING`,ATTRIBUTE_NOT_FOUND:`ATTRIBUTE_NOT_FOUND`,VALUE_NOT_FOUND:`VALUE_NOT_FOUND`,PARENT_NOT_FOUND:`PARENT_NOT_FOUND`,INVALID_PARAMETER:`INVALID_PARAMETER`,SNAPSHOT_FAILED:`SNAPSHOT_FAILED`},n=class e extends Error{code;constructor(e,t){super(e),this.name=`VirtualdisplayError`,this.code=t}static noMapping(){return new e(`No attributes available. Waiting for server metadata.`,t.NO_MAPPING)}static attributeNotFound(n){return new e(`Attribute "${n}" not found in mapping`,t.ATTRIBUTE_NOT_FOUND)}static valueNotFound(n,r){return new e(`Value "${r}" not found for attribute "${n}"`,t.VALUE_NOT_FOUND)}static parentNotFound(n){return new e(`Parent element not found: ${n}`,t.PARENT_NOT_FOUND)}static invalidParameter(n){return new e(n,t.INVALID_PARAMETER)}static snapshotFailed(n,r){return new e(`Snapshot failed for "${n}": ${r}`,t.SNAPSHOT_FAILED)}},r=class{defaultServer=`https://server.virtualdisplay.io`;options;constructor(e){this.options=e}create(){let e=this.createContainer(),t=this.createIframe();return e.appendChild(t),this.attachToParent(e),{container:e,iframe:t}}createContainer(){let e=document.createElement(`div`);return e.className=`vd-container`,Object.assign(e.style,{position:`relative`,width:`100%`,height:`100%`,overflow:`hidden`}),e}createIframe(){let e=document.createElement(`iframe`);return e.src=this.buildUrl(),Object.assign(e.style,{width:`100%`,height:`100%`,border:`none`,display:`block`}),e.setAttribute(`allow`,`xr-spatial-tracking; fullscreen`),e}attachToParent(e){this.getParentElement().appendChild(e)}buildUrl(){let e=this.getServerUrl(),t=new URL(e);return t.searchParams.set(`license`,this.options.license),t.searchParams.set(`model`,this.options.model),this.options.language!==void 0&&t.searchParams.set(`language`,this.options.language),this.options.debug===!0&&t.searchParams.set(`debug`,`true`),t.toString()}getServerUrl(){return this.defaultServer}getParentElement(){if(typeof this.options.parent!=`string`)return this.options.parent;let e=document.querySelector(this.options.parent);if(e===null)throw n.parentNotFound(this.options.parent);return e}};function i(e){let t=new Date(e.timestamp).toLocaleTimeString(`en-GB`,{hour12:!1}),n=e.level.toUpperCase().padEnd(5),r=e.trace_id?.slice(0,8)??`--------`,i=e.msg,a=[`timestamp`,`level`,`msg`,`service`,`trace_id`,`span_id`],o=Object.entries(e).filter(([e])=>!a.includes(e)).map(([e,t])=>`${e}=${JSON.stringify(t)}`).join(` `);return`${t} ${n} [${r}] ${i}${o?` `+o:``}`}function a(e){return JSON.stringify(e)}function o(e,t){let n=t?i(e):a(e);e.level===`error`?console.error(n):e.level===`warn`?console.warn(n):console.log(n)}function s(){return new Date}function c(e){return e.toISOString()}var l=class e{constructor(e){this.config=e}log(e,t,n={}){let r=this.config.traceProvider?.()??{};o({timestamp:c(s()),level:e,msg:t,service:this.config.service,...r,...n},this.config.isDev)}debug(e,t){this.config.isDev&&this.log(`debug`,e,t)}info(e,t){this.log(`info`,e,t)}warn(e,t){this.log(`warn`,e,t)}error(e,t){this.log(`error`,e,t)}with(t){let n=new e(this.config);return n.log=((e,n,r={})=>{this.log(e,n,{...t,...r})}).bind(this),n}};function u(e,t){return new l({service:e,isDev:t?.isDev===void 0?typeof process<`u`?process.env.NODE_ENV!==`production`:!0:t.isDev,traceProvider:t?.traceProvider})}function d(e){if(e!==void 0)return typeof e==`object`&&e&&!Array.isArray(e)&&!(e instanceof Error)?e:e instanceof Error?{error:e.message}:{value:e}}function f(e){return{debug:(t,n)=>e.debug(t,d(n)),info:(t,n)=>e.info(t,d(n)),warn:(t,n)=>e.warn(t,d(n)),error:(t,n)=>e.error(t,d(n))}}var p=!1,m=f(u(`client`,{isDev:!1}));function h(){p=!0,m=f(u(`client`,{isDev:!0}))}function g(){return p}var _=class{ready=!1;onReady;constructor(e){this.onReady=e}handleMappingReceived(){this.ready||(this.ready=!0,m.info(`Mapping received from server, client is now ready`),this.onReady?.())}get isReady(){return this.ready}clear(){this.ready=!1}},v=class{isSelectedValue=!1;constructor(e,t){this.value=e,this.attribute=t}get isSelected(){return this.isSelectedValue}setSelected(e){this.isSelectedValue=e}},ee=class{name;defaultValue;values;onSelect;onChangeCallback;constructor(e){this.name=e.name,this.defaultValue=e.defaultValue,this.onSelect=e.onSelect,this.values=this.createValues(e.values)}select(e){if(!this.values.has(e))throw n.valueNotFound(this.name,e);this.onSelect(this.name,e)}getValues(){return Array.from(this.values.values())}getValue(e){return this.values.get(e)}onChange(e){this.onChangeCallback=e}handleResult(e){let t;for(let n of this.values.values()){let r=n.value===e;n.setSelected(r),r&&(t=n)}t!==void 0&&this.onChangeCallback!==void 0&&this.onChangeCallback(t)}createValues(e){let t=new Map;for(let n of e){let e=new v(n,this.name);n===this.defaultValue&&e.setSelected(!0),t.set(n,e)}return t}},te=class{attributes=new Map;constructor(e,t,n){for(let n of e){let e=this.buildOptions(n,t);this.attributes.set(n.name,new ee(e))}this.onMutationFailed=n}onMutationFailed;get(e){return this.attributes.get(e)}defaults(){let e=[];for(let t of this.attributes.values())t.defaultValue!==void 0&&e.push({name:t.name,value:t.defaultValue});return e}handleResults(e){for(let t of e){if(!t.success){this.onMutationFailed?.(t.name,t.value);continue}this.get(t.name)?.handleResult(t.value)}}buildOptions(e,t){let n={name:e.name,values:e.values,onSelect:(e,n)=>{t([{name:e,value:n}],!1)}};return e.defaultValue===void 0?n:{...n,defaultValue:e.defaultValue}}},y={HANDSHAKE:`handshake`,MUTATION:`mutation`,STATE:`state`,LOADING_INDICATOR:`loading_indicator`,CAMERA:`camera`,SNAPSHOT:`snapshot`,MAPPING:`mapping`,AR_ACTIVATE:`ar_activate`,CONFIG:`config`,INTERACTION:`interaction`},ne=new Set(Object.values(y));function re(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.target==`string`?!1:typeof t.type==`string`&&ne.has(t.type)}function ie(e){let t=b(e);return t!==null&&t.type===y.HANDSHAKE}function ae(e){let t=b(e);return t!==null&&t.type===y.MUTATION&&Array.isArray(t.results)}function oe(e){let t=b(e);return t!==null&&t.type===y.SNAPSHOT&&(`data`in t||`error`in t)}function se(e){let t=b(e);return t!==null&&t.type===y.CAMERA&&Array.isArray(t.transforms)}function ce(e){let t=b(e);return t!==null&&t.type===y.MAPPING&&Array.isArray(t.attributes)}function le(e){let t=b(e);return t!==null&&t.type===y.LOADING_INDICATOR&&typeof t.progress==`number`}function ue(e){let t=b(e);return t!==null&&t.type===y.CONFIG&&typeof t.viewerSettings==`object`}function b(e){return typeof e!=`object`||!e?null:e}var de=class{pending=[];isReady=!1;constructor(e){this.processor=e}enqueue(e){if(this.isReady){this.processor(e);return}this.pending.push(e)}markReady(){if(this.isReady||(this.isReady=!0,this.pending.length===0))return;let e=[...this.pending];this.pending.length=0;for(let t of e)this.processor(t)}get ready(){return this.isReady}get pendingCount(){return this.pending.length}hasPending(e){return this.pending.some(t=>t.type===e)}clear(){this.pending.length=0}},fe=class{handlers=new Map;publisher;consumer;shouldBuffer;listener=null;sourceId;constructor(e,t){this.getTarget=e,this.sourceId=`vd-${Math.random().toString(36).slice(2,8)}`,this.publisher=new de(e=>this.post(e)),this.consumer=new de(e=>this.routeToHandler(e)),this.shouldBuffer=t?.shouldBuffer??null,t?.bufferIncoming!==!0&&this.consumer.markReady()}on(e,t){this.handlers.set(e,t)}off(e){this.handlers.delete(e)}send(e){this.publisher.enqueue(e)}markReady(){this.publisher.markReady()}markConsumerReady(){this.consumer.markReady()}consumerHasPending(e){return this.consumer.hasPending(e)}start(){this.listener===null&&(this.listener=e=>{let{data:t}=e;if(!re(t)||t._source===this.sourceId)return;let n=t;if(this.shouldBuffer!==null&&!this.shouldBuffer(n)){this.routeToHandler(n);return}this.consumer.enqueue(n)},window.addEventListener(`message`,this.listener))}destroy(){this.listener!==null&&(window.removeEventListener(`message`,this.listener),this.listener=null),this.publisher.clear(),this.consumer.clear(),this.handlers.clear()}get ready(){return this.publisher.ready}get pendingCount(){return this.publisher.pendingCount}post(e){let t=this.getTarget();t!==null&&t.postMessage({...e,_source:this.sourceId},`*`)}routeToHandler(e){let t=this.handlers.get(e.type);if(t===void 0)return;let n=t(e);n instanceof Promise&&n.catch(t=>{let n=t instanceof Error?t.message:String(t);console.error(`Virtualdisplay: error handling ${e.type}: ${n}`)})}};new Set([y.CAMERA]);var pe=class{registry;pendingCallbacks=[];constructor(e,t){this.send=e,this.onMutationFailed=t}handleMappingReceived(e){m.debug(`Initializing from server mapping`,{attributeCount:e.attributes.length}),this.registry=new te(e.attributes,(e,t)=>this.sendMutation(e,t),this.onMutationFailed),this.replayPendingCallbacks()}handleMutationResult(e){this.registry?.handleResults(e.results)}select(e,t){this.sendMutation([{name:e,value:t}],!1)}getValues(e){return this.registry?.get(e)?.getValues()??[]}getValue(e,t){return this.registry?.get(e)?.getValue(t)}onChange(e,t){if(this.registry===void 0){this.pendingCallbacks.push({name:e,callback:t});return}let n=this.registry.get(e);if(n===void 0){m.warn(`onChange: attribute "${e}" not found — callback will not fire`);return}n.onChange(t)}getAttribute(e){return this.registry?.get(e)}get hasMapping(){return this.registry!==void 0}sendMutation(e,t){let n={type:y.MUTATION,mutations:e,isInitial:t};this.send(n)}replayPendingCallbacks(){for(let{name:e,callback:t}of this.pendingCallbacks){let n=this.registry?.get(e);n===void 0&&m.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`),n?.onChange(t)}this.pendingCallbacks.length=0}},me=class{commands=[];constructor(e){this.send=e}rotate(e){return this.validateFiniteNumber(e,`rotate`),this.commands.push({action:`rotate`,value:e}),this}tilt(e){return this.validateFiniteNumber(e,`tilt`),this.commands.push({action:`tilt`,value:e}),this}zoom(e){return this.validateFiniteNumber(e,`zoom`),this.commands.push({action:`zoom`,value:e}),this}set(){if(this.commands.length===0)throw n.invalidParameter(`No camera commands to execute. Call rotate(), tilt(), or zoom() before set().`);let e={type:y.CAMERA,commands:this.commands};this.send(e),this.commands=[]}validateFiniteNumber(e,t){if(!Number.isFinite(e))throw n.invalidParameter(`${t}() requires a finite number, got ${String(e)}`)}reset(){let e={type:y.CAMERA,commands:[{action:`reset`}]};this.send(e)}},he=class{state;limitsState;changeCallbacks=[];constructor(){this.state={rotation:0,tilt:0,zoom:100}}get rotation(){return this.state.rotation}get tilt(){return this.state.tilt}get zoom(){return this.state.zoom}onChange(e){this.changeCallbacks.push(e)}get limits(){return this.limitsState}applyLimits(e){this.limitsState=e;let t={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(let e of this.changeCallbacks)e(t)}handlePositionUpdate(e){this.update(e.transforms)}update(e){let t=!1;for(let n of e)switch(n.type){case`rotation`:this.state.rotation=n.value,t=!0;break;case`tilt`:this.state.tilt=n.value,t=!0;break;case`zoom`:this.state.zoom=n.value,t=!0;break;default:break}if(t){let e={rotation:this.rotation,tilt:this.tilt,zoom:this.zoom};for(let t of this.changeCallbacks)t(e)}}},ge=class{developedCallbacks=new Set;errorCallbacks=new Set;developed=!1;failed=!1;photoData=null;constructor(e){this.filename=e}onDeveloped(e){return this.developed&&this.photoData!==null?(e(this.photoData),this):(this.developedCallbacks.add(e),this)}onError(e){return this.errorCallbacks.add(e),this}getFilename(){return this.filename}develop(e){this.developed||this.failed||(this.photoData=e,this.developed=!0,this.developedCallbacks.forEach(e=>{e(this.photoData)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}fail(e){this.developed||this.failed||(this.failed=!0,this.errorCallbacks.forEach(t=>{t(e)}),this.developedCallbacks.clear(),this.errorCallbacks.clear())}},_e=class{validExtensions=[`.png`];pendingPhotos=new Map;constructor(e){this.send=e}take(e){this.validateFilename(e),m.debug(`Taking snapshot`,{filename:e});let t=new ge(e);return this.pendingPhotos.set(t.getFilename(),t),this.send({type:y.SNAPSHOT,filename:e}),t}handleSnapshotResult(e){let r=this.pendingPhotos.get(e.filename);if(r===void 0){m.warn(`No pending photo found for filename`,{filename:e.filename,pendingFilenames:Array.from(this.pendingPhotos.keys())});return}if(this.pendingPhotos.delete(e.filename),e.error!==void 0){r.fail(new n(e.error,t.SNAPSHOT_FAILED));return}e.data!==void 0&&r.develop({filename:e.filename,data:e.data})}validateFilename(e){if(e===``||typeof e!=`string`)throw new n(`Filename must be a non-empty string`,t.INVALID_PARAMETER);if(!this.validExtensions.some(t=>e.toLowerCase().endsWith(t)))throw new n(`Invalid filename: "${e}". Filename must end with one of: ${this.validExtensions.join(`, `)}`,t.INVALID_PARAMETER);if(e.includes(`..`)||e.includes(`/`)||e.includes(`\\`))throw new n(`Filename cannot contain path separators or ".."`,t.INVALID_PARAMETER)}},ve=class{container=null;attach(e){this.container=e}dispatch(e,t,n=!1){let r=new CustomEvent(e,{detail:t,cancelable:n});return this.container?.dispatchEvent(r),r}on(e,t){let n=e=>{let n=e;t({...n.detail,preventDefault:()=>{n.preventDefault()}})};return this.container?.addEventListener(e,n),()=>{this.container?.removeEventListener(e,n)}}},ye={},be=[`en`,`nl`,`de`],x=[`baseLocale`],S=[],C,w;function xe(e){if(S.length===0)return;let t=typeof e==`string`?e:e.href;if(C===t)return w;let n=new URL(t,`http://dummy.com`),r;for(let e of S)if(new ye(e.match,n.href).exec(n.href)){r=e;break}return C=t,w=r,r}function T(e){let t=xe(e);return t&&t.exclude!==!0&&Array.isArray(t.strategy)?t.strategy:x}var E=void 0,D=typeof window>`u`;globalThis.__paraglide=globalThis.__paraglide??{},globalThis.__paraglide.ssr=globalThis.__paraglide.ssr??{};var O=!1,k=()=>{if(E){let e=E?.getStore()?.locale;if(e)return e}let e=x;!D&&typeof window<`u`&&window.location?.href&&(e=T(window.location.href));let t=Se(e,typeof window<`u`?window.location?.href:void 0);if(t)return O||(O=!0,A(t,{reload:!1})),t;throw Error(`No locale found. Read the docs https://inlang.com/m/gerre34r/library-inlang-paraglideJs/errors#no-locale-found`)};function Se(e,t){let n;for(let t of e){if(t===`baseLocale`)n=`en`;else if(N(t)&&M.has(t)){let e=M.get(t);if(e){let t=e.getLocale();if(t instanceof Promise)continue;if(t!==void 0)return we(t)}}let e=j(n);if(e)return e}}var Ce=e=>{e?window.location.href=e:window.location.reload()},A=(e,t)=>{let n={reload:!0,...t},r;try{r=k()}catch{}let i=[],a=x;!D&&typeof window<`u`&&window.location?.href&&(a=T(window.location.href));for(let t of a)if(t===`baseLocale`)continue;else if(N(t)&&M.has(t)){let n=M.get(t);if(n){let r=n.setLocale(e);r instanceof Promise&&(r=r.catch(e=>{throw Error(`Custom strategy "${t}" setLocale failed.`,{cause:e})}),i.push(r))}}let o=()=>{!D&&n.reload&&window.location&&e!==r&&Ce(void 0)};if(i.length)return Promise.all(i).then(()=>{o()});o()};function j(e){if(typeof e!=`string`)return;let t=e.toLowerCase();for(let e of be)if(e.toLowerCase()===t)return e}function we(e){let t=j(e);if(t)return t;throw Error(`Invalid locale: ${e}. Expected one of: ${be.join(`, `)}`)}var M=new Map;function N(e){return typeof e==`string`&&/^custom-[A-Za-z0-9_-]+$/.test(e)}var Te=()=>`Activate AR`,Ee=()=>`AR activeren`,De=()=>`AR aktivieren`,Oe=((e={},t={})=>{let n=t.locale??k();return n===`en`?Te(e):n===`nl`?Ee(e):De(e)}),ke=()=>`Scan to view in AR`,Ae=()=>`Scan om in AR te bekijken`,je=()=>`Scannen für AR-Ansicht`,Me=((e={},t={})=>{let n=t.locale??k();return n===`en`?ke(e):n===`nl`?Ae(e):je(e)}),Ne=()=>`Use your smartphone camera to scan this QR code`,Pe=()=>`Gebruik de camera van uw smartphone om deze QR-code te scannen`,Fe=()=>`Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen`,Ie=((e={},t={})=>{let n=t.locale??k();return n===`en`?Ne(e):n===`nl`?Pe(e):Fe(e)}),Le=()=>`The 3D model will open in your phone's AR mode`,Re=()=>`Het 3D-model wordt geopend in de AR-modus van uw telefoon`,ze=()=>`Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet`,Be=((e={},t={})=>{let n=t.locale??k();return n===`en`?Le(e):n===`nl`?Re(e):ze(e)}),Ve=()=>`Close`,He=()=>`Sluiten`,Ue=()=>`Schließen`,We=((e={},t={})=>{let n=t.locale??k();return n===`en`?Ve(e):n===`nl`?He(e):Ue(e)}),Ge=()=>`Toggle fullscreen`,Ke=()=>`Volledig scherm`,qe=()=>`Vollbild umschalten`,Je=((e={},t={})=>{let n=t.locale??k();return n===`en`?Ge(e):n===`nl`?Ke(e):qe(e)}),Ye=()=>`Downloading`,Xe=()=>`Downloaden`,Ze=()=>`Herunterladen`,P=((e={},t={})=>{let n=t.locale??k();return n===`en`?Ye(e):n===`nl`?Xe(e):Ze(e)}),Qe=()=>`Rendering`,$e=()=>`Renderen`,et=()=>`Rendern`,tt=((e={},t={})=>{let n=t.locale??k();return n===`en`?Qe(e):n===`nl`?$e(e):et(e)}),nt=()=>`Screenshot`,rt=()=>`Screenshot`,it=()=>`Screenshot`,at=((e={},t={})=>{let n=t.locale??k();return n===`en`?nt(e):n===`nl`?rt(e):it(e)}),ot=()=>`Reset camera`,st=()=>`Camera resetten`,ct=()=>`Kamera zurücksetzen`,lt=((e={},t={})=>{let n=t.locale??k();return n===`en`?ot(e):n===`nl`?st(e):ct(e)}),ut=()=>`Zoom in`,dt=()=>`Inzoomen`,ft=()=>`Hineinzoomen`,pt=((e={},t={})=>{let n=t.locale??k();return n===`en`?ut(e):n===`nl`?dt(e):ft(e)}),mt=()=>`Zoom out`,ht=()=>`Uitzoomen`,gt=()=>`Herauszoomen`,_t=((e={},t={})=>{let n=t.locale??k();return n===`en`?mt(e):n===`nl`?ht(e):gt(e)}),vt=()=>`Rotate left`,yt=()=>`Naar links draaien`,bt=()=>`Nach links drehen`,xt=((e={},t={})=>{let n=t.locale??k();return n===`en`?vt(e):n===`nl`?yt(e):bt(e)}),St=()=>`Rotate right`,Ct=()=>`Naar rechts draaien`,wt=()=>`Nach rechts drehen`,Tt=((e={},t={})=>{let n=t.locale??k();return n===`en`?St(e):n===`nl`?Ct(e):wt(e)}),Et=()=>`Tilt up`,Dt=()=>`Omhoog kantelen`,Ot=()=>`Nach oben kippen`,kt=((e={},t={})=>{let n=t.locale??k();return n===`en`?Et(e):n===`nl`?Dt(e):Ot(e)}),At=()=>`Tilt down`,jt=()=>`Omlaag kantelen`,Mt=()=>`Nach unten kippen`,Nt=((e={},t={})=>{let n=t.locale??k();return n===`en`?At(e):n===`nl`?jt(e):Mt(e)});function F(e){let t=Math.max(0,Math.min(1,e));return t*t*(3-2*t)}function Pt(e,t,n,r,i,a){let[o,s,c]=e,l=Math.cos(t),u=Math.sin(t),d=l*o+u*c,f=-u*o+l*c,p=Math.cos(n),m=Math.sin(n),h=p*s-m*f,g=m*s+p*f,_=.55;return[r+d*a*_,i-h*a*_,g]}function Ft(e,t,n){e.beginPath(),e.moveTo(t[0],t[1]),e.lineTo(n[0],n[1]),e.strokeStyle=`#000`,e.lineWidth=2,e.stroke()}function It(e,t,n,r,i){let a=t(n),o=t(r);Ft(e,a,[a[0]+(o[0]-a[0])*i,a[1]+(o[1]-a[1])*i,a[2]])}var I=[-1,-1,1],L=[1,-1,1],R=[1,-1,-1],z=[-1,-1,-1],B=[-1,1,1],V=[1,1,1],H=[1,1,-1],U=[-1,1,-1],Lt=[[I,L],[L,R],[R,z],[z,I],[I,B],[L,V],[R,H],[z,U],[B,V],[V,H],[H,U],[U,B]],Rt=400,zt=`-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif`;function Bt(){let e=document.createElement(`div`);Object.assign(e.style,{position:`absolute`,inset:`0`,display:`flex`,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,background:`#fff`,zIndex:`20`,opacity:`0`,transition:`opacity 0.3s ease-in-out`});let t=document.createElement(`canvas`);Object.assign(t.style,{width:`100%`,height:`100%`,position:`absolute`,inset:`0`});let n=document.createElement(`div`);Object.assign(n.style,{position:`absolute`,top:`56%`,left:`0`,right:`0`,textAlign:`center`,pointerEvents:`none`});let r=document.createElement(`span`);Object.assign(r.style,{fontSize:`13px`,fontWeight:`400`,color:`#000`,fontVariantNumeric:`tabular-nums`,fontFamily:zt});let i=document.createElement(`span`);return Object.assign(i.style,{fontSize:`13px`,color:`#000`,fontFamily:zt}),i.textContent=P(),n.appendChild(r),n.appendChild(i),e.appendChild(t),e.appendChild(n),{overlay:e,canvas:t,pctEl:r,phaseEl:i}}var Vt=class{overlay;canvas;ctx;pctEl;phaseEl;animationId=null;showTimerId=null;startTime;hidden=!1;visible=!1;constructor(e,t={}){this.startTime=performance.now();let n=Bt();this.overlay=n.overlay,this.canvas=n.canvas,this.pctEl=n.pctEl,this.phaseEl=n.phaseEl,e.appendChild(this.overlay),this.ctx=this.canvas.getContext(`2d`),this.ctx!==null&&(this.sizeCanvas(),this.tick());let r=t.showDelay??Rt;this.showTimerId=setTimeout(()=>{this.reveal()},r)}get loadingTexts(){return{downloading:P(),rendering:tt()}}updateProgress(e,t){this.hidden||(this.pctEl.textContent=`${Math.round(e)}%`,this.phaseEl.textContent=t===``?``:` \u00B7 ${t}`)}showError(e){if(this.hidden=!1,this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.ctx!==null){let e=Math.min(devicePixelRatio,2),t=this.canvas.width/e,n=this.canvas.height/e;this.ctx.fillStyle=`#fff`,this.ctx.fillRect(0,0,t*e,n*e)}this.pctEl.textContent=``,this.phaseEl.textContent=e,this.phaseEl.style.color=`#b91c1c`,this.reveal()}hide(){if(!this.hidden){if(this.hidden=!0,this.cancelShowTimer(),!this.visible){this.destroy();return}this.overlay.style.opacity=`0`,this.overlay.addEventListener(`transitionend`,()=>{this.destroy()},{once:!0}),setTimeout(()=>{this.destroy()},500)}}destroy(){this.cancelShowTimer(),this.animationId!==null&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.overlay.remove()}reveal(){this.hidden||this.visible||(this.visible=!0,this.overlay.style.opacity=`1`)}cancelShowTimer(){this.showTimerId!==null&&(clearTimeout(this.showTimerId),this.showTimerId=null)}sizeCanvas(){if(this.ctx===null)return;let e=Math.min(devicePixelRatio,2),t=this.overlay.clientWidth||440,n=this.overlay.clientHeight||360;this.canvas.width=t*e,this.canvas.height=n*e,this.ctx.scale(e,e),this.ctx.lineCap=`round`,this.ctx.lineJoin=`round`}tick=()=>{this.hidden||(this.drawFrame(),this.animationId=requestAnimationFrame(this.tick))};drawFrame(){if(this.ctx===null)return;let e=this.canvas.width/Math.min(devicePixelRatio,2),t=this.canvas.height/Math.min(devicePixelRatio,2),n=(performance.now()-this.startTime)/1e3;this.ctx.fillStyle=`#fff`,this.ctx.fillRect(0,0,e,t);let r=e/2,i=t*.44,a=Math.min(e,t)*.08,o=e=>Pt(e,.785,.615,r,i,a),s=n%6/6,c=Lt.length,l;l=s<.35?F(s/.35)*c:s<.55?c:s<.9?(1-F((s-.55)/.35))*c:0,this.ctx.shadowBlur=5,this.ctx.shadowColor=`rgba(30,30,30,0.08)`;for(let e=0;e<c&&!(e>=l);e++){let t=Lt[e];if(t===void 0)continue;let n=Math.min(1,l-e);It(this.ctx,o,t[0],t[1],n)}this.ctx.shadowBlur=0}},Ht={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":2,"stroke-linecap":`round`,"stroke-linejoin":`round`},Ut=([e,t,n])=>{let r=document.createElementNS(`http://www.w3.org/2000/svg`,e);return Object.keys(t).forEach(e=>{r.setAttribute(e,String(t[e]))}),n?.length&&n.forEach(e=>{let t=Ut(e);r.appendChild(t)}),r},Wt=(e,t={})=>Ut([`svg`,{...Ht,...t},e]),Gt=[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`}],[`path`,{d:`M12 22V12`}]],Kt=[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`}],[`circle`,{cx:`12`,cy:`13`,r:`3`}]],qt=[[`path`,{d:`m6 9 6 6 6-6`}]],Jt=[[`path`,{d:`m15 18-6-6 6-6`}]],Yt=[[`path`,{d:`m9 18 6-6-6-6`}]],Xt=[[`path`,{d:`m18 15-6-6-6 6`}]],Zt=[[`path`,{d:`M15 3h6v6`}],[`path`,{d:`m21 3-7 7`}],[`path`,{d:`m3 21 7-7`}],[`path`,{d:`M9 21H3v-6`}]],Qt=[[`path`,{d:`m14 10 7-7`}],[`path`,{d:`M20 10h-6V4`}],[`path`,{d:`m3 21 7-7`}],[`path`,{d:`M4 14h6v6`}]],$t=[[`path`,{d:`M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8`}],[`path`,{d:`M3 3v5h5`}]],en=[[`circle`,{cx:`11`,cy:`11`,r:`8`}],[`line`,{x1:`21`,x2:`16.65`,y1:`21`,y2:`16.65`}],[`line`,{x1:`11`,x2:`11`,y1:`8`,y2:`14`}],[`line`,{x1:`8`,x2:`14`,y1:`11`,y2:`11`}]],tn=[[`circle`,{cx:`11`,cy:`11`,r:`8`}],[`line`,{x1:`21`,x2:`16.65`,y1:`21`,y2:`16.65`}],[`line`,{x1:`8`,x2:`14`,y1:`11`,y2:`11`}]];function W(e,{size:t=20,strokeWidth:n=1.75}={}){return Wt(e,{width:t,height:t,"stroke-width":n})}var G={ar:e=>W(Gt,e),fullscreen:e=>W(Zt,e),exitFullscreen:e=>W(Qt,e),screenshot:e=>W(Kt,e),tiltUp:e=>W(Xt,e),tiltDown:e=>W(qt,e),rotateLeft:e=>W(Jt,e),rotateRight:e=>W(Yt,e),zoomIn:e=>W(en,e),zoomOut:e=>W(tn,e),reset:e=>W($t,e)},K=class{element;constructor({variant:e=`default`,size:t=`default`,label:n,icon:r,onClick:i,disabled:a=!1}={}){this.element=document.createElement(`button`),this.element.className=`ui-btn ui-btn--${e} ui-btn--size-${t}`,n!==void 0&&(this.element.setAttribute(`aria-label`,n),this.element.title=n),r===void 0?n!==void 0&&(this.element.textContent=n):this.element.appendChild(r),i&&this.element.addEventListener(`click`,i),this.element.disabled=a}setIcon(e){let t=this.element.querySelector(`svg`);t===null?this.element.appendChild(e):t.replaceWith(e)}},q={brand:{DEFAULT:`#171717`,primary:`#171717`,hover:`#262626`,light:`#f5f5f5`,50:`#fafafa`,100:`#f5f5f5`,200:`#e5e5e5`,300:`#d4d4d4`,400:`#a3a3a3`,500:`#737373`,600:`#525252`,700:`#404040`,800:`#262626`,900:`#171717`,950:`#0a0a0a`},semantic:{success:`#16a34a`,warning:`#ca8a04`,error:`#dc2626`,info:`#0891b2`},neutral:{50:`#fafafa`,100:`#f5f5f5`,200:`#e5e5e5`,300:`#d4d4d4`,400:`#a3a3a3`,500:`#737373`,600:`#525252`,700:`#404040`,800:`#262626`,900:`#171717`,950:`#0a0a0a`},white:`#ffffff`,black:`#000000`},J={px:`1px`,0:`0`,.5:`0.125rem`,1:`0.25rem`,1.5:`0.375rem`,2:`0.5rem`,2.5:`0.625rem`,3:`0.75rem`,3.5:`0.875rem`,4:`1rem`,5:`1.25rem`,6:`1.5rem`,7:`1.75rem`,8:`2rem`,9:`2.25rem`,10:`2.5rem`,12:`3rem`,14:`3.5rem`,16:`4rem`,20:`5rem`,24:`6rem`};J[1],J[2],J[4],J[6],J[8],J[12];var nn=class{element;constructor(){this.element=document.createElement(`div`),Object.assign(this.element.style,{background:q.white,borderRadius:J[3],padding:J[6],boxShadow:`0 ${J[2]} ${J[8]} oklch(0% 0 0 / 20%)`,maxWidth:`20rem`,width:`100%`})}},rn=class{card;backdrop;keyHandler=null;constructor(e={}){this.options=e,this.card=new nn,this.backdrop=this.createBackdrop(),this.backdrop.appendChild(this.card.element)}open(){document.body.appendChild(this.backdrop),this.keyHandler=e=>{e.key===`Escape`&&this.close()},document.addEventListener(`keydown`,this.keyHandler)}close(){this.backdrop.remove(),this.keyHandler!==null&&(document.removeEventListener(`keydown`,this.keyHandler),this.keyHandler=null),this.options.onClose?.()}createBackdrop(){let e=document.createElement(`div`);return Object.assign(e.style,{position:`fixed`,inset:J[0],background:`oklch(0% 0 0 / 50%)`,zIndex:`9999`,display:`flex`,alignItems:`center`,justifyContent:`center`}),e.addEventListener(`click`,t=>{t.target===e&&this.close()}),e}},an=class{element;selectCallback=null;constructor(e,t,n){this.element=document.createElement(`div`),this.element.className=`ui-toggle-group`;for(let r=0;r<e.length;r++){let i=e[r],a=document.createElement(`button`);a.className=`ui-toggle-group-item`,a.dataset.value=i,a.textContent=n?.[r]??i,a.dataset.state=i===t?`on`:`off`,a.addEventListener(`click`,()=>{this.selectCallback?.(i)}),this.element.appendChild(a)}}setSelected(e){for(let t of this.element.querySelectorAll(`.ui-toggle-group-item`))t.dataset.state=t.dataset.value===e?`on`:`off`}onSelect(e){this.selectCallback=e}},on=class{element;select;constructor(e,t,n,r,i){this.select=document.createElement(`select`),this.select.className=`ui-native-select`,this.select.dataset.name=e;let a=document.createElement(`option`);a.value=``,a.disabled=!0,a.textContent=n,this.select.appendChild(a);let o=!1;for(let e=0;e<t.length;e++){let n=t[e],a=document.createElement(`option`);a.value=n,a.textContent=i?.[e]??n,n===r&&(a.selected=!0,o=!0),this.select.appendChild(a)}o||(a.selected=!0);let s=Wt(qt,{width:16,height:16,"stroke-width":2});s.classList.add(`ui-native-select-icon`),this.element=document.createElement(`div`),this.element.className=`ui-native-select-wrap`,this.element.appendChild(this.select),this.element.appendChild(s)}setSelected(e){this.select.value=e}onSelect(e){this.select.addEventListener(`change`,()=>{e(this.select.value)})}},Y={fontFamily:{sans:[`Mona Sans`,`ui-sans-serif`,`system-ui`,`sans-serif`,`Apple Color Emoji`,`Segoe UI Emoji`,`Segoe UI Symbol`,`Noto Color Emoji`],mono:[`JetBrains Mono`,`ui-monospace`,`monospace`]},fontSize:{xs:`0.75rem`,sm:`0.875rem`,base:`1rem`,lg:`1.125rem`,xl:`1.25rem`,"2xl":`1.5rem`,"3xl":`1.875rem`,"4xl":`2.25rem`},fontWeight:{normal:`400`,medium:`500`,semibold:`600`,bold:`700`},lineHeight:{tight:`1.25`,normal:`1.5`,relaxed:`1.75`}},sn=Y.fontFamily.sans.join(`, `),cn=class{qrLib=null;dialog=null;async show(t){this.hide(),this.qrLib??=await Promise.resolve().then(()=>e.n(require(`./browser-DiwLZG-y.cjs`).default,1));let n=await this.qrLib.toDataURL(t,{width:256,margin:4,errorCorrectionLevel:`M`,color:{dark:q.black,light:q.white}});this.dialog=new rn({onClose:()=>{this.dialog=null}}),Object.assign(this.dialog.card.element.style,{display:`flex`,flexDirection:`column`,alignItems:`center`,gap:J[3],fontFamily:sn}),this.dialog.card.element.appendChild(this.createText(Me(),{fontSize:Y.fontSize.base,fontWeight:Y.fontWeight.semibold,color:q.neutral[900]})),this.dialog.card.element.appendChild(this.createText(Ie(),{fontSize:Y.fontSize.sm,color:q.neutral[600]})),this.dialog.card.element.appendChild(this.createQrImage(n)),this.dialog.card.element.appendChild(this.createText(Be(),{fontSize:Y.fontSize.xs,color:q.neutral[500]}));let r=new K({variant:`outline`,label:We(),onClick:()=>{this.hide()}});this.dialog.card.element.appendChild(r.element),this.dialog.open()}hide(){this.dialog?.close(),this.dialog=null}createText(e,t){let n=document.createElement(`p`);return n.textContent=e,Object.assign(n.style,{margin:`0`,textAlign:`center`,...t}),n}createQrImage(e){let t=document.createElement(`img`);return t.src=e,t.alt=`QR code`,Object.assign(t.style,{width:J[24],height:J[24],borderRadius:J[1]}),t}},X=Y.fontFamily.sans.join(`, `),ln=`
2
+ :root {
3
+ --primary: oklch(5% 0 0);
4
+ --primary-foreground: oklch(100% 0 0);
5
+ --secondary: oklch(92% 0 0);
6
+ --secondary-foreground: oklch(5% 0 0);
7
+ --background: oklch(100% 0 0);
8
+ --foreground: oklch(5% 0 0);
9
+ --border: oklch(92% 0 0);
10
+ --ring: oklch(44% 0 0);
11
+ --radius: 0.625rem;
12
+ --accent: oklch(92% 0 0);
13
+ --accent-foreground: oklch(5% 0 0);
14
+ --muted-foreground: oklch(44% 0 0);
15
+ }
16
+
17
+ /* ── Button ──────────────────────────────────────────────── */
18
+ .ui-btn {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ gap: 0.5rem;
23
+ border: 1px solid transparent;
24
+ border-radius: var(--radius);
25
+ font-family: ${X};
26
+ font-size: 0.875rem;
27
+ font-weight: 600;
28
+ white-space: nowrap;
29
+ cursor: pointer;
30
+ transition: all 200ms;
31
+ flex-shrink: 0;
32
+ }
33
+ .ui-btn:active { transform: scale(0.98); }
34
+ .ui-btn:disabled { opacity: 0.5; pointer-events: none; }
35
+ .ui-btn svg { inline-size: 1rem; block-size: 1rem; pointer-events: none; flex-shrink: 0; }
36
+
37
+ .ui-btn--default {
38
+ background: var(--primary);
39
+ color: var(--primary-foreground);
40
+ box-shadow: 0 1px 3px oklch(5% 0 0 / 20%);
41
+ }
42
+ .ui-btn--default:hover { background: oklch(10% 0 0); }
43
+
44
+ .ui-btn--outline {
45
+ background: var(--background);
46
+ color: var(--foreground);
47
+ border-color: var(--border);
48
+ box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
49
+ }
50
+ .ui-btn--outline:hover { background: var(--accent); border-color: oklch(85% 0 0); }
51
+
52
+ .ui-btn--secondary {
53
+ background: var(--secondary);
54
+ color: var(--secondary-foreground);
55
+ box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
56
+ }
57
+ .ui-btn--secondary:hover { background: oklch(88% 0 0); }
58
+
59
+ .ui-btn--ghost { background: transparent; color: var(--foreground); }
60
+ .ui-btn--ghost:hover { background: var(--accent); }
61
+
62
+ .ui-btn--size-default { block-size: 2.25rem; padding: 0 1rem; }
63
+ .ui-btn--size-sm { block-size: 2rem; padding: 0 0.75rem; border-radius: calc(var(--radius) - 0.125rem); }
64
+ .ui-btn--size-lg { block-size: 2.5rem; padding: 0 1.5rem; }
65
+ .ui-btn--size-icon { inline-size: 2.25rem; block-size: 2.25rem; padding: 0; }
66
+ .ui-btn--size-icon-sm { inline-size: 2rem; block-size: 2rem; padding: 0; }
67
+ .ui-btn--size-icon-lg { inline-size: 2.5rem; block-size: 2.5rem; padding: 0; }
68
+
69
+ /* ── Toggle group ────────────────────────────────────────── */
70
+ .ui-toggle-group { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; }
71
+
72
+ .ui-toggle-group-item {
73
+ display: inline-flex;
74
+ align-items: center;
75
+ justify-content: center;
76
+ block-size: 2rem;
77
+ padding: 0 0.75rem;
78
+ border: 1px solid var(--border);
79
+ border-radius: var(--radius);
80
+ background: var(--background);
81
+ color: var(--foreground);
82
+ font-family: ${X};
83
+ font-size: 0.875rem;
84
+ font-weight: 600;
85
+ cursor: pointer;
86
+ white-space: nowrap;
87
+ transition: all 200ms;
88
+ box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
89
+ }
90
+ .ui-toggle-group-item:hover { background: var(--accent); border-color: oklch(85% 0 0); }
91
+ .ui-toggle-group-item:active { transform: scale(0.98); }
92
+ .ui-toggle-group-item[data-state="on"] {
93
+ background: var(--primary);
94
+ color: var(--primary-foreground);
95
+ border-color: var(--primary);
96
+ }
97
+ .ui-toggle-group-item[data-state="on"]:hover { background: oklch(10% 0 0); }
98
+
99
+ /* ── Native select ───────────────────────────────────────── */
100
+ .ui-native-select-wrap {
101
+ position: relative;
102
+ display: inline-flex;
103
+ min-inline-size: 8rem;
104
+ }
105
+
106
+ .ui-native-select {
107
+ display: block;
108
+ inline-size: 100%;
109
+ block-size: 2.25rem;
110
+ padding: 0 2.25rem 0 0.75rem;
111
+ border: 1px solid var(--border);
112
+ border-radius: var(--radius);
113
+ background: var(--background);
114
+ appearance: none;
115
+ color: var(--foreground);
116
+ font-family: ${X};
117
+ font-size: 0.875rem;
118
+ font-weight: 400;
119
+ cursor: pointer;
120
+ transition: color 200ms, box-shadow 200ms, border-color 200ms;
121
+ box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
122
+ }
123
+ .ui-native-select:hover { border-color: oklch(85% 0 0); }
124
+ .ui-native-select:focus-visible {
125
+ outline: none;
126
+ border-color: var(--ring);
127
+ box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
128
+ }
129
+
130
+ .ui-native-select-icon {
131
+ position: absolute;
132
+ inset-block-start: 50%;
133
+ inset-inline-end: 0.625rem;
134
+ transform: translateY(-50%);
135
+ color: var(--muted-foreground);
136
+ pointer-events: none;
137
+ }
138
+ `,Z=!1;function un(){if(Z||typeof document>`u`)return;Z=!0;let e=document.createElement(`style`);e.id=`vd-ui-vanilla`,e.textContent=ln,document.head.appendChild(e)}function dn(e,t){let n=document.createElement(`a`);n.href=`data:image/png;base64,${e}`,n.download=t,n.click()}var fn=class{element;screenshotBtn=null;constructor(e){this.options=e,this.element=document.createElement(`div`),this.element.className=`vd-toolbar`}syncButton(e,t,n){if(t&&e===null){let e=n();return this.element.appendChild(e.element),e}return!t&&e!==null?(e.element.remove(),null):e}applySettings(e){this.screenshotBtn=this.syncButton(this.screenshotBtn,e.screenshot===!0,()=>new K({variant:`outline`,size:`icon`,label:at(),icon:G.screenshot(),onClick:()=>{this.options.snapshotApi.take(`snapshot.png`).onDeveloped(({data:e,filename:t})=>{dn(e,t)})}}))}},pn=class{element;arBtn=null;fullscreenBtn=null;onFullscreenChange;constructor(e){this.options=e,this.element=document.createElement(`div`),this.element.className=`vd-action-bar`,this.onFullscreenChange=()=>{if(this.fullscreenBtn===null)return;let e=document.fullscreenElement!==null;this.fullscreenBtn.setIcon(e?G.exitFullscreen():G.fullscreen())},document.addEventListener(`fullscreenchange`,this.onFullscreenChange)}syncButton(e,t,n){if(t&&e===null){let e=n();return this.element.appendChild(e.element),e}return!t&&e!==null?(e.element.remove(),null):e}applySettings(e){this.arBtn=this.syncButton(this.arBtn,e.ar!==!1&&this.options.onAr!==void 0,()=>new K({variant:`outline`,size:`icon`,label:Oe(),icon:G.ar(),onClick:()=>{this.options.onAr?.()}})),this.fullscreenBtn=this.syncButton(this.fullscreenBtn,e.fullscreen!==!1&&this.options.onFullscreen!==void 0,()=>new K({variant:`outline`,size:`icon`,label:Je(),icon:G.fullscreen(),onClick:()=>{this.options.onFullscreen?.()}}))}destroy(){document.removeEventListener(`fullscreenchange`,this.onFullscreenChange)}},Q=.5,mn=class e{element;constructor(t,n){this.element=Object.assign(document.createElement(`div`),{className:`vd-camera-controls`});let r=n.rotation,i=n.tilt,a=n.zoom,o=0,s=e=>Math.max(n.limits?.minZoom??1,Math.min(n.limits?.maxZoom??1/0,e)),c=e=>{let t=n.limits?.minRotate,r=n.limits?.maxRotate;return t!==void 0||r!==void 0?Math.max(t??-1/0,Math.min(r??1/0,e)):e},l=e=>{let a=n.limits?.minTilt,s=n.limits?.maxTilt;if(a!==void 0||s!==void 0){i=Math.max(a??0,Math.min(s??180,i+e)),t.tilt(i).set();return}let c=i+e;c>180||c<0?(i=c>180?360-c:-c,o=(o+180)%360,t.tilt(i).rotate(r+o).set()):(i=c,t.tilt(i).set())},u=new K({variant:`outline`,size:`icon`,label:_t(),icon:G.zoomOut(),onClick:()=>{a=s(a-10),t.zoom(a).set()}}),d=new K({variant:`outline`,size:`icon`,label:pt(),icon:G.zoomIn(),onClick:()=>{a=s(a+10),t.zoom(a).set()}}),f=new K({variant:`outline`,size:`icon`,label:kt(),icon:G.tiltUp(),onClick:()=>{l(-15)}}),p=new K({variant:`outline`,size:`icon`,label:xt(),icon:G.rotateLeft(),onClick:()=>{r=c(r-15),t.rotate(r+o).set()}}),m=new K({variant:`outline`,size:`icon`,label:lt(),icon:G.reset(),onClick:()=>{o=0,t.reset()}}),h=new K({variant:`outline`,size:`icon`,label:Tt(),icon:G.rotateRight(),onClick:()=>{r=c(r+15),t.rotate(r+o).set()}}),g=new K({variant:`outline`,size:`icon`,label:Nt(),icon:G.tiltDown(),onClick:()=>{l(15)}}),_=e=>{let t=n.limits;t!==void 0&&(u.element.disabled=t.minZoom!==void 0&&e.zoom<=t.minZoom+Q,d.element.disabled=t.maxZoom!==void 0&&e.zoom>=t.maxZoom-Q,f.element.disabled=t.minTilt!==void 0&&e.tilt<=t.minTilt+Q,g.element.disabled=t.maxTilt!==void 0&&e.tilt>=t.maxTilt-Q,p.element.disabled=t.minRotate!==void 0&&e.rotation<=t.minRotate+Q,h.element.disabled=t.maxRotate!==void 0&&e.rotation>=t.maxRotate-Q)};n.onChange(e=>{r=e.rotation-o,i=e.tilt,a=e.zoom,_(e)}),this.element.appendChild(e.buildZoom(u,d)),this.element.appendChild(e.buildDpad(f,p,m,h,g))}static buildZoom(e,t){let n=document.createElement(`div`);return n.className=`vd-zoom`,n.appendChild(e.element),n.appendChild(t.element),n}static buildDpad(e,t,n,r,i){let a=document.createElement(`div`);a.className=`vd-dpad`;for(let[o,s]of[[e,`up`],[t,`left`],[n,`center`],[r,`right`],[i,`down`]])o.element.classList.add(`vd-dpad-${s}`),a.appendChild(o.element);return a}},hn=5;function $(e){let t=e.replace(/([A-Z])/g,` $1`).trim();return t.charAt(0).toUpperCase()+t.slice(1).toLowerCase()}function gn(e,t,n,r,i){let a=document.createElement(`div`);a.className=`vd-attribute`,a.dataset.name=e.name;let o=document.createElement(`span`);o.className=`vd-attribute-label`,o.textContent=$(e.name),a.appendChild(o);let s=e.values.find(n=>t.getValue(e.name,n)?.isSelected===!0),c=e.values.map($),l=e.values.length<=hn?new an(e.values,s,c):new on(e.name,e.values,$(e.name),s,c);return l.onSelect(t=>{n.dispatch(`ui:select`,{attribute:e.name,value:t},!0).defaultPrevented||r(e.name,t)}),i(e.name,t=>{l.setSelected(t.value),n.dispatch(`ui:selected`,{attribute:e.name,value:t.value})}),a.appendChild(l.element),a}var _n=Y.fontFamily.sans.join(`, `),vn=`
139
+ /* Override browser's default black fullscreen backdrop */
140
+ .vd-container:fullscreen {
141
+ background: oklch(100% 0 0);
142
+ }
143
+
144
+ /* Top-right: screenshot + camera controls */
145
+ .vd-toolbar {
146
+ position: absolute;
147
+ inset-block-start: ${J[3]};
148
+ inset-inline-end: ${J[3]};
149
+ display: flex;
150
+ flex-direction: column;
151
+ align-items: flex-end;
152
+ gap: ${J[1.5]};
153
+ z-index: 10;
154
+ }
155
+
156
+ /* Bottom-right: AR + fullscreen */
157
+ .vd-action-bar {
158
+ position: absolute;
159
+ inset-block-end: ${J[3]};
160
+ inset-inline-end: ${J[3]};
161
+ display: flex;
162
+ flex-direction: row;
163
+ gap: ${J[1.5]};
164
+ z-index: 10;
165
+ }
166
+
167
+ /* Camera controls card inside .vd-toolbar */
168
+ .vd-camera-controls {
169
+ display: flex;
170
+ flex-direction: column;
171
+ gap: ${J[1]};
172
+ background: color-mix(in oklch, ${q.white} 85%, transparent);
173
+ backdrop-filter: blur(8px);
174
+ border-radius: ${J[2]};
175
+ padding: ${J[2]};
176
+ }
177
+
178
+ .vd-zoom {
179
+ display: flex;
180
+ gap: ${J[.5]};
181
+ }
182
+
183
+ .vd-dpad {
184
+ display: grid;
185
+ grid-template-columns: repeat(3, ${J[9]});
186
+ grid-template-rows: repeat(3, ${J[9]});
187
+ gap: ${J[.5]};
188
+ }
189
+
190
+ .vd-dpad-up { grid-column: 2; grid-row: 1; }
191
+ .vd-dpad-left { grid-column: 1; grid-row: 2; }
192
+ .vd-dpad-center { grid-column: 2; grid-row: 2; }
193
+ .vd-dpad-right { grid-column: 3; grid-row: 2; }
194
+ .vd-dpad-down { grid-column: 2; grid-row: 3; }
195
+
196
+ /* Bottom-left: attribute selectors */
197
+ .vd-attributes {
198
+ position: absolute;
199
+ inset-block-end: ${J[3]};
200
+ inset-inline-start: ${J[3]};
201
+ display: flex;
202
+ flex-direction: column;
203
+ gap: ${J[2]};
204
+ background: color-mix(in oklch, ${q.white} 85%, transparent);
205
+ backdrop-filter: blur(8px);
206
+ border-radius: ${J[2]};
207
+ padding: ${J[2]};
208
+ font-family: ${_n};
209
+ z-index: 10;
210
+ }
211
+
212
+ .vd-attribute {
213
+ display: flex;
214
+ flex-direction: column;
215
+ gap: ${J[1]};
216
+ }
217
+
218
+ .vd-attribute-label {
219
+ font-size: ${Y.fontSize.xs};
220
+ font-weight: ${Y.fontWeight.medium};
221
+ color: ${q.neutral[900]};
222
+ font-family: ${_n};
223
+ }
224
+
225
+ `;function yn(){if(un(),document.getElementById(`vd-styles`)!==null)return;let e=document.createElement(`style`);e.id=`vd-styles`,e.textContent=vn,document.head.appendChild(e)}var bn=class{options;settings={};container=null;loading=null;toolbar=null;actionBar=null;cameraControls=null;attributes=null;constructor(e){this.options=e}attach(e){yn(),this.container=e,this.loading=new Vt(e),this.toolbar=new fn({snapshotApi:this.options.snapshotApi}),this.toolbar.applySettings(this.settings),e.appendChild(this.toolbar.element),this.actionBar=new pn({onAr:this.options.onAr,onFullscreen:()=>{document.fullscreenElement===null?this.container?.requestFullscreen():document.exitFullscreen()}}),this.actionBar.applySettings(this.settings),e.appendChild(this.actionBar.element)}onReady(){this.loading?.hide(),this.loading=null,this.cameraControls!==null&&(this.cameraControls.element.style.display=`flex`),this.attributes!==null&&(this.attributes.style.display=`flex`)}updateProgress(e,t){this.loading?.updateProgress(e,t)}showError(e){this.loading?.showError(e)}applyViewerSettings(e){this.settings=e,e.language!==void 0&&A(e.language),this.toolbar?.applySettings(e),this.actionBar?.applySettings(e),this.cameraControls!==null&&(this.cameraControls.element.style.display=e.cameraControls===!0?`flex`:`none`)}renderAttributeControls(e,t){if(!(this.container===null||this.toolbar===null)&&(this.cameraControls?.element.remove(),this.cameraControls=null,this.attributes?.remove(),this.attributes=null,this.settings.cameraControls===!0&&(this.cameraControls=new mn(this.options.cameraApi,this.options.cameraPositionApi),this.cameraControls.element.style.display=`none`,this.toolbar.element.appendChild(this.cameraControls.element)),t.length!==0)){this.attributes=document.createElement(`div`),this.attributes.className=`vd-attributes`,this.attributes.style.display=`none`;for(let n of t)this.attributes.appendChild(gn(n,e,this.options.eventBus,this.options.onSelect,this.options.onSubscribe));this.container.appendChild(this.attributes)}}get viewerSettings(){return this.settings}destroy(){this.loading?.destroy(),this.toolbar?.element.remove(),this.actionBar?.destroy(),this.actionBar?.element.remove(),this.cameraControls?.element.remove(),this.attributes?.remove(),this.container=null}},xn=class{attributes;readyStateTracker;messenger;cameraApi;cameraPositionApi;snapshotApi;eventBus;ui;qrModal;options;iframe;container;readyCallbacks=[];mutationFailedCallbacks=[];constructor(e){this.options=e,this.initializeLogging(),this.messenger=new fe(()=>this.iframe?.contentWindow??null);let t=e=>{this.messenger.send(e)};this.attributes=new pe(t,(e,t)=>{for(let n of this.mutationFailedCallbacks)n({attribute:e,value:t})}),this.snapshotApi=new _e(t),this.cameraApi=new me(t),this.cameraPositionApi=new he,this.eventBus=new ve,this.qrModal=new cn,this.readyStateTracker=new _(()=>{let e=this.readyCallbacks;this.readyCallbacks=[];for(let t of e)t(this);this.ui.onReady()}),this.ui=new bn({snapshotApi:this.snapshotApi,cameraApi:this.cameraApi,cameraPositionApi:this.cameraPositionApi,eventBus:this.eventBus,onSelect:(e,t)=>this.attributes.select(e,t),onSubscribe:(e,t)=>this.attributes.onChange(e,t),onAr:()=>{this.qrModal.show(this.iframe?.src??``)}}),this.registerHandlers(),this.messenger.start(),this.createAndConnectIframe()}registerHandlers(){this.messenger.on(y.HANDSHAKE,e=>{ie(e)&&(m.info(`Server handshake received, flushing publisher queue`),this.messenger.markReady())}),this.messenger.on(y.MUTATION,e=>{ae(e)&&this.attributes.handleMutationResult(e)}),this.messenger.on(y.SNAPSHOT,e=>{oe(e)&&this.snapshotApi.handleSnapshotResult(e)}),this.messenger.on(y.CAMERA,e=>{se(e)&&this.cameraPositionApi.handlePositionUpdate(e)}),this.messenger.on(y.LOADING_INDICATOR,e=>{le(e)&&(e.error===void 0?this.ui.updateProgress(e.progress,e.phase):this.ui.showError(e.error))}),this.messenger.on(y.CONFIG,e=>{ue(e)&&(e.viewerSettings!==void 0&&this.ui.applyViewerSettings(e.viewerSettings),this.cameraPositionApi.applyLimits(e.cameraLimits))}),this.messenger.on(y.MAPPING,e=>{ce(e)&&(this.attributes.handleMappingReceived(e),this.ui.renderAttributeControls(this.attributes,e.attributes),this.readyStateTracker.handleMappingReceived())})}initializeLogging(){this.options.debug===!0&&h(),m.info(`Initializing Virtualdisplay client`,{model:this.options.model})}createAndConnectIframe(){let e=new r(this.options).create();this.container=e.container,this.iframe=e.iframe,this.eventBus.attach(this.container),this.ui.attach(this.container)}select(e,t){this.attributes.select(e,t)}getValues(e){return this.attributes.getValues(e)}getValue(e,t){return this.attributes.getValue(e,t)}onChange(e,t){this.attributes.onChange(e,t)}getAttribute(e){return this.attributes.getAttribute(e)}get isReady(){return this.readyStateTracker.isReady}onReady(e){if(this.readyStateTracker.isReady){e(this);return}this.readyCallbacks.push(e)}onMutationFailed(e){this.mutationFailedCallbacks.push(e)}on(e,t){this.eventBus.on(e,t)}get camera(){return this.cameraApi}get cameraPosition(){return this.cameraPositionApi}get snapshot(){return this.snapshotApi}get viewerSettings(){return this.ui.viewerSettings}destroy(){this.readyStateTracker.clear(),this.readyCallbacks=[],this.messenger.destroy(),this.qrModal.hide(),this.ui.destroy(),this.container?.parentElement!==null&&this.container?.parentElement!==void 0&&this.container.parentElement.removeChild(this.container),this.container=void 0,this.iframe=void 0}};exports.Attribute=ee,exports.AttributeValue=v,exports.Camera=me,exports.ERROR_CODES=t,exports.Photo=ge,exports.Snapshot=_e,exports.VirtualdisplayClient=xn,exports.VirtualdisplayError=n,exports.enableDebugMode=h,exports.isDebugMode=g,Object.defineProperty(exports,`logger`,{enumerable:!0,get:function(){return m}});