@titan-os/sdk 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # @titan-os/sdk
2
+
3
+ Titan SDK for TV platforms - Device info, accessibility, and app management.
4
+
5
+ 📖 **[Official Documentation](https://docs.titanos.tv/titan-sdk)** | 🚀 **[Getting Started Guide](https://docs.titanos.tv/titan-sdk/getting-started)**
6
+
7
+ > **Note**: This is the NPM package for integrating Titan SDK into your applications. For comprehensive guides, examples, and API reference, visit the [official documentation](https://docs.titanos.tv/titan-sdk).
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install @titan-os/sdk
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### ES Modules (Recommended)
18
+
19
+ ```javascript
20
+ import { getTitanSDK } from '@titan-os/sdk';
21
+
22
+ const sdk = getTitanSDK();
23
+
24
+ // Wait for SDK to initialize
25
+ await sdk.isReady;
26
+
27
+ // Get device information
28
+ const deviceInfo = await sdk.deviceInfo.getDeviceInfo();
29
+ console.log('Device:', deviceInfo);
30
+ ```
31
+
32
+ ### CommonJS
33
+
34
+ ```javascript
35
+ const { getTitanSDK } = require('@titan-os/sdk');
36
+
37
+ const sdk = getTitanSDK();
38
+
39
+ // Wait for SDK to initialize
40
+ await sdk.isReady;
41
+
42
+ // Get device information
43
+ const deviceInfo = await sdk.deviceInfo.getDeviceInfo();
44
+ console.log('Device:', deviceInfo);
45
+ ```
46
+
47
+ ### UMD (Browser)
48
+
49
+ ```html
50
+ <script src="https://sdk.titanos.tv/sdk/sdk.js"></script>
51
+ <script>
52
+ const sdk = TitanSDK.getTitanSDK();
53
+
54
+ sdk.isReady.then(async () => {
55
+ const deviceInfo = await sdk.deviceInfo.getDeviceInfo();
56
+ console.log('Device:', deviceInfo);
57
+ });
58
+ </script>
59
+ ```
60
+
61
+ > **Note**: For CDN usage, see the [official documentation](https://docs.titanos.tv/titan-sdk).
62
+
63
+ ## Features
64
+
65
+ - **Device Information**: Get detailed device capabilities and information
66
+ - **Accessibility**: Screen reader and accessibility features
67
+ - **App Management**: Launch and manage TV applications
68
+ - **Platform Support**: Philips, Vestel, and browser platforms
69
+ - **TypeScript**: Full TypeScript support with type definitions
70
+
71
+ ## API Reference
72
+
73
+ ### getTitanSDK(options?)
74
+
75
+ Creates a new SDK instance.
76
+
77
+ **Options:**
78
+
79
+ - `gatewayUrl` (string): Custom gateway URL for API calls (optional)
80
+
81
+ **Returns:** `TitanSDK` instance
82
+
83
+ ### SDK Instance
84
+
85
+ #### Properties
86
+
87
+ - `isReady` (Promise<boolean>): Promise that resolves when SDK is ready
88
+ - `VERSION` (string): SDK version
89
+
90
+ #### Methods
91
+
92
+ - `deviceInfo.getDeviceInfo()`: Get device information
93
+ - `accessibility.*`: Accessibility features
94
+ - `apps.*`: App management features
95
+
96
+ ## Platform Support
97
+
98
+ - **Philips TV**: Full support for Philips Smart TV platform
99
+ - **Vestel TV**: Support for Vestel TV platform
100
+ - **Browser**: Fallback for web browsers and unsupported platforms
101
+
102
+ ## TypeScript
103
+
104
+ This package includes full TypeScript definitions:
105
+
106
+ ```typescript
107
+ import { getTitanSDK, DeviceInfo } from '@titan-os/sdk';
108
+
109
+ const sdk = getTitanSDK();
110
+ const deviceInfo: DeviceInfo = await sdk.deviceInfo.getDeviceInfo();
111
+ ```
112
+
113
+ ## Migration from CDN
114
+
115
+ If you're migrating from the CDN version to NPM:
116
+
117
+ ```javascript
118
+ // CDN way (for direct HTML integration)
119
+ <script src="https://sdk.titanos.tv/sdk/sdk.js"></script>
120
+ <script>
121
+ const sdk = TitanSDK.getTitanSDK();
122
+ </script>
123
+
124
+ // NPM way (for bundling in your app)
125
+ import { getTitanSDK } from '@titan-os/sdk';
126
+ const sdk = getTitanSDK();
127
+ ```
128
+
129
+ > **Note**: CDN version is still available and recommended for direct HTML integration. Use NPM package when you need to bundle the SDK with your application.
130
+
131
+ ## License
132
+
133
+ Apache-2.0
@@ -0,0 +1 @@
1
+ "use strict";var e=Object.defineProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("rollbar");var i=(e=>(e.PHILIPS="PHILIPS",e.PHILIPS_OLD="PHILIPS_OLD",e.VESTEL="VESTEL",e.BROWSER="BROWSER",e.UNKNOWN="UNKNOWN",e))(i||{}),n=(e=>(e.NOT_INITIALIZED="NOT_INITIALIZED",e.NOT_SUPPORTED="NOT_SUPPORTED",e.NOT_IMPLEMENTED="NOT_IMPLEMENTED",e.INVALID_ARGUMENTS="INVALID_ARGUMENTS",e.INVALID_PARAMETER="INVALID_PARAMETER",e.PLATFORM_NOT_DETECTED="PLATFORM_NOT_DETECTED",e.COMMUNICATION_ERROR="COMMUNICATION_ERROR",e.TIMEOUT="TIMEOUT",e.UNKNOWN="UNKNOWN",e))(n||{});class r extends Error{code;details;constructor(e,t="UNKNOWN",i){super(e),this.name="SDKError",this.code=t,this.details=i,Error.captureStackTrace&&Error.captureStackTrace(this,r)}toString(){return`SDKError [${this.code}]: ${this.message}`}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}}const s=new class{subscriptions=new Map;logBuffer=[];maxBufferSize=1e3;nextId=1;debugMode=!1;constructor(e=1e3){this.maxBufferSize=e}setDebugMode(e){this.debugMode=e}subscribe(e,t={}){const i="sub-"+this.nextId++,n={id:i,levels:t.levels||["debug","info","warn","error"],modules:t.modules,callback:e,created:Date.now()};if(this.subscriptions.set(i,n),t.includeHistory){this.getFilteredHistory(n.levels,n.modules).forEach((t=>{try{e(t)}catch(i){}}))}return i}unsubscribe(e){return this.subscriptions.delete(e)}addLogEntry(e){this.logBuffer.push(e),this.logBuffer.length>this.maxBufferSize&&this.logBuffer.shift(),this.subscriptions.forEach((t=>{if(this.shouldNotifySubscription(t,e))try{t.callback(e)}catch(i){}}))}getHistory(e,t,i){return this.getFilteredHistory(e,t,i)}clear(){this.logBuffer=[]}getSubscriptionCount(){return this.subscriptions.size}getMetrics(){const e={totalEntries:this.logBuffer.length,entriesByLevel:{},entriesByModule:{},memoryUsageKB:Math.round(JSON.stringify(this.logBuffer).length/1024)};return this.logBuffer.length>0&&(e.oldestEntry=new Date(this.logBuffer[0].timestamp),e.newestEntry=new Date(this.logBuffer[this.logBuffer.length-1].timestamp)),this.logBuffer.forEach((t=>{e.entriesByLevel[t.level]=(e.entriesByLevel[t.level]||0)+1,e.entriesByModule[t.module]=(e.entriesByModule[t.module]||0)+1})),e}exportLogs(e,t){const i=this.getFilteredHistory(e,t);return JSON.stringify(i,null,2)}isDebugMode(){return this.debugMode}shouldNotifySubscription(e,t){return!!e.levels.includes(t.level)&&!(e.modules&&!e.modules.includes(t.module))}getFilteredHistory(e,t,i){let n=this.logBuffer;return e&&(n=n.filter((t=>e.includes(t.level)))),t&&(n=n.filter((e=>t.includes(e.module)))),i&&i>0&&(n=n.slice(-i)),[...n]}};function o(e){const t=(t,i,...n)=>{var r;const o=(()=>{try{const e=(new Error).stack;if(!e)return"";const t=e.split("\n");for(let i=3;i<t.length;i++){const e=t[i];if(e&&!e.includes("logger.ts")&&!e.includes("Logger")){const t=e.match(/\((.*):(\d+):(\d+)\)/)||e.match(/at (.*):(\d+):(\d+)/);if(t){const[,e,i]=t;return`${e.split("/").pop()||e}:${i}`}}}return""}catch{return""}})(),a=(e=>{var t;try{const i=null==(t=e.stack)?void 0:t.split("\n");if(!i||i.length<4)return"Unknown location";const n=i[3].replace("at","").trim()||"Unknown location",{fnName:r,fnPath:s}=(e=>{let t="",i="";return 1===e.split(" ").length?{fnName:"",fnPath:e.split(" ")[0]}:(3===e.split(" ").length?(t=e.split(" (")[0],i=e.split(" (")[1].replace(")","")):(t=e.split(" ")[0],i=e.split(" ")[1].replace(/\((.*)\)/,"$1")),{fnName:t,fnPath:i})})(n);return r?`${r}[${s}]`:`[${s}]`}catch{return"Unknown location"}})(new Error),c={id:`${e}-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,timestamp:Date.now(),level:t,module:e,message:i,args:n,metadata:{url:"undefined"!=typeof window?null==(r=window.location)?void 0:r.href:void 0,caller:o}};if(s.addLogEntry(c),s.isDebugMode()){t}};return{debug:(e,...i)=>t("debug",e,...i),info:(e,...i)=>t("info",e,...i),warn:(e,...i)=>t("warn",e,...i),error:(e,...i)=>t("error",e,...i),subscribe:(e,t)=>s.subscribe(e,t),unsubscribe:e=>s.unsubscribe(e),getHistory:(e,t,i)=>s.getHistory(e,t,i),clear:()=>s.clear()}}function a(e){return o(e)}const c=(e,t)=>s.subscribe(e,t),l=e=>s.unsubscribe(e),u=(e,t,i)=>s.getHistory(e,t,i),d=()=>s.clear(),h=e=>s.addLogEntry(e),g=a("PlatformDetection");class p{strategies=[];register(e){this.strategies.push(e),this.strategies.sort(((e,t)=>t.getPriority()-e.getPriority()))}getStrategies(){return[...this.strategies]}}class f{canDetect(){return"undefined"!=typeof window&&("t9_core"in window||"vestel"===window.deviceBrand||navigator.userAgent.toLowerCase().includes("vestel"))}getPlatform(){return this.canDetect()?i.VESTEL:null}getPriority(){return 3}}class m{canDetect(){return"undefined"!=typeof window&&("jwt"in window||"launcher_env"in window||"undefined"!=typeof navigator&&navigator.userAgent.toLowerCase().indexOf("philips")>-1)}getPlatform(){return this.canDetect()?i.PHILIPS:null}getPriority(){return 5}}class S{canDetect(){if("undefined"==typeof window)return!1;const e=(()=>{const e=navigator.userAgent.match(/Chrome\/(\d+)\./);return e?parseInt(e[1],10):null})(),t=null!==e&&e<=84;return"undefined"!=typeof navigator&&navigator.userAgent.includes("Philips")&&(document.cookie.includes("tos-session")||t)}getPlatform(){return this.canDetect()?i.PHILIPS_OLD:null}getPriority(){return 10}}class v{canDetect(){return!0}getPlatform(){return i.BROWSER}getPriority(){return 1}}const b=new class{factory;lastDetectedPlatform=null;constructor(){this.factory=new p,this.factory.register(new m),this.factory.register(new f),this.factory.register(new S),this.factory.register(new v)}registerStrategy(e){this.factory.register(e)}detectPlatform(e={}){if(e.forcePlatform)return{platform:e.forcePlatform,detectedBy:"forced",confidence:1};if(this.lastDetectedPlatform)return{...this.lastDetectedPlatform};const t=this.factory.getStrategies();for(const i of t)if(i.canDetect()){const t=i.getPlatform();if(null!==t){const n={platform:t,detectedBy:i.constructor.name,confidence:.9};return this.lastDetectedPlatform=n,e.debug&&g.info(`Platform detected as ${t}`),{...n}}}if(!1===e.fallbackToBrowser)throw new r("Could not detect platform and fallback is disabled",n.PLATFORM_NOT_DETECTED);const s={platform:i.BROWSER,detectedBy:"fallback",confidence:.1};return this.lastDetectedPlatform=s,e.debug&&g.info("Fallback to browser platform - no strategy matched"),{...s}}reset(){this.lastDetectedPlatform=null}},y={LAUNCH_APP_REQUEST:"LAUNCH_APP_REQUEST",DEVICE_INFO_REQUEST:"DEVICE_INFO_REQUEST",TTS_REQUEST_SETTINGS:"TTS_REQUEST_SETTINGS",TTS_REQUEST_START_SPEAKING:"TTS_REQUEST_START_SPEAKING",TTS_REQUEST_STOP_SPEAKING:"TTS_REQUEST_STOP_SPEAKING",ERROR_SIMULATION:"ERROR_SIMULATION",LAUNCH_APP_RESPONSE:"LAUNCH_APP_RESPONSE",DEVICE_INFO_RESPONSE:"DEVICE_INFO_RESPONSE",TTS_RESPONSE_SETTINGS:"TTS_RESPONSE_SETTINGS",TTS_RESPONSE_START_SPEAKING:"TTS_RESPONSE_START_SPEAKING",TTS_RESPONSE_STOP_SPEAKING:"TTS_RESPONSE_STOP_SPEAKING",ERROR_SIMULATION_RESPONSE:"ERROR_SIMULATION_RESPONSE",LAUNCHER_READY:"LAUNCHER_READY",BRIDGE_READY:"BRIDGE_READY",TTS_SETTINGS_CHANGE:"TTS_SETTINGS_CHANGE",TM_SETTINGS_CHANGE:"TM_SETTINGS_CHANGE",LOG_ENTRY:"LOG_ENTRY",ERROR_RESPONSE:"ERROR_RESPONSE",TRANSFER_DATA:"TRANSFER_DATA"},w={TTS_SETTINGS_CHANGE:y.TTS_SETTINGS_CHANGE,TM_SETTINGS_CHANGE:y.TM_SETTINGS_CHANGE,LOG_ENTRY:y.LOG_ENTRY},T={enabled:!1,available:!1},E={enabled:!1,available:!1},I={tts:T,tm:E},C="TIMEOUT",R="NOT_SUPPORTED",D="INVALID_REQUEST",A="COMMUNICATION_ERROR",P="LAUNCH_FAILED",k="APP_NOT_FOUND",M="APP_NOT_AVAILABLE",N="INVALID_APP_CODE";var _=(e=>(e.PHILIPS="philips",e.VESTEL="vestel",e.BROWSER="browser",e))(_||{});class O{mocks={};constructor(e){e&&(this.mocks={...e})}get(e){return e in this.mocks?this.mocks[e]:"undefined"!=typeof window&&e in window?window[e]:void 0}has(e){return e in this.mocks||"undefined"!=typeof window&&e in window}get proxy(){return new Proxy({},{get:(e,t)=>{const i=t,n=this.get(i);return"function"==typeof n?(...e)=>{try{return n(...e)}catch(t){return}}:n}})}setMocks(e){this.mocks={...this.mocks,...e}}clearMocks(){this.mocks={}}removeMock(e){const t={};for(const i in this.mocks)i!==e&&(t[i]=this.mocks[i]);this.mocks=t}getAvailableMethods(){const e=new Set;for(const t in this.mocks)Object.prototype.hasOwnProperty.call(this.mocks,t)&&e.add(t);if("undefined"!=typeof window)for(const t in window)Object.prototype.hasOwnProperty.call(window,t)&&t in window&&e.add(t);return Array.from(e)}create(e,t){"undefined"!=typeof window&&(window[e]=t)}removeGlobal(e){"undefined"!=typeof window&&e in window&&delete window[e]}}function L(e,t,i="titanos"){return new Promise(((e,n)=>{const r=new O,s="deviceInfoCallback_"+Date.now()+"_"+Math.floor(1e4*Math.random());r.create(s,(t=>{e(t),r.removeGlobal(s)}));const o=`https://${t}/potamoi/v1/device_info?callback=${s}`,a=`https://smarttv.zeasn.tv/homepage_api/device/clientInfo?callback=${s}`,c=document.createElement("script");c.src="titanos"===i?o:a,c.type="text/javascript",c.onerror=()=>{n(new Error("Failed to load device info script.")),delete r.proxy[s]},document.head.appendChild(c),setTimeout((()=>{r.has(s)&&(n(new Error("Device info request timed out.")),delete r.proxy[s]),c.parentNode&&c.parentNode.removeChild(c)}),7e3)}))}const x=()=>{const e=e=>{const t=(Math.random().toString(16)+"000000000").substring(2,10);return e?"-"+t.substring(0,4)+"-"+t.substring(4,8):t};return e(!1)+e(!0)+e(!0)+e(!1)};function H(){return"undefined"!=typeof document&&!!document.body}function U(e=5e3){return new Promise(((t,i)=>{if(H())return void t();const n=setTimeout((()=>{i(new Error("Timeout waiting for document.body to be available"))}),e),r=()=>{H()?(clearTimeout(n),t()):setTimeout(r,10)};r()}))}const F=(e="en-US")=>"undefined"!=typeof navigator&&navigator.language&&navigator.language||e,B=a("BaseBridge");class V{src="";isInitialized=!1;iframe=null;iframeOrigin="";pendingRequests=new Map;messageTimeout=1e4;iframeTimeout=3e3;connected=!1;debug=!1;initializationPromise=null;aborted=!1;initReject;MESSAGE_TYPES=y;eventHandlers=new Map;constructor(e){this.debug=(null==e?void 0:e.debug)||!1,(null==e?void 0:e.gatewayUrl)&&(this.src=e.gatewayUrl),B.debug("bridge: constructor",this.src)}async initialize(){if(this.isInitialized)return!0;if(this.initializationPromise)return B.debug("bridge: initialization already in progress, waiting..."),this.initializationPromise;B.debug("bridge: initialization not in progress, starting new one"),this.initializationPromise=this.performInitialization();try{return await this.initializationPromise}catch(e){throw this.initializationPromise=null,e}}async performInitialization(){return new Promise(((e,t)=>{this.aborted=!1,this.initReject=t,B.debug("bridge: starting initialization process"),window.addEventListener("message",this.handleMessage.bind(this));const i=()=>{this.aborted||(this.isInitialized=!0,B.debug("bridge initialized successfully"),e(!0))},n=()=>{this.aborted||(B.error("Bridge iframe failed to load or initialize."),this.isInitialized=!1,t(new Error("Bridge iframe failed to load or initialize.")))};(async()=>{try{await this.setupIframe(i,n)}catch(e){B.error("Failed to setup iframe:",e),this.isInitialized=!1,t(e)}})()}))}async sendMessage(e,t){this.isInitialized||await this.initialize();try{const i=this.prepareMessage(e,t);return new Promise(((e,t)=>{const s=setTimeout((()=>{this.pendingRequests.delete(i.requestId),t(new r("Bridge request timeout",n.TIMEOUT))}),this.messageTimeout);this.pendingRequests.set(i.requestId,{resolve:e,reject:t,timeout:s}),this.iframe&&this.iframe.contentWindow?(B.debug("bridge: sendMessage",i),this.iframe.contentWindow.postMessage(i,this.iframeOrigin||"*")):(clearTimeout(s),this.pendingRequests.delete(i.requestId),t(new r("Bridge iframe not available",n.COMMUNICATION_ERROR)))}))}catch(i){B.error("bridge: error sending message:",i);return(await Promise.resolve().then((()=>Pt)).then((e=>e.rollbarClient))).reportError(i instanceof Error?i:new Error("Unknown error"),{component:"SDK",operation:"sendMessage",requestId:this.prepareMessage(e,t).requestId}),Promise.reject({success:!1,type:e,error:{code:n.COMMUNICATION_ERROR,message:i instanceof Error?i.message:"Unknown error"}})}}disconnect(){this.aborted=!0,this.initReject&&(this.initReject(new Error("Bridge initialization aborted")),this.initReject=void 0),this.iframe&&(window.removeEventListener("message",this.handleMessage.bind(this)),document.body.removeChild(this.iframe),this.iframe=null),this.isInitialized=!1,this.connected=!1,this.initializationPromise=null,this.pendingRequests.clear(),this.eventHandlers.clear()}isConnected(){return this.isInitialized&&this.connected}getBridgeHealth(){return{connected:this.isConnected()}}registerEventHandler(e,t){var i;this.eventHandlers.has(e)||this.eventHandlers.set(e,new Set);const n=e=>{t(e)};return null==(i=this.eventHandlers.get(e))||i.add(n),window.addEventListener("message",(e=>n(e.data.data))),()=>{var t;window.removeEventListener("message",(e=>{var t;return n(null==(t=e.data)?void 0:t.data)})),null==(t=this.eventHandlers.get(e))||t.delete(n)}}handleMessage(e){var t;if(!this.iframeOrigin||e.origin===this.iframeOrigin)try{const i=e.data;if(this.debug&&i&&i.requestId&&B.debug("bridge handleMessage",i),i&&("BRIDGE_READY"===i.type||"LAUNCHER_READY"===i.type)&&(null==(t=this.iframe)?void 0:t.contentWindow)===e.source)return void(this.connected=!0);if(i&&i.type&&Object.values(w).includes(i.type)&&!i.requestId)return void this.handleNotification(i);if(i&&i.requestId&&this.pendingRequests.has(i.requestId)){const{resolve:e,reject:t,timeout:n}=this.pendingRequests.get(i.requestId);if(clearTimeout(n),this.pendingRequests.delete(i.requestId),!1===i.success&&i.error){const e=this.getOperationFromMessageType(i.type||"unknown");t(this.createSDKErrorFromGatewayResponse(i.error,e))}else e({success:!0,data:i.response||i.data||i.result,requestId:i.requestId,timestamp:i.timestamp||Date.now()})}}catch(i){B.error("Error handling message:",i)}}handleNotification(e){B.debug("bridge notification received:",e);const t=this.eventHandlers.get(e.type);t&&t.forEach((t=>{try{t(e.data)}catch(i){B.error(`Error in ${e.type} handler:`,i)}}))}prepareMessage(e,t){return{payload:t,type:e,requestId:this.generateRequestId(),timestamp:Date.now()}}generateRequestId(){return`bridge_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}createSDKErrorFromGatewayResponse(e,t){const i=this.mapGatewayErrorCodeToSDK(e.code);return new r(e.message,i,{operation:t,gatewayErrorCode:e.code,gatewayErrorMessage:e.message})}mapGatewayErrorCodeToSDK(e){switch(e){case P:case k:case M:case N:return n.INVALID_PARAMETER;case C:return n.TIMEOUT;case R:return n.NOT_SUPPORTED;case A:return n.COMMUNICATION_ERROR;case D:return n.INVALID_ARGUMENTS;default:return n.UNKNOWN}}getOperationFromMessageType(e){switch(e){case y.LAUNCH_APP_REQUEST:return"launchApp";case y.DEVICE_INFO_REQUEST:return"getDeviceInfo";case y.TTS_REQUEST_START_SPEAKING:return"startSpeaking";case y.TTS_REQUEST_STOP_SPEAKING:return"stopSpeaking";case y.TTS_REQUEST_SETTINGS:return"getTTSSettings";default:return"sdkOperation"}}async setupIframe(e,t){if(!this.iframe&&this.src){if(await new Promise((e=>{"undefined"!=typeof document&&"loading"===document.readyState?document.addEventListener("DOMContentLoaded",(()=>e()),{once:!0}):e()})),this.iframe=document.createElement("iframe"),this.iframe.style.display="none",this.iframe.src=this.src,this.iframe.setAttribute("sandbox","allow-scripts"),!H())try{await U(5e3)}catch(i){throw new Error("Document body is not available even after waiting. Make sure the SDK is initialized after DOM content loaded.")}document.body.appendChild(this.iframe),await new Promise((i=>{const n=setTimeout((()=>{this.aborted||(B.warn("Bridge iframe ready timeout - continuing anyway"),i())}),this.iframeTimeout),r=t=>{var s;this.aborted||t.data&&t.data.type===y.LAUNCHER_READY&&(null==(s=this.iframe)?void 0:s.contentWindow)===t.source&&(B.debug("bridge iframe ready:",t.data),window.removeEventListener("message",r),clearTimeout(n),this.connected=!0,e&&e(),i())};window.addEventListener("message",r),window.addEventListener("message",(e=>{var t;this.aborted||e.data&&e.data.type===y.TRANSFER_DATA&&(null==(t=this.iframe)?void 0:t.contentWindow)===e.source&&B.debug("bridge transferData:",e.data)})),this.iframe&&(this.iframe.onload=()=>{this.aborted||B.debug("bridge iframe loaded: ",this.src)},this.iframe.onerror=()=>{this.aborted||(B.error("bridge iframe error: ",this.src),t&&t())})}))}}promisify(e){return(...t)=>new Promise(((i,n)=>{try{i(e.apply(null,t))}catch(r){n(r)}}))}async getDeviceInfo(){this.isInitialized||await this.initialize();const e=await this.sendMessage(y.DEVICE_INFO_REQUEST,void 0);if(e.success&&"data"in e)return e.data}async launchApp(e){this.isInitialized||await this.initialize();const t={code:e.appId,query:e.deepLink||""};return(await this.sendMessage(y.LAUNCH_APP_REQUEST,t)).success}onLogEntry(e){return this.registerEventHandler(y.LOG_ENTRY,(t=>{h({...t,metadata:{...t.metadata,source:"Gateway",tunneled:!0}}),e(t)}))}}const z=a("CSPDetector");let K=[];const $=class{static async canCreateIframe(e){try{if("undefined"==typeof document)return!1;try{await U(5e3)}catch(t){return z.warn("Timeout waiting for document.body, cannot create iframe"),!1}const i=document.createElement("iframe");return i.style.display="none",i.style.position="absolute",i.style.top="-9999px",i.src=e,i.allow="storage-access",i.setAttribute("sandbox","allow-scripts allow-same-origin"),new Promise((e=>{const n=setTimeout((()=>{r(),e(!1)}),5e3),r=()=>{clearTimeout(n),i.parentNode&&i.parentNode.removeChild(i)};i.onload=()=>{r(),e(!0)},i.onerror=()=>{r(),e(!1)};try{document.body.appendChild(i)}catch(t){r(),e(!1)}}))}catch(t){return z.error("Error checking iframe creation:",t),!1}}static async canPostMessage(e){try{if("undefined"==typeof window)return!1;try{await U(5e3)}catch(t){return z.warn("Timeout waiting for document.body, cannot test postMessage"),!1}const e=document.createElement("iframe");return e.style.display="none",e.src="about:blank",new Promise((i=>{const n=setTimeout((()=>{r(),i(!1)}),1e3),r=()=>{clearTimeout(n),e.parentNode&&e.parentNode.removeChild(e)};e.onload=()=>{try{e.contentWindow?(e.contentWindow.postMessage({type:"test"},"*"),r(),i(!0)):(r(),i(!1))}catch(t){r(),i(!1)}};try{document.body.appendChild(e)}catch(t){r(),i(!1)}}))}catch(t){return z.error("Error checking postMessage:",t),!1}}static async checkBridgeCSP(e){z.debug("Checking CSP compatibility for:",e);const t={canCreateIframe:!1,canPostMessage:!1,cspViolations:[...this.violations]};try{return this.violations.length=0,t.canCreateIframe=await this.canCreateIframe(e),t.canPostMessage=await this.canPostMessage(e),t.cspViolations=[...this.violations],z.debug("CSP check results:",t),t}catch(i){return t.error=i instanceof Error?i.message:"Unknown error",z.error("CSP check failed:",i),t}}static getViolations(){return[...this.violations]}static clearViolations(){this.violations.length=0}static onViolation(e){return K.push(e),()=>{K=K.filter((t=>t!==e))}}static checkWebAPISupport(){return{hasPostMessage:"undefined"!=typeof window&&"postMessage"in window,hasIframe:"undefined"!=typeof document&&"createElement"in document,hasMessageEvent:"undefined"!=typeof MessageEvent,hasDocument:"undefined"!=typeof document}}};var G;((t,i,n)=>{i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n})($,"symbol"!=typeof(G="violations")?G+"":G,[]),"undefined"!=typeof document&&document.addEventListener("securitypolicyviolation",(e=>{const t=`${e.violatedDirective}: ${e.blockedURI}`;$.violations.push(t),z.warn("CSP Violation detected:",t);const i={directive:e.violatedDirective,blockedURI:e.blockedURI,originalEvent:e};K.forEach((e=>{try{e(i)}catch(t){z.error("CSPDetector listener error",t)}}))}));let W=$;const j=a("EnhancedBridge");class q extends V{bridgeHealthStatus={connected:!1,cspBlocked:!1,iframeCreated:!1,communicationWorking:!1,cspViolations:[]};cspUnsubscribe;cspViolationPromise;resolveCspViolation;enhancedInitializationPromise=null;constructor(e){super(e),this.bridgeHealthStatus.gatewayUrl=this.src,this.cspViolationPromise=new Promise((e=>{this.resolveCspViolation=e})),this.setupCspViolationPromise()}setupCspViolationPromise(){this.cspUnsubscribe=W.onViolation((e=>{(function(e,t){if("frame-src"!==e.directive||!e.blockedURI||!t)return!1;try{const i=new URL(t),n=new URL(e.blockedURI);if(i.origin===n.origin)return!0}catch{}return!!t.startsWith(e.blockedURI)||!!(e.blockedURI&&t&&t.includes(e.blockedURI))})(e,this.src)&&(this.resolveCspViolation(e),this.cspUnsubscribe&&(this.cspUnsubscribe(),this.cspUnsubscribe=void 0))}))}async initialize(){return this.enhancedInitializationPromise||(this.enhancedInitializationPromise=(async()=>{try{j.debug("Starting enhanced bridge initialization");const e=await this.checkCSPCompatibility();if(this.updateHealthStatus(e),e.cspViolations.length>0&&j.warn("CSP violations detected:",e.cspViolations),!e.canCreateIframe)return j.error("Cannot create iframe due to CSP restrictions"),this.bridgeHealthStatus.cspBlocked=!0,!1;const t=await Promise.race([super.initialize(),this.cspViolationPromise.then((e=>{j.warn("[EnhancedBridge] CSP violation detected:",e,this.src),this.bridgeHealthStatus.cspBlocked=!0,this.bridgeHealthStatus.communicationWorking=!1,this.bridgeHealthStatus.lastError="CSP blocked bridge iframe",this.disconnect()}))]);return this.bridgeHealthStatus.connected=!!t,!!t}catch(e){const t=e instanceof Error?e.message:"Unknown error";return this.bridgeHealthStatus.lastError=t,j.error("Enhanced bridge initialization failed:",e),!1}finally{this.enhancedInitializationPromise=null}})()),this.enhancedInitializationPromise}async checkCSPCompatibility(){return this.src?await W.checkBridgeCSP(this.src):{canCreateIframe:!1,canPostMessage:!1,cspViolations:[],error:"No gateway URL configured"}}updateHealthStatus(e){this.bridgeHealthStatus.cspBlocked=!e.canCreateIframe,this.bridgeHealthStatus.communicationWorking=e.canPostMessage,this.bridgeHealthStatus.cspViolations=e.cspViolations,e.error&&(this.bridgeHealthStatus.lastError=e.error)}getBridgeHealth(){return{...this.bridgeHealthStatus,connected:this.isConnected(),iframeCreated:null!==this.iframe}}async setupIframe(e,t){try{const i=await this.checkCSPCompatibility();if(!i.canCreateIframe)throw new r("Cannot create iframe due to CSP restrictions",n.NOT_SUPPORTED,{cspViolations:i.cspViolations});await super.setupIframe(e,t),this.bridgeHealthStatus.iframeCreated=!0}catch(i){throw this.bridgeHealthStatus.iframeCreated=!1,this.bridgeHealthStatus.lastError=i instanceof Error?i.message:"Unknown error",i}}async executeBridgeFunction(e,t){const i=this.getBridgeHealth();if(!i.connected||i.cspBlocked){if(t)return j.debug("Bridge unavailable, using fallback function"),await t();throw new r(i.cspBlocked?"Bridge unavailable due to CSP restrictions":"Bridge not connected",i.cspBlocked?n.NOT_SUPPORTED:n.COMMUNICATION_ERROR,{healthStatus:i})}return await e()}async executeWithFallback(e,t){return await this.executeBridgeFunction(e,t)}async sendMessage(e,t){return await this.executeBridgeFunction((()=>super.sendMessage(e,t)))}getConnectionResult(){const e=this.getBridgeHealth();return{success:e.connected&&!e.cspBlocked,healthStatus:e,error:e.lastError}}async testConnectivity(){try{j.debug("Testing bridge connectivity");const t=await this.checkCSPCompatibility();if(this.updateHealthStatus(t),t.canCreateIframe&&this.isConnected())try{await this.getDeviceInfo(),this.bridgeHealthStatus.communicationWorking=!0}catch(e){this.bridgeHealthStatus.communicationWorking=!1,this.bridgeHealthStatus.lastError=e instanceof Error?e.message:"Communication test failed"}return this.getConnectionResult()}catch(e){const t=e instanceof Error?e.message:"Unknown error";return this.bridgeHealthStatus.lastError=t,{success:!1,healthStatus:this.getBridgeHealth(),error:t}}}disconnect(){this.aborted||(super.disconnect(),this.cspUnsubscribe&&(this.cspUnsubscribe(),this.cspUnsubscribe=void 0),this.bridgeHealthStatus={connected:!1,cspBlocked:!1,iframeCreated:!1,communicationWorking:!1,gatewayUrl:this.src,cspViolations:[]},this.aborted=!0)}}class Q extends q{constructor(e){if(null==e?void 0:e.gatewayUrl)super({gatewayUrl:e.gatewayUrl});else{const e=window.location.hostname.includes("dev01.devview"),t=window.location.hostname.startsWith("dev");super({gatewayUrl:`http://localhost:4660/gateway/${e||t?"dev01":"index"}.html`})}}}const J=new O;class Y extends q{constructor(e){var t,i;if(null==e?void 0:e.gatewayUrl)super({gatewayUrl:e.gatewayUrl});else{let e="app";if(J.proxy.jwt&&!J.proxy.jwt.includes("null")){const t=(e=>{const t=e.split(".");if(3!==t.length)throw new Error("Invalid JWT token format");try{const e=t[1].replace(/-/g,"+").replace(/_/g,"/"),i=window.atob(e),n=decodeURIComponent(Array.from(i).map((e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2))).join(""));return JSON.parse(n)}catch(i){throw new Error("Error decoding JWT token: "+(i instanceof Error?i.message:String(i)))}})(J.proxy.jwt);e=("production"===t.iss?"app":t.iss)||"app"}let n=`https://${e}.titanos.tv/gateway/${e.startsWith("dev")?"dev01":"index"}.html`;((null==(i=null==(t=J.proxy.location)?void 0:t.host)?void 0:i.includes("dev01.devview"))||e.startsWith("dev"))&&(n="https://dev01.devview.titanos.tv/gateway/dev01.html"),super({gatewayUrl:n})}}async getTTSSettings(){return(await this.getA11ySettings()).tts||T}async getTMSettings(){return(await this.getA11ySettings()).tm||E}async getA11ySettings(){const e=await this.sendMessage(y.TTS_REQUEST_SETTINGS,void 0);return e.success&&"data"in e?e.data:I}async startSpeaking(e){this.isInitialized||await this.initialize();return(await this.sendMessage(y.TTS_REQUEST_START_SPEAKING,e)).success}async stopSpeaking(){return(await this.sendMessage(y.TTS_REQUEST_STOP_SPEAKING,void 0)).success}onTTSSettingsChange(e){return this.registerEventHandler(y.TTS_SETTINGS_CHANGE,(t=>{e(t)}))}onTMSettingsChange(e){return this.registerEventHandler(y.TM_SETTINGS_CHANGE,(t=>{e(t)}))}}const Z={HIGH:["button","link","heading","listitem"],MEDIUM:["textbox","combobox","checkbox","radio","slider"],LOW:["list","navigation","main","dialog","grid"]},X=a("AriaProcessor");class ee{config;implicitRoles={button:"button",a:"link",'input[type="text"]':"textbox",'input[type="email"]':"textbox",'input[type="password"]':"textbox",'input[type="search"]':"textbox",'input[type="tel"]':"textbox",'input[type="url"]':"textbox",'input[type="checkbox"]':"checkbox",'input[type="radio"]':"radio",'input[type="range"]':"slider",textarea:"textbox",select:"combobox",h1:"heading",h2:"heading",h3:"heading",h4:"heading",h5:"heading",h6:"heading",nav:"navigation",main:"main",aside:"complementary",section:"region",article:"article",ul:"list",ol:"list",li:"listitem",table:"table",tr:"row",td:"cell",th:"columnheader",img:"img",dialog:"dialog"};tvElementTypes={navigation:["nav","menu",'[role="navigation"]','[role="menubar"]'],mediaControl:['[role="button"][aria-label*="play"]','[role="button"][aria-label*="pause"]','[role="slider"][aria-label*="volume"]','[role="progressbar"]'],contentGrid:['[role="grid"]','[role="gridcell"]',".content-grid",".video-grid"],mainContent:["main",'[role="main"]',".main-content","#main"]};constructor(e){this.config={...e}}updateConfig(e){this.config={...e}}async processElement(e){try{if(this.isElementHidden(e))return null;const t=this.getElementRole(e);if(this.config.tvOptimized&&!this.isRelevantForTV(t))return null;const i=this.computeAccessibleName(e);if(!i&&this.isInteractiveElement(t))return X.warn("Interactive element without accessible name:",e),null;const n=this.getAccessibleDescription(e),r=this.computeElementState(e),s=this.computePositionInfo(e,t),o=this.getAvailableActions(e,t),a=this.config.tvOptimized?this.getTVSpecificProperties(e,t):void 0,c={element:e,role:t,name:i,description:n,state:r,position:s,actions:o,tvProperties:a};return X.debug("Processed accessibility element:",{role:t,name:i.substring(0,50),state:r,tvOptimized:!!a}),c}catch(t){return X.error("Error processing element:",t),null}}isElementHidden(e){if("true"===e.getAttribute("aria-hidden"))return!0;const t=window.getComputedStyle(e);if("none"===t.display||"hidden"===t.visibility||"0"===t.opacity)return!0;if(this.config.tvOptimized){const t=e.getBoundingClientRect();if(0===t.width&&0===t.height)return!0}return!1}getElementRole(e){const t=e.getAttribute("role");if(t)return t;const i=e.tagName.toLowerCase(),n=e.getAttribute("type");if("input"===i&&n){const e=`input[type="${n}"]`;if(this.implicitRoles[e])return this.implicitRoles[e]}return this.implicitRoles[i]||"generic"}computeAccessibleName(e){const t=e.getAttribute("aria-labelledby");if(t){const e=[];for(const i of t.split(/\s+/)){const t=document.getElementById(i);t&&e.push(this.getTextContent(t))}if(e.length>0)return e.join(" ").trim()}const i=e.getAttribute("aria-label");if(i)return i.trim();if(this.isFormControl(e)){const t=this.getAssociatedLabels(e);if(t.length>0)return t.map((e=>this.getTextContent(e))).join(" ").trim()}if("input"===e.tagName.toLowerCase()){const t=e.getAttribute("placeholder");if(t)return t.trim()}if("img"===e.tagName.toLowerCase()){const t=e.getAttribute("alt");if(null!==t)return t.trim()}return this.getTextContent(e)}getAccessibleDescription(e){const t=e.getAttribute("aria-describedby");if(!t)return;const i=[];for(const n of t.split(/\s+/)){const e=document.getElementById(n);e&&i.push(this.getTextContent(e))}return i.length>0?i.join(" ").trim():void 0}computeElementState(e){const t={},i=e.getAttribute("aria-expanded");null!==i&&(t.expanded="true"===i);const n=e.getAttribute("aria-checked");null!==n&&(t.checked="mixed"===n?"mixed":"true"===n);const r=e.getAttribute("aria-selected");null!==r&&(t.selected="true"===r);const s=e.getAttribute("aria-disabled")||e.getAttribute("disabled");null!==s&&(t.disabled="true"===s||""===s);const o=e.getAttribute("aria-invalid");null!==o&&(t.invalid="true"===o||o);const a=e.getAttribute("aria-level");null!==a?t.level=parseInt(a,10):e.tagName.match(/^H[1-6]$/)&&(t.level=parseInt(e.tagName.charAt(1),10));const c=e.getAttribute("aria-valuenow");null!==c&&(t.valueNow=parseFloat(c));const l=e.getAttribute("aria-valuetext");return null!==l&&(t.valueText=l),t.focused=document.activeElement===e,t}computePositionInfo(e,t){return"listitem"===t?this.computeListItemPosition(e):"gridcell"===t||"cell"===t?this.computeGridCellPosition(e):void 0}computeListItemPosition(e){const t=e.getAttribute("aria-posinset"),i=e.getAttribute("aria-setsize");if(t&&i)return{position:parseInt(t,10),setSize:parseInt(i,10)};const n=e.closest('ul, ol, [role="list"]');if(n){const t=Array.from(n.querySelectorAll('li, [role="listitem"]')),i=t.indexOf(e)+1;if(i>0)return{position:i,setSize:t.length}}}computeGridCellPosition(e){const t=e.closest('[role="row"], tr'),i=e.closest('[role="grid"], table');if(t&&i){const n=Array.from(i.querySelectorAll('[role="row"], tr')),r=Array.from(t.querySelectorAll('[role="gridcell"], [role="cell"], td, th')),s=n.indexOf(t)+1,o=r.indexOf(e)+1;if(s>0&&o>0)return{position:o,setSize:r.length,row:s,column:o,totalRows:n.length,totalColumns:r.length}}}getAvailableActions(e,t){const i=[];if(this.isClickableElement(e,t)&&i.push({name:"activate",description:this.getActivationDescription(t),tvButton:"OK"}),e.hasAttribute("aria-expanded")){const t="true"===e.getAttribute("aria-expanded");i.push({name:t?"collapse":"expand",description:t?"Collapse":"Expand",tvButton:"OK"})}return"textbox"!==t&&"combobox"!==t||i.push({name:"edit",description:"Enter text",tvButton:"OK"}),i}getTVSpecificProperties(e,t){const i={};return this.matchesSelectors(e,this.tvElementTypes.navigation)&&(i.isMainNavigation=!0,i.priority="high"),this.matchesSelectors(e,this.tvElementTypes.mediaControl)&&(i.isMediaControl=!0,i.priority="high"),this.matchesSelectors(e,this.tvElementTypes.contentGrid)&&(i.isContentGrid=!0,i.priority="medium"),i.priority||(Z.HIGH.includes(t)?i.priority="high":Z.MEDIUM.includes(t)?i.priority="medium":i.priority="low"),Object.keys(i).length>0?i:void 0}isRelevantForTV(e){return[...Z.HIGH,...Z.MEDIUM,...Z.LOW].includes(e)}isInteractiveElement(e){return["button","link","textbox","combobox","checkbox","radio","slider"].includes(e)}isFormControl(e){return["input","textarea","select","button"].includes(e.tagName.toLowerCase())}isClickableElement(e,t){return["button","link","checkbox","radio","menuitem"].includes(t)||e.hasAttribute("onclick")}getActivationDescription(e){return{button:"Press button",link:"Follow link",checkbox:"Toggle checkbox",radio:"Select option",menuitem:"Select menu item"}[e]||"Activate"}getTextContent(e){let t="";for(const i of e.childNodes)if(i.nodeType===Node.TEXT_NODE)t+=i.textContent||"";else if(i.nodeType===Node.ELEMENT_NODE){const e=i;this.isElementHidden(e)||(t+=this.getTextContent(e))}return t.replace(/\s+/g," ").trim()}getAssociatedLabels(e){const t=[],i=e.getAttribute("id");if(i){const e=document.querySelectorAll(`label[for="${i}"]`);t.push(...Array.from(e))}const n=e.closest("label");return n&&t.push(n),t}matchesSelectors(e,t){return t.some((t=>{try{return e.matches(t)}catch{return!1}}))}}const te=a("DOMMonitor");class ie{config;ariaProcessor;isTracking=!1;focusHandler;liveRegionHandler;focusListener;keydownListener;mutationObserver;currentFocusedElement=null;liveRegions=new Map;previousFocusedElement=null;constructor(e,t){this.config={...e},this.focusHandler=t,this.ariaProcessor=new ee(e)}updateConfig(e){this.config={...e},this.ariaProcessor.updateConfig(e)}async startFocusTracking(){if(this.isTracking)return void te.debug("Focus tracking already active");te.info("Starting focus tracking"),this.focusListener=this.handleFocusEvent.bind(this),document.addEventListener("focusin",this.focusListener,!0),document.addEventListener("focusout",this.focusListener,!0),this.keydownListener=this.handleKeydownEvent.bind(this),document.addEventListener("keydown",this.keydownListener,!0);const e=document.activeElement;e&&e!==document.body&&(this.currentFocusedElement=e,await this.processFocusChange(e,"initial")),this.isTracking=!0,te.info("Focus tracking started")}async startLiveRegionMonitoring(e){this.liveRegionHandler=e,te.info("Starting live region monitoring"),await this.scanForLiveRegions(),this.mutationObserver=new MutationObserver(this.handleMutations.bind(this)),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["aria-live","aria-atomic","aria-relevant","aria-busy"]}),te.info("Live region monitoring started")}async stop(){te.info("Stopping DOM monitoring"),this.focusListener&&(document.removeEventListener("focusin",this.focusListener,!0),document.removeEventListener("focusout",this.focusListener,!0),this.focusListener=void 0),this.keydownListener&&(document.removeEventListener("keydown",this.keydownListener,!0),this.keydownListener=void 0),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=void 0),this.currentFocusedElement=null,this.previousFocusedElement=null,this.liveRegions.clear(),this.isTracking=!1,this.liveRegionHandler=void 0,te.info("DOM monitoring stopped")}async restart(){await this.stop(),this.config.focusTracking&&await this.startFocusTracking(),this.config.liveRegions&&this.liveRegionHandler&&await this.startLiveRegionMonitoring(this.liveRegionHandler)}async handleFocusEvent(e){try{const t=e.target;"focusin"===e.type?t&&t!==this.currentFocusedElement&&(this.currentFocusedElement=t,await this.processFocusChange(t,"user")):"focusout"===e.type&&t===this.currentFocusedElement&&(this.currentFocusedElement=null)}catch(t){te.error("Error handling focus event:",t)}}async handleKeydownEvent(e){const t={ArrowUp:"UP",ArrowDown:"DOWN",ArrowLeft:"LEFT",ArrowRight:"RIGHT",Enter:"OK",Escape:"BACK",Tab:"TAB"}[e.key];t&&this.currentFocusedElement&&te.debug("TV remote button pressed:",t)}async processFocusChange(e,t){try{if(this.ariaProcessor.isElementHidden(e))return;const i=await this.ariaProcessor.processElement(e);if(i&&this.focusHandler){const e={previousElement:this.previousFocusedElement||void 0,currentElement:i,reason:t};await this.focusHandler(e),this.previousFocusedElement=i}}catch(i){te.error("Error processing focus change:",i)}}async scanForLiveRegions(){const e=document.querySelectorAll("[aria-live]");for(const t of e){const e=this.createLiveRegion(t);e&&(this.liveRegions.set(t,e),te.debug("Found live region:",{politeness:e.politeness,atomic:e.atomic}))}}createLiveRegion(e){const t=e.getAttribute("aria-live");if(!t||"off"===t)return null;const i=t,n="true"===e.getAttribute("aria-atomic"),r=(e.getAttribute("aria-relevant")||"additions text").split(" "),s="true"===e.getAttribute("aria-busy");return{element:e,politeness:i,atomic:n,relevant:r,busy:s}}async handleMutations(e){for(const i of e)try{"attributes"===i.type&&await this.handleAttributeChange(i),"childList"!==i.type&&"characterData"!==i.type||await this.handleContentChange(i)}catch(t){te.error("Error handling mutation:",t)}}async handleAttributeChange(e){const t=e.target,i=e.attributeName;if("aria-live"===i){const e=this.createLiveRegion(t);e?this.liveRegions.set(t,e):this.liveRegions.delete(t)}else if("aria-busy"===i){const e=this.liveRegions.get(t);e&&(e.busy="true"===t.getAttribute("aria-busy"))}}async handleContentChange(e){let t=e.target;for(;t&&t!==document.body;){const i=this.liveRegions.get(t);if(i&&!i.busy&&this.liveRegionHandler){const n=i.atomic?t.textContent||"":this.extractChangedContent(e);n.trim()&&await this.liveRegionHandler(i,n);break}t=t.parentElement}}extractChangedContent(e){if("characterData"===e.type)return e.target.textContent||"";if("childList"===e.type){let t="";for(const i of e.addedNodes)(i.nodeType===Node.TEXT_NODE||i.nodeType===Node.ELEMENT_NODE)&&(t+=i.textContent||"");return t}return""}}const ne=a("AnnouncementProcessor");class re{config;ttsFunction;stopTtsFunction;lastAnnouncementTime=0;announcementQueue=[];isProcessingQueue=!1;tvTimings={minInterval:100,maxQueueSize:5,priorityDelay:50,politeDelay:200};constructor(e,t,i){this.config={...e},this.ttsFunction=t,this.stopTtsFunction=i}updateConfig(e){this.config={...e}}async announce(e,t="polite"){const i=this.processAnnouncementText(e);if(!i||0===i.length)return ne.debug("No text to announce after processing"),!1;const n={text:i,priority:t,timestamp:Date.now()};return"assertive"===t?(this.announcementQueue.length=0,await this.speakNow(n)):(this.queueAnnouncement(n),this.processQueue(),!0)}async stopAnnouncement(){try{if(this.announcementQueue.length=0,this.isProcessingQueue=!1,this.stopTtsFunction){const e=await this.stopTtsFunction();return ne.debug("TTS stop result:",e),e}return ne.debug("No stopTtsFunction available"),!0}catch(e){return ne.error("Error stopping announcement:",e),!1}}async announceFocusChange(e){const{currentElement:t}=e;if(!t)return;const i=this.buildFocusAnnouncement(t);i.length>0&&await this.announce(i,"polite")}async announceLiveRegion(e,t){if(!e.trim())return;const i=this.processLiveRegionContent(e);i&&await this.announce([i],t)}buildFocusAnnouncement(e){const t=[],i=this.getRoleAnnouncement(e.role);i&&t.push(i),e.name&&t.push(e.name);const n=this.getStateAnnouncement(e.state,e.role);n.length>0&&t.push(...n);const r=this.getPositionAnnouncement(e.position,e.role);r&&t.push(r),e.description&&this.shouldIncludeDescription()&&t.push(e.description);const s=this.getActionAnnouncement(e.actions||[]);return s&&t.push(s),this.filterAnnouncementContent(t,e.role)}shouldIncludeDescription(){return"concise"!==this.config.verbosity&&(this.config.verbosity,!0)}filterAnnouncementContent(e,t){if(!this.config.tvOptimized)return e;const i=["button","link","heading","alert","dialog"].includes(t);return"concise"===this.config.verbosity?i?e.slice(0,2):e.slice(1,2):"standard"===this.config.verbosity?e.slice(0,4):e}getRoleAnnouncement(e){const t={button:{concise:"",standard:"button",detailed:"button"},link:{concise:"",standard:"link",detailed:"link"},heading:{concise:"",standard:"heading",detailed:"heading"},listitem:{concise:"",standard:"list item",detailed:"list item"},textbox:{concise:"",standard:"text field",detailed:"text field"},combobox:{concise:"",standard:"dropdown",detailed:"combo box"},checkbox:{concise:"check box",standard:"check box",detailed:"check box"},radio:{concise:"radio",standard:"radio button",detailed:"radio button"},slider:{concise:"slider",standard:"slider",detailed:"slider"},navigation:{concise:"",standard:"navigation",detailed:"navigation menu"},main:{concise:"",standard:"main content",detailed:"main content area"},dialog:{concise:"dialog",standard:"dialog",detailed:"dialog box"},grid:{concise:"",standard:"grid",detailed:"content grid"},gridcell:{concise:"",standard:"",detailed:"grid cell"},list:{concise:"",standard:"list",detailed:"list"},menu:{concise:"menu",standard:"menu",detailed:"menu"},menuitem:{concise:"",standard:"menu item",detailed:"menu item"},tab:{concise:"tab",standard:"tab",detailed:"tab"},tabpanel:{concise:"",standard:"tab panel",detailed:"tab panel"},progressbar:{concise:"progress",standard:"progress bar",detailed:"progress indicator"},alert:{concise:"alert",standard:"alert",detailed:"alert message"},status:{concise:"",standard:"status",detailed:"status update"}}[e];if(!t)return null;return t[this.config.verbosity]||t.standard||null}getStateAnnouncement(e,t){const i=[];if(!e)return i;const n="concise"===this.config.verbosity,r="detailed"===this.config.verbosity;if(void 0!==e.expanded&&(n?i.push(e.expanded?"open":"closed"):i.push(e.expanded?"expanded":"collapsed")),void 0!==e.checked&&("mixed"===e.checked?i.push(n?"mixed":"partially checked"):n?i.push(e.checked?"on":"off"):i.push(e.checked?"checked":"not checked")),e.selected&&i.push(n?"on":"selected"),e.disabled&&i.push("disabled"),e.invalid&&(r?i.push("string"==typeof e.invalid?e.invalid:"invalid"):i.push("invalid")),"heading"===t&&e.level&&(n?i.push(`h${e.level}`):i.push(`level ${e.level}`)),e.valueText)i.push(e.valueText);else if(void 0!==e.valueNow)if("progressbar"===t){const t=e.valueMax?Math.round(e.valueNow/e.valueMax*100):e.valueNow;i.push(n?`${t}%`:`${t} percent`)}else"slider"===t?i.push(n?`${e.valueNow}`:`value ${e.valueNow}`):i.push(`${e.valueNow}`);return this.config.tvOptimized&&e.focused&&r&&i.push("focused"),i}getPositionAnnouncement(e,t){if(!e)return null;const i="concise"===this.config.verbosity,n="detailed"===this.config.verbosity;return"listitem"===t?i?null:`${e.position} of ${e.setSize}`:"gridcell"===t&&e.row&&e.column?this.config.tvOptimized?i?`${e.row},${e.column}`:n&&e.totalRows&&e.totalColumns?`row ${e.row} of ${e.totalRows}, column ${e.column} of ${e.totalColumns}`:`row ${e.row}, column ${e.column}`:`row ${e.row}, column ${e.column}`:"tab"===t&&e.position&&e.setSize?i?null:`tab ${e.position} of ${e.setSize}`:"menuitem"===t&&e.position&&e.setSize?i?null:`${e.position} of ${e.setSize}`:null}getActionAnnouncement(e){if(!e||0===e.length)return null;const t="concise"===this.config.verbosity,i="detailed"===this.config.verbosity;if(!this.config.tvOptimized){return`available actions: ${e.map((e=>e.name)).slice(0,2).join(", ")}`}const n=e[0];if(!n)return null;if(n.tvButton){if(t)return null;const e=this.getTVButtonText(n.tvButton),r=n.description||"activate";return i?`press ${e} to ${r.toLowerCase()}`:`press ${e}`}if(n.name){if(t)return null;const e=this.getCommonTVAction(n.name);if(e)return i?`available actions: ${e}`:e}return null}getTVButtonText(e){return{OK:"OK",BACK:"Back",UP:"Up",DOWN:"Down",LEFT:"Left",RIGHT:"Right",MENU:"Menu"}[e]||e}getCommonTVAction(e){return{activate:"activate",click:"select",toggle:"toggle",expand:"expand",collapse:"collapse",select:"select",play:"play",pause:"pause",stop:"stop",mute:"mute",unmute:"unmute"}[e.toLowerCase()]||null}processAnnouncementText(e){if(!e)return[];if("string"==typeof e&&(e=[e]),!Array.isArray(e))return[];let t=[...e];return this.config.tvOptimized&&(t=this.applyTVOptimizations(t)),t=this.applyVerbosityFilter(t),t=t.map((e=>e.trim())).filter((e=>e.length>0)).map((e=>this.cleanupText(e))),t}applyTVOptimizations(e){return e.map((e=>{let t=e.replace(/\bnavigation\b/gi,"nav").replace(/\bmenuitem\b/gi,"menu").replace(/\btextbox\b/gi,"text field").replace(/\bcombobox\b/gi,"dropdown").replace(/\bcheckbox\b/gi,"check box");return t=t.replace(/\bapplication\b/gi,"").replace(/\bregion\b/gi,"").replace(/\blandmark\b/gi,""),t.trim()}))}applyVerbosityFilter(e){switch(this.config.verbosity){case"concise":return e.slice(0,2);case"detailed":return e;default:return e.slice(0,4)}}cleanupText(e){return e.replace(/\s+/g," ").replace(/[_-]+/g," ").replace(/([a-z])([A-Z])/g,"$1 $2").trim()}processLiveRegionContent(e){const t=this.cleanupText(e);return t.length<3||/^\s*[.!?]*\s*$/.test(t)?null:this.config.tvOptimized?this.applyTVOptimizations([t])[0]:t}queueAnnouncement(e){this.announcementQueue.length>=this.tvTimings.maxQueueSize&&this.announcementQueue.shift(),this.announcementQueue.push(e)}async processQueue(){if(!this.isProcessingQueue&&0!==this.announcementQueue.length){for(this.isProcessingQueue=!0;this.announcementQueue.length>0;){const e=this.announcementQueue.shift();if(e){await this.speakNow(e);const t="assertive"===e.priority?this.tvTimings.priorityDelay:this.tvTimings.politeDelay;await this.delay(t)}}this.isProcessingQueue=!1}}async speakNow(e){const t=Date.now()-this.lastAnnouncementTime;t<this.tvTimings.minInterval&&await this.delay(this.tvTimings.minInterval-t);try{const t=await this.ttsFunction(e.text);return this.lastAnnouncementTime=Date.now(),ne.debug("Announced:",{text:e.text.join(" ").substring(0,100),priority:e.priority,success:t}),t}catch(i){return ne.error("Error speaking announcement:",i),!1}}delay(e){return new Promise((t=>setTimeout(t,e)))}}const se=a("AccessibilityReader");class oe{config;isActive=!1;domMonitor;ariaProcessor;announcementProcessor;currentElement=null;liveRegions=new Map;constructor(e,t,i){this.config={...e},this.ariaProcessor=new ee(e),this.announcementProcessor=new re(e,t,i),this.domMonitor=new ie(e,this.handleFocusChange.bind(this))}async start(){if(this.isActive)return se.debug("Accessibility Reader already active"),!0;try{se.info("Starting Accessibility Reader",this.config),this.config.focusTracking&&await this.domMonitor.startFocusTracking(),this.config.liveRegions&&await this.domMonitor.startLiveRegionMonitoring(this.handleLiveRegionChange.bind(this));const e=document.activeElement;return e&&e!==document.body&&await this.announceElement(e),this.isActive=!0,se.info("Accessibility Reader started successfully"),!0}catch(e){return se.error("Failed to start Accessibility Reader:",e),!1}}async stop(){if(!this.isActive)return se.debug("Accessibility Reader not active"),!0;try{return se.info("Stopping Accessibility Reader"),await this.domMonitor.stop(),this.currentElement=null,this.liveRegions.clear(),this.isActive=!1,se.info("Accessibility Reader stopped"),!0}catch(e){return se.error("Failed to stop Accessibility Reader:",e),!1}}async updateConfig(e){try{const t={...this.config};if(this.config={...this.config,...e},this.ariaProcessor.updateConfig(this.config),this.announcementProcessor.updateConfig(this.config),this.domMonitor.updateConfig(this.config),this.isActive){const e=t.focusTracking!==this.config.focusTracking,i=t.liveRegions!==this.config.liveRegions;(e||i)&&await this.domMonitor.restart()}return se.info("Accessibility Reader configuration updated",this.config),!0}catch(t){return se.error("Failed to update Accessibility Reader config:",t),!1}}getConfig(){return{...this.config}}isReaderActive(){return this.isActive}async announce(e,t="polite"){return this.isActive?await this.announcementProcessor.announce(e,t):(se.debug("Accessibility Reader not active, skipping announcement"),!1)}async stopAnnouncement(){return this.isActive?await this.announcementProcessor.stopAnnouncement():(se.debug("Accessibility Reader not active, skipping stop"),!1)}getCurrentElement(){return this.currentElement}async handleFocusChange(e){var t,i;try{se.debug("Focus changed",{from:null==(t=e.previousElement)?void 0:t.role,to:null==(i=e.currentElement)?void 0:i.role,reason:e.reason}),this.currentElement=e.currentElement||null,e.currentElement&&await this.announcementProcessor.announceFocusChange(e)}catch(n){se.error("Error handling focus change:",n)}}async handleLiveRegionChange(e,t){try{if(se.debug("Live region changed",{politeness:e.politeness,content:t.substring(0,100)}),e.busy)return;const i="assertive"===e.politeness?"assertive":"polite";await this.announcementProcessor.announceLiveRegion(t,i)}catch(i){se.error("Error handling live region change:",i)}}async announceElement(e){try{const t=await this.ariaProcessor.processElement(e);if(t){const e={previousElement:this.currentElement||void 0,currentElement:t,reason:"programmatic"};await this.handleFocusChange(e)}}catch(t){se.error("Error announcing element:",t)}}}class ae{static sanitizeSpeechCues(e){return e.map((e=>this.sanitizeSpeechCue(e)))}static sanitizeSpeechCue(e){return"string"==typeof e?this.sanitizeText(e):{...e,Name:this.sanitizeText(e.Name),Value:e.Value?this.sanitizeText(e.Value):void 0,ItemSubType:e.ItemSubType?this.sanitizeText(e.ItemSubType):void 0,Status:e.Status?this.sanitizeText(e.Status):void 0}}static sanitizeText(e){return e?e.replace(/<[^>]*>/g,"").replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/(javascript|data|vbscript):/gi,"blocked:").replace(/\\{2,}/g,"\\").slice(0,1e3):e}static sanitizeHtml(e){return e.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,"").replace(/on\w+=/gi,"disabled-event=").replace(/allow=/gi,"data-blocked-allow=").replace(/(javascript|data|vbscript):/gi,"blocked:")}static sanitizeInput(e){return e.replace(/[\x00-\x1F\x7F]/g,"").replace(/['"\\]/g,"\\$&").replace(/\0/g,"").slice(0,500)}static checkRateLimit(e,t=10,i=6e4){const n=Date.now();return e.filter((e=>n-e.timestamp<i)).length<t}}const ce=a("PhilipsTTS"),le=e=>e?{available:!0,enabled:"1"===e.setVoiceGuidance,rate:e.speechRate?Number(e.speechRate):1,volume:e.speechVolume?Number(e.speechVolume):1}:T,ue=e=>e?{available:!0,enabled:"on"===e.setTextMagnification,scale:e.fontSizeBase?Number(e.fontSizeBase):1}:E;class de{windowApi;constructor(e){this.windowApi=e||new O}messageToJSON(e){const t=JSON.stringify(e.info).replace(/'/g,"''");return JSON.stringify({...e,info:t})}getSettings(){const e=this.windowApi.get("getDeviceContent");if(!e)return I;const t=e("getVoiceGuidance",!1)??"",i=e("getTextMagnification",!1)??"";try{return{tts:le(this.hexToObject(t)),tm:ue(this.hexToObject(i))}}catch(n){return ce.warn("JSON Parsing Error:",n),I}}sendTTSMessage(e){const t=this.windowApi.get("omi_platform");if(t)try{t.sendPlatformMessage(this.messageToJSON(e))}catch(i){ce.warn("Failed to send platform message:",i)}}startSpeaking(e){const t=ae.sanitizeSpeechCues(e).filter((e=>!(e=>"string"==typeof e?""===e.trim():""===e.Name.trim())(e)));if(0===t.length)return!1;const i=Object.fromEntries(t.map(((e,t)=>[`tts${t+1}`,e])));return this.sendTTSMessage({cmd:"startToSpeak",info:i}),!0}stopSpeaking(){return this.sendTTSMessage({cmd:"stopToSpeak",info:{param1:"false"}}),!0}stopSpeakingButKeepHighlightTask(){this.sendTTSMessage({cmd:"stopSpeakAndKeepInHighlightTask",info:{param1:"false"}})}hexToString(e){var t;return(null==(t=e.match(/.{2}/g))?void 0:t.map((e=>String.fromCharCode(parseInt(e,16)))).join(""))||""}hexToObject(e){if(!e)return null;try{let t=this.hexToString(e).replace(/\\/g,"").trim();t.startsWith('"')&&t.endsWith('"')&&(t=t.slice(1,-1));return JSON.parse(t)}catch(t){return null}}getTTSSettings(){return this.getSettings().tts}getTMSettings(){return this.getSettings().tm}createPlatformEventHandler(e,t){return i=>{try{const r=JSON.parse(i),s=decodeURIComponent(r.data),o=/cmd:\s*'(?<command>[^']+)'\s*,\s*info:\s*'(?<info>[^']+)'\s*;/,a=s.match(o);if(!a||!a.groups)return;if(a.groups.command!==e)return;try{let e=JSON.parse(a.groups.info);"string"==typeof e&&(e=JSON.parse(e)),t(e)}catch(n){ce.warn(`[tts] Could not parse info as JSON: ${n}`)}}catch(r){ce.warn(`[tts] Failed to parse platform event: ${r}`)}}}onTTSSettingsChange(e){var t;const i=this.windowApi.get("omi_platform");if(!i)return()=>{};const n=this.createPlatformEventHandler("VoiceGuidanceNotify",(t=>e(le(t))));return null==(t=i.addPlatformEventListener)||t.call(i,n),()=>{var e;null==(e=i.removePlatformEventListener)||e.call(i,n)}}onTMSettingsChange(e){var t;const i=this.windowApi.get("omi_platform");if(!i)return()=>{};const n=this.createPlatformEventHandler("TextMagnificationNotify",(t=>e(ue(t))));return null==(t=i.addPlatformEventListener)||t.call(i,n),()=>{var e;null==(e=i.removePlatformEventListener)||e.call(i,n)}}}const he=a("AccessibilityService");class ge{tts;reader=null;ttsSettings=T;tmSettings=E;constructor(){this.tts=new de,this.tts.onTTSSettingsChange((e=>{this.ttsSettings=e})),this.tts.onTMSettingsChange((e=>{this.tmSettings=e}))}async startSpeaking(e){if("string"==typeof e&&(e=[e]),await this.isTTSEnabled())try{return this.tts.startSpeaking(e),!0}catch(t){return he.error("Error starting speaking:",t),!1}return!0}async stopSpeaking(){return await this.isTTSEnabled()&&this.tts.stopSpeaking(),!0}async enableReader(e){try{if(!(await this.isTTSSupported()))return he.warn("Cannot enable Reader: TTS not supported"),!1;if(!(await this.isTTSEnabled()))return he.warn("Cannot enable Reader: TTS not enabled"),!1;this.reader=new oe(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(he.info("Reader enabled"),!0)}catch(t){return he.error("Error enabling Reader:",t),!1}}async disableReader(){try{if(this.reader){const e=await this.reader.stop();return this.reader=null,e&&he.info("Reader disabled"),e}return he.debug("Reader was not active"),!0}catch(e){return he.error("Error disabling Reader:",e),!1}}getReader(){if(!this.reader)throw new Error("Reader is not active");return this.reader}async isTTSSupported(){try{return(await this.getTTSSettings()).available}catch(e){return he.error("Error checking TTS support:",e),!1}}async isTextMagnificationSupported(){try{return(await this.getTMSettings()).available}catch(e){return he.error("Error checking magnification support:",e),!1}}onTTSSettingsChange(e){return this.tts.onTTSSettingsChange(e)}onTMSettingsChange(e){return this.tts.onTMSettingsChange(e)}async getTTSSettings(){return this.ttsSettings}async getTMSettings(){return this.tmSettings}async isTTSEnabled(){return(await this.getTTSSettings()).enabled}async isTMEnabled(){return(await this.getTMSettings()).enabled}}class pe{config;waitReady=new Promise((()=>{}));waitReadyResolver;constructor(e){this.config=e,this.waitReady=new Promise((e=>{this.waitReadyResolver=e}))}logError(...e){this.config.debug}}var fe,me={exports:{}};var Se,ve,be=(fe||(fe=1,Se=me,ve=function(){var e=String.fromCharCode,t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",n={};function r(e,t){if(!n[e]){n[e]={};for(var i=0;i<e.length;i++)n[e][e.charAt(i)]=i}return n[e][t]}var s={compressToBase64:function(e){if(null==e)return"";var i=s._compress(e,6,(function(e){return t.charAt(e)}));switch(i.length%4){default:case 0:return i;case 1:return i+"===";case 2:return i+"==";case 3:return i+"="}},decompressFromBase64:function(e){return null==e?"":""==e?null:s._decompress(e.length,32,(function(i){return r(t,e.charAt(i))}))},compressToUTF16:function(t){return null==t?"":s._compress(t,15,(function(t){return e(t+32)}))+" "},decompressFromUTF16:function(e){return null==e?"":""==e?null:s._decompress(e.length,16384,(function(t){return e.charCodeAt(t)-32}))},compressToUint8Array:function(e){for(var t=s.compress(e),i=new Uint8Array(2*t.length),n=0,r=t.length;n<r;n++){var o=t.charCodeAt(n);i[2*n]=o>>>8,i[2*n+1]=o%256}return i},decompressFromUint8Array:function(t){if(null==t)return s.decompress(t);for(var i=new Array(t.length/2),n=0,r=i.length;n<r;n++)i[n]=256*t[2*n]+t[2*n+1];var o=[];return i.forEach((function(t){o.push(e(t))})),s.decompress(o.join(""))},compressToEncodedURIComponent:function(e){return null==e?"":s._compress(e,6,(function(e){return i.charAt(e)}))},decompressFromEncodedURIComponent:function(e){return null==e?"":""==e?null:(e=e.replace(/ /g,"+"),s._decompress(e.length,32,(function(t){return r(i,e.charAt(t))})))},compress:function(t){return s._compress(t,16,(function(t){return e(t)}))},_compress:function(e,t,i){if(null==e)return"";var n,r,s,o={},a={},c="",l="",u="",d=2,h=3,g=2,p=[],f=0,m=0;for(s=0;s<e.length;s+=1)if(c=e.charAt(s),Object.prototype.hasOwnProperty.call(o,c)||(o[c]=h++,a[c]=!0),l=u+c,Object.prototype.hasOwnProperty.call(o,l))u=l;else{if(Object.prototype.hasOwnProperty.call(a,u)){if(u.charCodeAt(0)<256){for(n=0;n<g;n++)f<<=1,m==t-1?(m=0,p.push(i(f)),f=0):m++;for(r=u.charCodeAt(0),n=0;n<8;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1}else{for(r=1,n=0;n<g;n++)f=f<<1|r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r=0;for(r=u.charCodeAt(0),n=0;n<16;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1}0==--d&&(d=Math.pow(2,g),g++),delete a[u]}else for(r=o[u],n=0;n<g;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;0==--d&&(d=Math.pow(2,g),g++),o[l]=h++,u=String(c)}if(""!==u){if(Object.prototype.hasOwnProperty.call(a,u)){if(u.charCodeAt(0)<256){for(n=0;n<g;n++)f<<=1,m==t-1?(m=0,p.push(i(f)),f=0):m++;for(r=u.charCodeAt(0),n=0;n<8;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1}else{for(r=1,n=0;n<g;n++)f=f<<1|r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r=0;for(r=u.charCodeAt(0),n=0;n<16;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1}0==--d&&(d=Math.pow(2,g),g++),delete a[u]}else for(r=o[u],n=0;n<g;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;0==--d&&(d=Math.pow(2,g),g++)}for(r=2,n=0;n<g;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;for(;;){if(f<<=1,m==t-1){p.push(i(f));break}m++}return p.join("")},decompress:function(e){return null==e?"":""==e?null:s._decompress(e.length,32768,(function(t){return e.charCodeAt(t)}))},_decompress:function(t,i,n){var r,s,o,a,c,l,u,d=[],h=4,g=4,p=3,f="",m=[],S={val:n(0),position:i,index:1};for(r=0;r<3;r+=1)d[r]=r;for(o=0,c=Math.pow(2,2),l=1;l!=c;)a=S.val&S.position,S.position>>=1,0==S.position&&(S.position=i,S.val=n(S.index++)),o|=(a>0?1:0)*l,l<<=1;switch(o){case 0:for(o=0,c=Math.pow(2,8),l=1;l!=c;)a=S.val&S.position,S.position>>=1,0==S.position&&(S.position=i,S.val=n(S.index++)),o|=(a>0?1:0)*l,l<<=1;u=e(o);break;case 1:for(o=0,c=Math.pow(2,16),l=1;l!=c;)a=S.val&S.position,S.position>>=1,0==S.position&&(S.position=i,S.val=n(S.index++)),o|=(a>0?1:0)*l,l<<=1;u=e(o);break;case 2:return""}for(d[3]=u,s=u,m.push(u);;){if(S.index>t)return"";for(o=0,c=Math.pow(2,p),l=1;l!=c;)a=S.val&S.position,S.position>>=1,0==S.position&&(S.position=i,S.val=n(S.index++)),o|=(a>0?1:0)*l,l<<=1;switch(u=o){case 0:for(o=0,c=Math.pow(2,8),l=1;l!=c;)a=S.val&S.position,S.position>>=1,0==S.position&&(S.position=i,S.val=n(S.index++)),o|=(a>0?1:0)*l,l<<=1;d[g++]=e(o),u=g-1,h--;break;case 1:for(o=0,c=Math.pow(2,16),l=1;l!=c;)a=S.val&S.position,S.position>>=1,0==S.position&&(S.position=i,S.val=n(S.index++)),o|=(a>0?1:0)*l,l<<=1;d[g++]=e(o),u=g-1,h--;break;case 2:return m.join("")}if(0==h&&(h=Math.pow(2,p),p++),d[u])f=d[u];else{if(u!==g)return null;f=s+s.charAt(0)}m.push(f),d[g++]=s+f.charAt(0),s=f,0==--h&&(h=Math.pow(2,p),p++)}}};return s}(),null!=Se?Se.exports=ve:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",(function(){return ve}))),me.exports);const ye=a("TVPlatform");class we extends pe{DEFAULT_DEVICE_INFO={};bridge;isInitialized=!1;CACHE_KEY="titansdk";CACHE_EXPIRY=6048e5;constructor(e,t){if(super(e),t)this.bridge=t;else{const e={gatewayUrl:this.config.gatewayUrl};this.bridge=new q(e)}this.initializeBridgeSafely()}async initializeBridgeSafely(){try{await this.bridge.initialize()&&(this.isInitialized=!0)}catch(e){ye.warn("Bridge initialization failed:",e)}this.waitReadyResolver(!0)}getFromLocalStorage(){try{if("undefined"==typeof localStorage)return null;if(!localStorage.getItem)return null;const e=localStorage.getItem(this.CACHE_KEY);if(!e)return null;const t=JSON.parse(e);return Date.now()-t.timestamp>this.CACHE_EXPIRY?(localStorage.removeItem(this.CACHE_KEY),null):(ye.debug("Device info loaded from localStorage cache"),t)}catch(e){return ye.warn("Failed to load device info from localStorage:",e),null}}getFromURL(){try{const i=new URLSearchParams(window.location.search).get("titandata");if(!i)return null;let n=null;const r=new O;try{n=be.decompressFromEncodedURIComponent(i),n&&ye.debug("Device info loaded from URL parameter (lz-string)")}catch(e){ye.debug("lz-string decompression failed, trying base64")}if(!n)try{const e=r.get("atob");if(!e)return ye.warn("atob function not available"),null;n=e(decodeURIComponent(i)),ye.debug("Device info loaded from URL parameter (base64)")}catch(t){return ye.warn("Both lz-string and base64 decoding failed"),null}if(!n)return ye.warn("Failed to decode URL parameter"),null;return JSON.parse(n)}catch(i){return ye.warn("Failed to load device info from URL parameter:",i),null}}saveToLocalStorage(e){try{if("undefined"==typeof localStorage)return;if(!(e&&e.deviceId&&e.brand&&e.model))return void ye.warn("Skipping cache save - invalid or empty device info");const t={data:e,timestamp:Date.now()};localStorage.setItem(this.CACHE_KEY,JSON.stringify(t)),ye.debug("Device info saved to localStorage cache")}catch(t){ye.warn("Failed to save device info to localStorage:",t)}}async getBaseDeviceInfo(){const e=this.getFromURL();if(e)return this.saveToLocalStorage(e),this.waitReadyResolver(!0),{deviceInfo:e,tts:T,tm:E};const t=this.getFromLocalStorage();if(t)return this.waitReadyResolver(!0),{deviceInfo:t.data,tts:T,tm:E};try{return await this.waitReady,await this.bridge.executeWithFallback((async()=>{const e=await this.bridge.getDeviceInfo();if(!e)throw new Error("Failed to get device info");return e}),(async()=>{ye.warn("Bridge unavailable, returning fallback device info");return{deviceInfo:null,tts:T,tm:E}}))}catch(i){return ye.warn("Failed to get device info from bridge:",i),{deviceInfo:null,tts:T,tm:E}}}isTV(){return"undefined"!=typeof window&&(navigator.userAgent.includes("TV")||navigator.userAgent.includes("SmartTV")||navigator.userAgent.includes("SMART-TV")||window.location.href.includes("file://"))}}const Te=new O,Ee=new O;function Ie(){const e=document.createElement("video");return e.canPlayType&&"function"==typeof e.canPlayType?{supportAppleHLS:""!==e.canPlayType("application/vnd.apple.mpegURL")||""!==e.canPlayType("audio/mpegurl"),supportMSSmoothStreaming:""!==e.canPlayType("application/vnd.ms-sstr+xml"),supportMSSInitiator:""!==e.canPlayType("application/vnd.ms-playready.initiator+xml"),supportMPEG_DASH:""!==e.canPlayType("application/dash+xml")||"unknown"}:{supportAppleHLS:!1,supportMSSmoothStreaming:!1,supportMSSInitiator:!1,supportMPEG_DASH:"unknown"}}function Ce(){try{if(void 0!==Te.get("oipfObjectFactory"))return{supportOIPF:!0};const e=document.createElement("object");e.type="application/oipfdrmagent";return"function"==typeof e.sendDRMMessage?{supportOIPF:!0}:{supportOIPF:!1}}catch(e){return{supportOIPF:!1}}}function Re(){try{const e=(new O).get("navigator"),t=void 0!==e&&"function"==typeof e.requestMediaKeySystemAccess,i=Ee.has("MSMediaKeys");return{supportWebSocket:Ee.has("WebSocket"),supportEME:t||i,hasStorage:Ee.has("localStorage")&&Ee.has("sessionStorage")}}catch(e){return{supportWebSocket:!1,supportEME:!1,hasStorage:!1}}}const De=new O;function Ae(){let e="";e=function(){try{const e=document.createElement("object");e.type="application/oipfdrmagent";return"function"==typeof e.sendDRMMessage?"OIPF":""}catch(e){return""}}();try{const t=De.has("MediaKeys"),i=De.has("WebKitMediaKeys"),n=De.has("MSMediaKeys");return e=t||i||n?"EME":e,{drmMethod:e}}catch(t){return{drmMethod:""}}}function Pe(){try{const e=De.has("MediaKeys"),t=De.has("WebKitMediaKeys"),i=De.has("MSMediaKeys");return{supportEME:e||t||i}}catch(e){return{supportEME:!1}}}const ke=a("PhilipsCapabilities");async function Me(){const e={os:"Linux",browserEngine:"Blink",supportPlayready:!0===await function(){const e=[{initDataTypes:["cenc"],audioCapabilities:[{contentType:'audio/mp4;codecs="mp4a.40.2"'}],videoCapabilities:[{contentType:'video/mp4;codecs="avc1.42E01E"'}]}];return new Promise((t=>{try{navigator.requestMediaKeySystemAccess("com.microsoft.playready",e).then((()=>{t(!0)})).catch((()=>{t(!1)}))}catch(i){t(!1)}}))}()||"unknown",supportWidevineModular:!0===await function(){const e=[{initDataTypes:["cenc"],audioCapabilities:[{contentType:'audio/mp4;codecs="mp4a.40.2"'}],videoCapabilities:[{contentType:'video/mp4;codecs="avc1.42E01E"'}]}];return new Promise((t=>{try{navigator.requestMediaKeySystemAccess("com.widevine.alpha",e).then((()=>{t(!0)})).catch((()=>{t(!1)}))}catch(i){t(!1)}}))}()||"unknown"},t=function(){try{const e={support3d:!1,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportUHD:!1,supportFHD:!1,supportHDR_HDR10:!1,supportHDR_DV:!1,supportHDR:"unknown",supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportAdobeHDS:"unknown",supportWidevineClassic:"unknown",supportDolbyAtmos:"unknown"},t=Ne.get("ols3DSupport");t&&t()&&(e.support3d=!0),e.supportKeyNumeric=!0,e.supportKeyColor=!0,e.supportMultiscreen=!1,e.supportMultiAudio=!0,e.supportTTMLInband=!0,e.supportTTMLOutofband=!0,e.supportFHD=!0;const i=Ne.get("olsUHD"),n=Ne.get("olsDVSupport"),r=i&&i(),s=n&&n();!0===r?(e.supportUHD=!0,e.supportHDR_HDR10=!0,e.supportHDR_DV=!!s,e.supportHDR_HDR10||e.supportHDR_DV?e.supportHDR=!0:e.supportHDR=!1):!1===r?(e.supportUHD=!1,e.supportHDR_HDR10=!1,e.supportHDR_DV=!1,e.supportHDR=!1):(e.supportUHD=!1,e.supportHDR_HDR10=!1,e.supportHDR_DV=!1,e.supportHDR="unknown");const o=Ne.get("olsAtmosSupport");return e.supportDolbyAtmos="function"==typeof o?o():"function"==typeof n?n():"unknown",e}catch(e){return ke.error("Error detecting SmartTV API capabilities:",e),{support3d:!1,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportUHD:!1,supportFHD:!1,supportHDR_HDR10:!1,supportHDR_DV:!1,supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportAdobeHDS:"unknown",supportHDR:"unknown",supportWidevineClassic:"unknown",supportDolbyAtmos:"unknown"}}}();return{...e,...t,...Re(),...Ie(),...Ae(),...Pe(),...Ce()}}const Ne=new O;const _e=a("PhilipsCompat");class Oe extends we{deviceInfo=null;deviceInfoPromise=null;DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"TPV",brand:"Philips"},Product:{platform:"TitanOS",year:"2025",deviceID:"philips-device",firmwareVersion:"1.0.0",firmwareComponentID:"",mac:"",WhaleAdID:x(),language:"en"}};constructor(e,t){super(e,t)}async isSupported(){return this.isTV()}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent.toLowerCase();return["philips","saphi","nettv","tpvision"].some((t=>e.includes(t)))}async getDeviceInfo(){if(this.deviceInfo)return this.deviceInfo;if(this.deviceInfoPromise)return await this.deviceInfoPromise;this.deviceInfoPromise=this.fetchDeviceInfoInternal();try{const e=await this.deviceInfoPromise;return this.deviceInfo=e,e}catch(e){throw this.deviceInfoPromise=null,e}}async fetchDeviceInfoInternal(){try{const e=await Me(),t={...this.DEFAULT_DEVICE_INFO,Capability:e},i=await this.getBaseDeviceInfo();return this.formatBridgeResponse(i,t)}catch(e){throw _e.error("Error getting device info:",e),e}}formatBridgeResponse(e,t){if(!e.deviceInfo)return t;let i=e.deviceInfo.platformName;e.deviceInfo.profileId&&(i=(e.deviceInfo.profileId.split("_")[1]||i).replace(/\d+$/,""));return t.Product.firmwareVersion=e.deviceInfo.firmwareVersion,t.Product.country=e.deviceInfo.country,t.Product.deviceID=e.deviceInfo.deviceId,t.Product.platform=i,t.Product.language=e.deviceInfo.language,t.Product.mac=e.deviceInfo.mac,t.Product.ifa=e.deviceInfo.ifa||"",t.Product.ifaType=e.deviceInfo.ifaType||"",t.Product.year=e.deviceInfo.year||"",t.Product.firmwareComponentID=i||"",t}getPriority(){return 100}getId(){return"philips"}}const Le=a("PhilipsDeviceInfoService");class xe{platform;info;bridge;constructor(e,t){this.platform=new Oe(e,t),this.bridge=t,this.info=null}async getDeviceInfo(){try{const e=await this.platform.getDeviceInfo();return this.info=e,this.info}catch(e){throw Le.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const He=a("PhilipsAppControlService");class Ue{bridge;constructor(e){this.bridge=e}async launch(e,t){return await this.bridge.executeWithFallback((()=>this.bridge.launchApp({appId:e,deepLink:t})),(async()=>(He.warn("Function unavailable, app launch failed gracefully",{appId:e,deepLink:t}),!1)))}}const Fe=a("ChromeTTS");class Be{voices=[];currentVoice=null;settings={available:!0,enabled:!0,rate:1,volume:1};speechSynthesis;constructor(){const e=new O;this.speechSynthesis=e.get("speechSynthesis"),this.speechSynthesis&&(this.initVoices(),"onvoiceschanged"in this.speechSynthesis&&(this.speechSynthesis.onvoiceschanged=()=>{this.initVoices()}))}initVoices(){var e,t,i,n,r,s;if(!("speechSynthesis"in window))return;const o=null==(e=this.speechSynthesis)?void 0:e.getVoices();this.voices=null==o?void 0:o.map((e=>({voiceName:e.name,lang:e.lang,gender:e.name.toLowerCase().includes("female")?"female":"male",remote:!1===e.localService}))),this.currentVoice=(null==(t=this.voices)?void 0:t.find((e=>"en-GB"===e.lang)))||(null==(i=this.voices)?void 0:i.find((e=>e.lang.startsWith("en-"))))||(null==(n=this.voices)?void 0:n[0]),Fe.info(`Initialized with ${null==(r=this.voices)?void 0:r.length} voices, using ${null==(s=this.currentVoice)?void 0:s.voiceName}`)}getTTSSettings(){return this.settings}getTMSettings(){return{available:!0,enabled:!1,scale:1}}getSettings(){return{tts:this.getTTSSettings(),tm:this.getTMSettings()}}startSpeaking(e){return Fe.info("Starting speaking:",e),!(!("speechSynthesis"in window)||!e||0===e.length)&&(e.forEach(((e,t)=>{var i,n,r,s;if(!e)return;const o=new SpeechSynthesisUtterance(e);if(o.rate=this.settings.rate??1,o.volume=this.settings.volume??1,o.lang=(null==(i=this.currentVoice)?void 0:i.lang)??"en-GB",this.currentVoice){const e=null==(n=this.speechSynthesis)?void 0:n.getVoices().find((e=>e.name===this.currentVoice.voiceName));e&&(o.voice=e)}0===t&&(null==(r=this.speechSynthesis)||r.cancel()),null==(s=this.speechSynthesis)||s.speak(o)})),!0)}stopSpeaking(){var e;return"speechSynthesis"in window&&(null==(e=this.speechSynthesis)||e.cancel(),!0)}stopSpeakingButKeepHighlightTask(){this.stopSpeaking()}onTTSSettingsChange(e){return()=>{}}onTMSettingsChange(e){return()=>{}}sendTTSMessage(e){}}const Ve=a("VestelTTS"),ze=e=>({available:!0,enabled:e.enabled,rate:e.rate,pitch:e.pitch,volume:e.level});class Ke extends Be{vestelSettings={available:!0,enabled:!1,rate:1,volume:1};windowApi=new O;ttsCallbacks=new Set;tmCallbacks=new Set;settingsInitialized=!1;constructor(){super(),this.initializeSettings()}async initializeSettings(){var e,t;const i=this.windowApi.get("TTSHelper");if(!i)return void Ve.warn("TTSHelper not available during initialization");const n={onSuccess:e=>{this.vestelSettings=ze(e),this.settingsInitialized=!0},onError:e=>{Ve.error("Error initializing TTS settings:",e),this.settingsInitialized=!0}},r={onSuccess:e=>{this.vestelSettings=ze(e)},onError:e=>{Ve.error("Error getting TTS info:",e)}};null==(e=i.getTextToSpeechSettings)||e.call(i,n,!1),null==(t=i.getTTSInfo)||t.call(i,r)}getTTSSettings(){var e;if(!this.settingsInitialized){const t=this.windowApi.get("TTSHelper");if(t){const i={onSuccess:e=>{Ve.info("Current TTS settings:",e,e.toString()),this.vestelSettings=ze(e)},onError:e=>{Ve.error("Error getting current TTS settings:",e)}};null==(e=t.getTextToSpeechSettings)||e.call(t,i,!1)}}return this.vestelSettings}getTMSettings(){return{available:this.getTTSSettings().available,enabled:!1,scale:1}}getSettings(){return{tts:this.getTTSSettings(),tm:this.getTMSettings()}}stopSpeakingButKeepHighlightTask(){this.stopSpeaking()}onTTSSettingsChange(e){var t;const i=this.windowApi.get("TTSHelper");if(!i)return Ve.warn("TTSHelper not available"),()=>{};const n={onSuccess:t=>{Ve.info("TTS settings changed:",t,t.toString()),e(ze(t)),this.settingsInitialized=!0},onError:e=>{Ve.error("Error getting TTS settings:",e)}};return this.ttsCallbacks.add(n),null==(t=i.getTextToSpeechSettings)||t.call(i,n,!0),()=>{var e;i&&this.ttsCallbacks.has(n)&&(null==(e=i.unsubscribe)||e.call(i,n),this.ttsCallbacks.delete(n))}}onTMSettingsChange(e){this.tmCallbacks.add(e);const t=this.onTTSSettingsChange((t=>{const i={available:t.available,enabled:!1,scale:1};e(i)})),i=this.getTMSettings();return e(i),()=>{this.tmCallbacks.delete(e),t()}}destroy(){const e=this.windowApi.get("TTSHelper");e&&this.ttsCallbacks.forEach((t=>{var i;null==(i=e.unsubscribe)||i.call(e,t)})),this.ttsCallbacks.clear(),this.tmCallbacks.clear()}}const $e=a("AccessibilityService"),Ge=e=>{const{available:t,...i}=e;return i};class We{tts;reader=null;constructor(){this.tts=new Ke}async startSpeaking(e){if("string"==typeof e&&(e=[e]),await this.isTTSEnabled())try{return this.tts.startSpeaking(e),!0}catch(t){return $e.error("Error starting speaking:",t),!1}return!1}async stopSpeaking(){return await this.isTTSEnabled()&&this.tts.stopSpeaking(),!0}async enableReader(e){try{if(!(await this.isTTSSupported()))return $e.warn("Cannot enable Reader: TTS not supported"),!1;if(!(await this.isTTSEnabled()))return $e.warn("Cannot enable Reader: TTS not enabled"),!1;this.reader=new oe(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&($e.info("Reader enabled"),!0)}catch(t){return $e.error("Error enabling Reader:",t),!1}}async disableReader(){try{if(this.reader){const e=await this.reader.stop();return this.reader=null,e&&$e.info("Reader disabled"),e}return $e.debug("Reader was not active"),!0}catch(e){return $e.error("Error disabling Reader:",e),!1}}getReader(){if(!this.reader)throw new Error("Reader is not active");return this.reader}async isTTSSupported(){try{return(await this.getTTSSettings()).available}catch(e){return $e.error("Error checking TTS support:",e),!1}}async isTextMagnificationSupported(){try{return(await this.getTMSettings()).available}catch(e){return $e.error("Error checking magnification support:",e),!1}}onTTSSettingsChange(e){return this.tts.onTTSSettingsChange(e)}onTMSettingsChange(e){return this.tts.onTMSettingsChange(e)}async getTTSSettings(){return this.tts.getTTSSettings()}async getTMSettings(){return this.tts.getTMSettings()}async isTTSEnabled(){return(await this.getTTSSettings()).enabled}async isTMEnabled(){return(await this.getTMSettings()).enabled}}class je{subscribe(e,t){const i=c(e,t);return()=>{l(i)}}getHistory(){return u()}clear(){d()}}const qe=a("PhilipsSDK");class Qe{bridge;accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new ge,this.bridge=new Y({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug}),this.deviceInfoService=new xe(e,this.bridge),this.appControlService=new Ue(this.bridge)}deviceInfo={getDeviceInfo:()=>this.deviceInfoService.getDeviceInfo(),getCapabilities:()=>this.deviceInfoService.getCapabilities()};accessibility={enableReader:e=>this.accessibilityService.enableReader(e),disableReader:()=>this.accessibilityService.disableReader(),isTTSSupported:()=>this.accessibilityService.isTTSSupported(),isTTSEnabled:()=>this.accessibilityService.isTTSEnabled(),isTMEnabled:()=>this.accessibilityService.isTMEnabled(),isTextMagnificationSupported:()=>this.accessibilityService.isTextMagnificationSupported(),getTTSSettings:async()=>Ge(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>Ge(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange((t=>{e(Ge(t))})),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange((t=>{e(Ge(t))}))};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new je}get dev(){return{isBridgeConnected:async()=>{try{return this.bridge.isConnected()}catch(e){return!1}}}}async init(){try{return await this.deviceInfo.getDeviceInfo(),!0}catch(e){throw qe.error("TitanSDK initialization failed:",e),e}}}function Je(){return{os:"Linux",browserEngine:"Blink",hasStorage:!0,support3d:!1,supportUHD:!0,supportFHD:!1,supportHDR:!0,supportHDR_HDR10:!0,supportHDR_DV:!0,supportWebSocket:!0,supportPlayready:!0,supportWidevineModular:!0,supportAppleHLS:!0,supportMSSmoothStreaming:!1,supportMSSInitiator:!1,supportMPEG_DASH:!0,drmMethod:"widevine",supportOIPF:!1,supportEME:!0,supportFairplay:!1,supportAdobeHDS:!1,supportPrimetime:!1,supportClearKey:!0,supportWidevineClassic:!0,supportDolbyAtmos:!0,supportMultiscreen:!0,supportMultiAudio:!0,supportTTMLInband:!0,supportTTMLOutofband:!0,...function(){var e;try{const t=document.createElement("object");t.setAttribute("id","sysinfo"),t.setAttribute("type","systeminfoobject"),document.body.appendChild(t);const i=t,n={support3d:Boolean(i.has3D),supportUHD:(null==(e=i.panelinfo)?void 0:e.toLowerCase().includes("uhd"))||!1};return{...n,supportFHD:!n.supportUHD}}catch(t){return{support3d:!1,supportUHD:!1,supportFHD:!0}}}(),...Re(),...Ie(),...Ae(),...Pe(),...Ce()}}const Ye=a("VestelCompat");class Ze extends we{deviceInfo=null;deviceInfoPromise=null;DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"Vestel",brand:"JVC"},Product:{platform:"TitanOS",year:"2025",deviceID:"vestel-device",firmwareVersion:"1.0.0",firmwareComponentID:"",mac:"",WhaleAdID:x(),language:"en"}};constructor(e,t){super(e,t)}async isSupported(){return this.isTV()}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent.toLowerCase();return["vestel"].some((t=>e.includes(t)))}async getDeviceInfo(){if(this.deviceInfo)return this.deviceInfo;if(this.deviceInfoPromise)return await this.deviceInfoPromise;this.deviceInfoPromise=this.fetchDeviceInfoInternal();try{const e=await this.deviceInfoPromise;return this.deviceInfo=e,e}catch(e){throw this.deviceInfoPromise=null,e}}async fetchDeviceInfoInternal(){try{const e=Je(),t={...this.DEFAULT_DEVICE_INFO,Capability:e};if(await this.waitReady){const e=await this.getBaseDeviceInfo();return this.formatBridgeResponse(e,t)}return t}catch(e){throw Ye.error("Error getting device info:",e),e}}formatBridgeResponse(e,t){return e.deviceInfo?(t.Product.firmwareVersion=e.deviceInfo.firmwareVersion,t.Product.country=e.deviceInfo.country.toUpperCase(),t.Product.deviceID=e.deviceInfo.deviceId,t.Product.platform=e.deviceInfo.model,t.Product.ifa=e.deviceInfo.ifa||"",t.Product.ifaType=e.deviceInfo.ifaType||"",t.Product.mac=e.deviceInfo.mac,t.Product.year=e.deviceInfo.year||"",t):t}getPriority(){return 90}getId(){return"vestel"}}const Xe=a("VestelDeviceInfoService");class et{platform;info;bridge;constructor(e,t){this.platform=new Ze(e,t),this.bridge=t,this.info=null}async getDeviceInfo(){try{const e=await this.platform.getDeviceInfo();return this.info=e,this.info}catch(e){throw Xe.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const tt=a("VestelAppControlService");class it{bridge;constructor(e){this.bridge=e}async launch(e,t){return await this.bridge.executeWithFallback((()=>this.bridge.launchApp({appId:e,deepLink:t})),(async()=>(tt.warn("Function unavailable, app launch failed gracefully",{appId:e,deepLink:t}),!1)))}}const nt=a("VestelSDK");class rt{bridge;accessibilityService;deviceInfoService;appControlService;constructor(e){this.bridge=new Q({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug}),this.accessibilityService=new We,this.deviceInfoService=new et(e,this.bridge),this.appControlService=new it(this.bridge)}deviceInfo={getDeviceInfo:()=>this.deviceInfoService.getDeviceInfo(),getCapabilities:()=>this.deviceInfoService.getCapabilities()};accessibility={enableReader:e=>this.accessibilityService.enableReader(e),disableReader:()=>this.accessibilityService.disableReader(),isTTSSupported:()=>this.accessibilityService.isTTSSupported(),isTextMagnificationSupported:()=>this.accessibilityService.isTextMagnificationSupported(),isTTSEnabled:()=>this.accessibilityService.isTTSEnabled(),isTMEnabled:()=>this.accessibilityService.isTMEnabled(),getTTSSettings:async()=>Ge(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>Ge(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange((t=>{e(Ge(t))})),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange((t=>{e(Ge(t))}))};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new je}get dev(){return{isBridgeConnected:async()=>{try{return this.bridge.isConnected()}catch(e){return!1}}}}async init(){try{return await this.deviceInfo.getDeviceInfo(),!0}catch(e){throw nt.error("TitanSDK initialization failed:",e),e}}}const st="titanSDK_tts_settings",ot="titanSDK_tm_settings",at=a("BrowserAccessibilityService"),ct=e=>{const{available:t,...i}=e;return i};class lt{reader=null;chromeTTS;windowMock;mockStorage;ttsSettings;tmSettings;constructor(e,t,i=!1){this.windowMock=e,this.mockStorage=t,this.chromeTTS=new Be,this.ttsSettings=this.loadTTSSettings(),this.tmSettings=this.loadTMSettings()}loadTTSSettings(){try{const e=localStorage.getItem(st);if(e)return{...this.getDefaultTTSSettings(),...JSON.parse(e)}}catch(e){}return this.getDefaultTTSSettings()}loadTMSettings(){try{const e=localStorage.getItem(ot);if(e)return{...this.getDefaultTMSettings(),...JSON.parse(e)}}catch(e){}return this.getDefaultTMSettings()}getDefaultTTSSettings(){return{available:!0,enabled:!0,rate:1,volume:1}}getDefaultTMSettings(){return{available:!0,enabled:!1,scale:1}}saveTTSSettings(){try{localStorage.setItem(st,JSON.stringify(this.ttsSettings))}catch(e){}}saveTMSettings(){try{localStorage.setItem(ot,JSON.stringify(this.tmSettings))}catch(e){}}async startSpeaking(e){try{if(!this.ttsSettings.enabled)return at.info("TTS is disabled in settings"),!1;const t=Array.isArray(e)?e.join(" "):e,i=this.chromeTTS.startSpeaking([t]);return i&&at.info("🔊 Speaking:",t),i}catch(t){return at.error("Error starting speech:",t),!1}}async stopSpeaking(){try{const e=this.chromeTTS.stopSpeaking();return e&&at.info("🔇 Speech stopped"),e}catch(e){return at.error("Error stopping speech:",e),!1}}async enableReader(e){try{if(!(await this.isTTSSupported()))return at.warn("Cannot enable Reader: TTS not supported"),!1;this.reader=new oe(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(at.info("Reader enabled"),!0)}catch(t){return at.error("Error enabling Reader:",t),!1}}async disableReader(){try{return!!this.reader&&(await this.reader.stop(),this.reader=null,at.info("Reader disabled"),!0)}catch(e){return at.error("Error disabling Reader:",e),!1}}getReader(){return this.reader}async isTTSSupported(){var e,t;return void 0!==(null==(t=null==(e=this.mockStorage)?void 0:e.features)?void 0:t.tts)?this.mockStorage.features.tts:"undefined"!=typeof window&&"speechSynthesis"in window}async isTextMagnificationSupported(){var e,t;return void 0===(null==(t=null==(e=this.mockStorage)?void 0:e.features)?void 0:t.magnification)||this.mockStorage.features.magnification}onTTSSettingsChange(e){return()=>{}}onTMSettingsChange(e){return()=>{}}async getTTSSettings(){return{...this.ttsSettings}}async getTMSettings(){return{...this.tmSettings}}async isTTSEnabled(){const e=await this.getTTSSettings();return e.available&&e.enabled}async isTMEnabled(){const e=await this.getTMSettings();return e.available&&e.enabled}updateTTSSettings(e){this.ttsSettings={...this.ttsSettings,...e},this.saveTTSSettings(),at.info("TTS settings updated:",this.ttsSettings)}updateTMSettings(e){this.tmSettings={...this.tmSettings,...e},this.saveTMSettings(),at.info("TM settings updated:",this.tmSettings)}}const ut=a("BrowserPlatform");class dt extends pe{constructor(e){super(e),this.waitReady=new Promise((e=>{this.waitReadyResolver=e})),this.waitReadyResolver(!0)}async isSupported(){return!0}async canHandle(){return!0}async getDeviceInfo(){return ut.debug("Getting default device info for browser"),this.getDefaultDeviceInfo()}getDefaultDeviceInfo(){return{Channel:{appStore:"browser",vendor:"browser",brand:"browser"},Product:{platform:"browser",year:(new Date).getFullYear().toString(),deviceID:"browser-"+Math.random().toString(36).substring(2,10),firmwareVersion:"unknown",firmwareComponentID:"unknown",mac:"unknown"},Capability:{os:(null==navigator?void 0:navigator.platform)||"unknown",browserEngine:this.detectBrowserEngine(),hasStorage:this.hasLocalStorage(),support3d:!1,supportUHD:!1,supportHDR:!1,supportWebSocket:"WebSocket"in window,supportPlayready:!1,supportWidevineModular:!1,supportAppleHLS:!1,supportMSSmoothStreaming:!1,supportMSSInitiator:!1,supportMPEG_DASH:!1,drmMethod:"",supportOIPF:!1,supportEME:"mediaKeys"in Document.prototype}}}detectBrowserEngine(){const e=navigator.userAgent;return e.includes("Chrome")?"Blink":e.includes("Firefox")?"Gecko":e.includes("Safari")?"WebKit":e.includes("Edge")?"EdgeHTML":e.includes("Trident")?"Trident":"unknown"}hasLocalStorage(){try{return"localStorage"in window&&null!==window.localStorage}catch(e){return!1}}getPriority(){return 10}getId(){return"browser"}}const ht=a("BrowserDeviceInfoService");class gt{platform;info;options;constructor(e,t,i){this.options=e,this.info=null;const n={debug:null==e?void 0:e.debug,timeout:(null==e?void 0:e.legacyDeviceInfoTimeout)||5e3,gatewayUrl:null==e?void 0:e.gatewayUrl,useCache:!0};this.platform=new dt(n)}async getDeviceInfo(){try{const e=await this.platform.getDeviceInfo();return this.info=e,this.info}catch(e){throw ht.error("Error getting device info:",e),e}}async getCapabilities(){try{return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}catch(e){throw ht.error("Error getting device capabilities:",e),e}}}const pt=a("BrowserAppControlService");class ft{windowMock;constructor(e){this.windowMock=e}async launch(e,t){pt.debug(`Launching app: ${e} with deepLink: ${t||"none"}`);const i=this.windowMock||window;if(!i||"function"!=typeof i.open)throw new r("Cannot open new window for app launch (window.open not available)",n.NOT_SUPPORTED,{operation:"launch",appId:e,deepLink:t,platform:"browser"});try{return i.open(t||e,"_blank"),pt.info(`Opened new tab for app: ${e}`),!0}catch(s){throw pt.error("Error opening new window for app launch:",s),new r(`Failed to launch app: ${e}`,n.COMMUNICATION_ERROR,{operation:"launch",appId:e,deepLink:t,platform:"browser",originalError:s})}}}const mt=a("BrowserSDK");class St{accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new lt(null==e?void 0:e.windowMock,null==e?void 0:e.mockStorage,(null==e?void 0:e.dev)||!1),this.deviceInfoService=new gt(e,null==e?void 0:e.windowMock,null==e?void 0:e.mockStorage),this.appControlService=new ft(null==e?void 0:e.windowMock),"undefined"!=typeof window&&Object.defineProperty(window,"titanSDK",{value:this,writable:!0,configurable:!0}),(null==e?void 0:e.debug)&&mt.debug("BrowserSDK constructor finished")}deviceInfo={getDeviceInfo:()=>this.deviceInfoService.getDeviceInfo(),getCapabilities:()=>this.deviceInfoService.getCapabilities()};accessibility={enableReader:e=>this.accessibilityService.enableReader(e),disableReader:()=>this.accessibilityService.disableReader(),isTTSSupported:()=>this.accessibilityService.isTTSSupported(),isTTSEnabled:()=>this.accessibilityService.isTTSEnabled(),isTMEnabled:()=>this.accessibilityService.isTMEnabled(),isTextMagnificationSupported:()=>this.accessibilityService.isTextMagnificationSupported(),getTTSSettings:async()=>ct(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>ct(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange((t=>{e(ct(t))})),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange((t=>{e(ct(t))}))};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new je}get dev(){return{updateTTSSettings:e=>{this.accessibilityService.updateTTSSettings(e)},updateTMSettings:e=>{this.accessibilityService.updateTMSettings(e)}}}async init(){try{return mt.debug("BrowserSDK initialization started"),mt.info("BrowserSDK initialized successfully"),!0}catch(e){throw mt.error("BrowserSDK initialization failed:",e),e}}}const vt=a("AccessibilityService"),bt=e=>{const{available:t,...i}=e;return i};class yt{reader=null;async startSpeaking(e){return!1}async stopSpeaking(){return!1}async enableReader(e){return vt.warn("Cannot enable Reader: TTS not supported"),!1}async disableReader(){return!1}getReader(){return null}async isTTSSupported(){return!1}async isTextMagnificationSupported(){return!1}onTTSSettingsChange(e){return()=>{}}onTMSettingsChange(e){return()=>{}}async getTTSSettings(){return T}async getTMSettings(){return E}async isTTSEnabled(){return!1}async isTMEnabled(){return!1}}const wt=a("PhilipsOldPlatform");class Tt extends pe{deviceInfo=null;deviceInfoPromise=null;timeout=7e3;DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"TPV",brand:"Philips"},Product:{platform:"TitanOS",year:"2023",deviceID:"philips-device",firmwareVersion:"1.0.0",firmwareComponentID:"",mac:"",WhaleAdID:x(),language:"en"}};constructor(e){super(e),this.waitReady=new Promise((e=>{this.waitReadyResolver=e})),this.waitReadyResolver(!0)}async isSupported(){return"undefined"!=typeof window&&(navigator.userAgent.includes("TV")||navigator.userAgent.includes("SmartTV")||navigator.userAgent.includes("SMART-TV")||window.location.href.includes("file://"))}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent.toLowerCase();return["philips","saphi","nettv","tpvision"].some((t=>e.includes(t)))}async getDeviceInfo(){if(this.deviceInfo)return this.deviceInfo;if(this.deviceInfoPromise)return await this.deviceInfoPromise;this.deviceInfoPromise=this.fetchDeviceInfoInternal();try{const e=await this.deviceInfoPromise;return this.deviceInfo=e,e}catch(e){throw this.deviceInfoPromise=null,e}}async fetchDeviceInfoInternal(){var e;try{const t=new O,i=await Me(),n={...this.DEFAULT_DEVICE_INFO,Capability:i,supportDolbyAtmos:(null==(e=t.get("olsDVSupport"))?void 0:e())||!1};if(await this.waitReady){const e=await this.fetchDeviceInfo();return e?this.formatBridgeResponse({deviceInfo:e,tts:T,tm:E},n):n}return n}catch(t){throw wt.warn("Error getting device info:",t),t}}async fetchDeviceInfo(){var e;try{const t="app.titanos.tv",i=await Promise.race([L(0,t,"zeasn"),new Promise((e=>{setTimeout((()=>{wt.warn("Zeasn backend device info request timed out"),e(null)}),this.timeout)}))]);if(!i||!(null==(e=i.datas)?void 0:e.cookies))return null;const n=i.datas.cookies.profileid;return{profileId:n,deviceId:decodeURIComponent(i.datas.cookies.deviceid||""),model:i.datas.cookies.deviceYear||"",year:i.datas.cookies.deviceYear||"",firmwareVersion:i.datas.cookies.ufversion||"",country:i.datas.cookies.country||"",language:F("en"),brand:_.PHILIPS,platformName:_.PHILIPS,mac:decodeURIComponent(i.datas.cookies.mac||""),ifa:"",ifaType:""}}catch(t){return wt.warn("Error fetching device info from backend",t),null}}formatBridgeResponse(e,t){let i="TitanOS",n="unknown";if(!e.deviceInfo)return t;if(e.deviceInfo.profileId&&(i=e.deviceInfo.platformName,e.deviceInfo.profileId)){var r=e.deviceInfo.profileId.split("_");i=(r[1]||i).replace(/\d+$/,""),n=r[1]?decodeURIComponent(r[1]):"unknown"}return t.Product.firmwareVersion=e.deviceInfo.firmwareVersion,t.Product.country=e.deviceInfo.country,t.Product.deviceID=e.deviceInfo.deviceId,t.Product.platform=i,t.Product.language=e.deviceInfo.language,t.Product.mac=e.deviceInfo.mac,t.Product.ifa=e.deviceInfo.ifa||"",t.Product.ifaType=e.deviceInfo.ifaType||"",t.Product.year=e.deviceInfo.year||"",t.Product.firmwareComponentID=n,t}getPriority(){return 100}getId(){return"philips"}}class Et{platform;info;constructor(e){this.platform=new Tt(e),this.info=null}async getDeviceInfo(){const e=await this.platform.getDeviceInfo();return this.info=e,this.info}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}class It{async launch(e,t){return!1}}class Ct{accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new yt,this.deviceInfoService=new Et(e),this.appControlService=new It}deviceInfo={getDeviceInfo:()=>this.deviceInfoService.getDeviceInfo(),getCapabilities:()=>this.deviceInfoService.getCapabilities()};accessibility={enableReader:e=>this.accessibilityService.enableReader(e),disableReader:()=>this.accessibilityService.disableReader(),isTTSSupported:()=>this.accessibilityService.isTTSSupported(),isTTSEnabled:()=>this.accessibilityService.isTTSEnabled(),isTMEnabled:()=>this.accessibilityService.isTMEnabled(),isTextMagnificationSupported:()=>this.accessibilityService.isTextMagnificationSupported(),getTTSSettings:async()=>bt(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>bt(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>()=>{},onTMSettingsChange:e=>()=>{}};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new je}async init(){return!0}}const Rt=a("RollbarClient"),Dt=["chrome://userjs/","chrome-extension://","moz-extension://","getJWTString","getjwtstring","user.js","userscript","tampermonkey","greasemonkey","can't find variable getjwtstring","referenceerror: can't find variable: getjwtstring","unexpected end of json input","jsonparse"];const At=new class{rollbar=null;config=null;windowWrapper=new O;initialize(e){if(e.enabled&&e.accessToken)try{this.config=e,this.rollbar=new t({accessToken:e.accessToken,environment:e.environment||"development",captureUncaught:!0,captureUnhandledRejections:!0,verbose:!1,reportLevel:"error",captureIp:!1,captureUsername:!1,captureEmail:!1,maxItems:100,itemsPerMinute:60,captureLambdaTimeouts:!1,endpoint:"https://sdk.titanos.tv/logs/",autoInstrument:{network:!1,log:!1,dom:!1,navigation:!1,connectivity:!1},payload:{client:{javascript:{code_version:"unknown",source_map_enabled:!0}}},transform:e=>{e.context&&(e.context=`hephaestus-${e.context}`)},checkIgnore:(e,t,i)=>{const n=t[0],r="string"==typeof n?n:null==n?void 0:n.message,s="object"==typeof n&&n?n.stack:"",o=String(n).toLowerCase();return Dt.some((e=>(null==r?void 0:r.toLowerCase().includes(e.toLowerCase()))||(null==s?void 0:s.toLowerCase().includes(e.toLowerCase()))||o.includes(e.toLowerCase())))}}),this.setupGlobalErrorHandlers(),Rt.info("Rollbar initialized successfully",{environment:e.environment})}catch(i){Rt.error("Failed to initialize Rollbar",{error:i,config:e})}else Rt.warn("Rollbar not initialized - disabled or missing access token")}shouldIgnoreError(e){if(!e)return!0;const t="string"==typeof e?e:e.message||"",i="object"==typeof e&&e.stack||"",n=String(e).toLowerCase();return Dt.some((e=>(null==t?void 0:t.toLowerCase().includes(e.toLowerCase()))||(null==i?void 0:i.toLowerCase().includes(e.toLowerCase()))||n.includes(e.toLowerCase())))}async reportError(e,t,i="error"){var n;return this.rollbar&&(null==(n=this.config)?void 0:n.enabled)&&e?this.shouldIgnoreError(e)?Promise.resolve(null):new Promise((n=>{this.getDeviceContext().then((r=>{var s,o,a;try{const c=u().filter((e=>!e.module.includes("RollbarClient")&&!e.message.includes("Rollbar")&&"debug"!==e.level)).slice(-20),l={logs:c.map((e=>`[${e.timestamp}] ${e.module}: ${e.message}${e.args&&e.args.length>0?"\n Args: "+JSON.stringify(e.args):""}`)).join("\n"),component:(null==t?void 0:t.component)||"SDK",operation:null==t?void 0:t.operation,requestId:null==t?void 0:t.requestId,timestamp:Date.now(),url:"undefined"!=typeof window?null==(s=window.location)?void 0:s.href:void 0,userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",sessionId:this.generateSessionId(),errorStack:"object"==typeof e?e.stack:void 0,version:"undefined"!=typeof window&&(null==(o=this.windowWrapper.get("TitanSDK"))?void 0:o.VERSION)||"unknown",...r,...t},d="critical"===i?"critical":"error",h="critical"===i?"critical_error_with_logs":"error_with_logs";null==(a=this.rollbar)||a[d](e,{custom:{type:h,context:l,logCount:c.length}},((t,r)=>{var s;if(t)this.shouldIgnoreError(t)||Rt.error(`Failed to send ${i} error to Rollbar`,{error:t,originalError:e}),n(null);else{const t=r&&(r.uuid||(null==(s=r.result)?void 0:s.uuid))||null;Rt.info(("critical"===i?"Critical error":"Error")+" sent to Rollbar",{message:"string"==typeof e?e:(null==e?void 0:e.message)||"Unknown error",component:l.component,rollbarId:t,logCount:c.length}),n(t)}}))}catch(c){Rt.error(`Failed to send ${i} error to Rollbar`,{error:c,originalError:e}),n(null)}})).catch((e=>{Rt.error(`Failed to get device context for ${i} error`,{error:e}),n(null)}))})):Promise.resolve(null)}collectSDKUsage(e,t,i,n){var r,s;if(this.rollbar&&(null==(r=this.config)?void 0:r.enabled))try{const r=i?"info":"warning";this.rollbar[r](`SDK function execution: ${e}`,{custom:{type:"sdk_function_execution",functionName:e,success:i,component:n,result:i?t:void 0,error:i?void 0:t,timestamp:Date.now(),url:"undefined"!=typeof window?null==(s=window.location)?void 0:s.href:void 0}}),Rt.info("SDK function execution logged",{functionName:e,success:i,component:n})}catch(o){Rt.error("Failed to log SDK function execution",{error:o,functionName:e,component:n})}}generateSessionId(){return`session_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}async getDeviceContext(){var e,t,i;try{if(null==window?void 0:window.TitanSDK)try{const n=await(null==(i=null==(t=null==(e=null==window?void 0:window.TitanSDK)?void 0:e.deviceInfo)?void 0:t.getDeviceInfo)?void 0:i.call(t));return{deviceInfo:n?JSON.stringify(n):"unavailable"}}catch(n){}return{deviceInfo:`OS: ${(null==navigator?void 0:navigator.platform)||"unknown"}, Browser: ${this.detectBrowserEngine()}, Storage: ${"localStorage"in(window||{})}`}}catch(r){return{}}}detectBrowserEngine(){if("undefined"==typeof navigator)return"unknown";const e=navigator.userAgent;return e.includes("Chrome")?"Blink":e.includes("Firefox")?"Gecko":e.includes("Safari")&&!e.includes("Chrome")?"WebKit":e.includes("Edge")?"EdgeHTML":"unknown"}setupGlobalErrorHandlers(){if("undefined"==typeof window)return;const e=console.error;console.error=(...t)=>{e.apply(console,t);const i=t.find((e=>e instanceof Error||"string"==typeof e&&e.includes("Error")));i&&!this.shouldIgnoreError(i)&&this.reportError(i,{component:"SDK",operation:"console.error"})},"undefined"!=typeof window&&(window.addEventListener("error",(e=>{this.shouldIgnoreError(e.error)||this.reportError(e.error||e.message,{component:"SDK",operation:"window.onerror"})})),window.addEventListener("unhandledrejection",(e=>{this.shouldIgnoreError(e.reason)||this.reportError(e.reason,{component:"SDK",operation:"unhandledrejection"})})))}isInitialized(){var e;return null!==this.rollbar&&!0===(null==(e=this.config)?void 0:e.enabled)}},Pt=Object.freeze(Object.defineProperty({__proto__:null,rollbarClient:At},Symbol.toStringTag,{value:"Module"})),kt=a("SmartTvA_API"),Mt=(e,t)=>{var i,n,r,s;try{if(!t)return kt.warn(`Device info not available, cannot check capability: ${e}`),!1;const o=t.Product||{},a=t.Channel||{},c=t.Capability||{};switch(e){case"3d":return Boolean(c.support3d);case"uhd":return Boolean(c.supportUHD);case"dolby-vision":return Boolean(c.supportHDR&&((null==(i=o.platform)?void 0:i.toLowerCase().includes("dolby"))||(null==(n=a.brand)?void 0:n.toLowerCase().includes("dolby"))));case"atmos":return Boolean((null==(r=o.platform)?void 0:r.toLowerCase().includes("atmos"))||(null==(s=a.brand)?void 0:s.toLowerCase().includes("dolby")));default:return kt.warn(`Unknown device capability: ${e}`),!1}}catch(o){return kt.error(`Error checking device capability ${e}:`,o),!1}},Nt=async e=>{if("undefined"==typeof window)return void kt.warn("Window object not available, cannot attach SmartTvA_API");if("object"==typeof window.SmartTvA_API)return void kt.info("SmartTvA_API already exists on window, skipping initialization");const t=await(async e=>{kt.info("Initializing SmartTvA_API with TitanSDK");let t=null;try{kt.info("Waiting for device info to be ready..."),t=await e.deviceInfo.getDeviceInfo(),kt.info("Device info is ready, proceeding with SmartTvA_API initialization")}catch(i){kt.warn("Failed to get device info during SmartTvA_API initialization:",i)}return{exit:()=>{kt.info("SmartTvA_API.exit() called"),window.close()},hasCapability:(e,...i)=>{switch(kt.debug(`SmartTvA_API.hasCapability('${e}', ${i.join(", ")})`),e){case"3DSupport":return Mt("3d",t);case"MultiScreen":return 1===i.length&&i[0],!1;case"DRM":if(2===i.length){const[e,t]=i;if("PlayReady"===e&&"DASH"===t)return!0;if("Widevine"===e&&"AdaptiveStreaming"===t)return!1}return!1;case"Key":if(1===i.length)switch(i[0]){case"numerickeys":case"colorkeys":case"prev_next":return!0;default:return!1}return!1;case"UHD":return Mt("uhd",t);case"FHD":case"Multiaudio":return!0;case"TTML":if(1===i.length)switch(i[0]){case"inband":case"outofband":case"EBU-TT-D":case"CFF-TT":return!0;default:return!1}return!1;case"HLS":return 1===i.length&&"DISCONTINUITY"===i[0];case"HDR":if(1===i.length){const e=i[0];if(!Mt("uhd",t))return!1;switch(e){case"HDR10":case"DA":case"HDR10+":return!0;case"DV":return Mt("dolby-vision",t);default:return!1}}return!1;case"8K":case"WidevineClassic":case"AdobeHDS":return!1;case"ATMOS":return Mt("atmos",t);default:return kt.warn(`Unknown capability requested: ${e}`),!1}}}})(e);Object.defineProperty(window,"SmartTvA_API",{value:t,writable:!1,configurable:!0}),kt.info("SmartTvA_API successfully attached to window object")},_t=a("WrapperUtils");function Ot(e){return{getTTSSettings:async()=>(await e()).accessibility.getTTSSettings(),getTMSettings:async()=>(await e()).accessibility.getTMSettings(),isTTSSupported:async()=>(await e()).accessibility.isTTSSupported(),isTTSEnabled:async()=>(await e()).accessibility.isTTSEnabled(),isTMEnabled:async()=>(await e()).accessibility.isTMEnabled(),isTextMagnificationSupported:async()=>(await e()).accessibility.isTextMagnificationSupported(),startSpeaking:async t=>(await e()).accessibility.startSpeaking(t),stopSpeaking:async()=>(await e()).accessibility.stopSpeaking(),enableReader:async t=>(await e()).accessibility.enableReader(t),disableReader:async()=>(await e()).accessibility.disableReader(),onTTSSettingsChange:t=>{let i=null;return e().then((e=>{i=e.accessibility.onTTSSettingsChange(t)})).catch((e=>{_t.error("Failed to set up TTS settings change handler:",e)})),()=>{i&&i()}},onTMSettingsChange:t=>{let i=null;return e().then((e=>{i=e.accessibility.onTMSettingsChange(t)})).catch((e=>{_t.error("Failed to set up TM settings change handler:",e)})),()=>{i&&i()}}}}function Lt(e){return{launch:async(t,i)=>(await e()).apps.launch(t,i)}}const xt="1.6.3-HEAD.1",Ht=a("SDK"),Ut={debug:!1,useLegacyDeviceInfo:!1,legacyDeviceInfoTimeout:5e3,fallbackToBrowser:!0};let Ft=null,Bt=null,Vt=null,zt=null;At.initialize({accessToken:"",enabled:!1});const Kt=async()=>{if(!Ft)throw new r("SDK not created. Call getTitanSDK() first.",n.NOT_INITIALIZED);if(!Vt)throw Ht.error("SDK initialization not started"),new r("SDK initialization not started.",n.NOT_INITIALIZED);if(!(await Vt))throw new r("SDK initialization failed.",n.UNKNOWN);return Ft},$t=e=>{if(Bt)return Bt;const t={...Ut,...e};s.setDebugMode(t.debug??!1);const o=b.detectPlatform(t).platform;Ht.info("Platform detected:",o);try{switch(o){case i.PHILIPS:Ft=new Qe(t);break;case i.PHILIPS_OLD:Ft=new Ct(t);break;case i.VESTEL:Ft=new rt(t);break;case i.BROWSER:default:o!==i.BROWSER&&t.debug&&Ht.warn(`Platform ${o} detected but no specific SDK found, using BrowserSDK as fallback.`),Ft=new St(t)}if(!Ft)throw new r("Failed to create SDK instance after platform detection",n.UNKNOWN)}catch(u){throw Ht.error("Error creating SDK instance:",u),new r(`Failed to create SDK instance after platform detection: ${u}`,n.UNKNOWN)}Vt=Ft.init(),Ht.info("SDK Version:",xt);const a={VERSION:xt,isReady:Vt,deviceInfo:(c=Kt,l=e=>{zt=e},{getDeviceInfo:async()=>{const e=await c(),t=await e.deviceInfo.getDeviceInfo();return null==l||l(t),t}}),accessibility:Ot(Kt),apps:Lt(Kt)};var c,l;return t.debug&&(Ht.info("🔧 [DEBUG MODE] TitanSDK debug access enabled"),a.logging=function(e){let t=null;return{subscribe:(i,n)=>{let r=null;return e().then((e=>{t=e,e.logging&&(r=e.logging.subscribe(i,n))})).catch((e=>{_t.error("Failed to set up logging subscription:",e)})),()=>{r&&r()}},getHistory:()=>(null==t?void 0:t.logging)?t.logging.getHistory():[],clear:()=>{(null==t?void 0:t.logging)&&t.logging.clear()}}}(Kt)),t.dev&&(t.debug&&Ht.info("🔧 [DEV MODE] TitanSDK dev access enabled"),o===i.BROWSER&&t.dev&&(Ht.info("Available dev methods:"),Ht.info(" sdk.dev.updateTTSSettings({ enabled: true, rate: 1.5 })"),Ht.info(" sdk.dev.updateTMSettings({ enabled: true, scale: 1.8 })")),a.dev=function(e){return{updateTTSSettings:async t=>{var i,n;return null==(n=null==(i=(await e()).dev)?void 0:i.updateTTSSettings)?void 0:n.call(i,t)},updateTMSettings:async t=>{var i,n;return null==(n=null==(i=(await e()).dev)?void 0:i.updateTMSettings)?void 0:n.call(i,t)},simulateError:async t=>{var i,n;return null==(n=null==(i=(await e()).dev)?void 0:i.simulateError)?void 0:n.call(i,t)},simulateGatewayError:async(t,i)=>{var n,r;return null==(r=null==(n=(await e()).dev)?void 0:n.simulateGatewayError)?void 0:r.call(n,t,i)},isBridgeConnected:async()=>{var t,i;return(null==(i=null==(t=(await e()).dev)?void 0:t.isBridgeConnected)?void 0:i.call(t))??!1}}}(Kt)),Bt=a,Vt.then((async()=>{try{zt=await Ft.deviceInfo.getDeviceInfo()}catch(u){t.debug&&Ht.warn("Failed to pre-cache device info:",u)}})).catch((e=>{Ht.error(`Initialization failed for platform ${o}:`,e)})),Bt},Gt=async()=>{const e=await Kt(),t=await e.deviceInfo.getDeviceInfo();return zt=t,t};if("undefined"!=typeof document&&document.addEventListener("securitypolicyviolation",(e=>{W.getViolations()})),"undefined"!=typeof window)if(window.TitanSDK&&window.TitanSDK.deviceInfo)Ht.info("TitanSDK already exists on window, skipping initialization"),Ht.info("You can still create a new SDK instance using window.getTitanSDK(options)"),window.getTitanSDK=$t;else{const e=()=>{window.onDeviceInfoReady=function(e){Gt().then((t=>e(t))).catch((t=>e({},String(t))))},Object.defineProperty(window,"DeviceInfo",{get:()=>{if(zt)return zt;if(Ft&&Bt)try{return Ft.deviceInfo.getDeviceInfo()}catch{return null}return null},configurable:!0}),void 0===window.SmartTvA_API&&Object.defineProperty(window,"SmartTvA_API",{value:{exit:()=>window.close()},writable:!1,configurable:!0})},t=e=>{const t=null==localStorage?void 0:localStorage.getItem(e);return t?JSON.parse(t):{}},i=(new O).get("TITAN_SDK_PARAMS")||t("TITAN_SDK_PARAMS");i&&Ht.info("Initializing TitanSDK with params:",i),window.TitanSDK=$t(i),e(),Nt(window.TitanSDK).catch((e=>{Ht.error("Failed to initialize SmartTvA_API:",e)}))}exports.VERSION=xt,exports.getDeviceInfo=Gt,exports.getTitanSDK=$t;