@titan-os/sdk 1.9.0 → 1.10.0
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/dist/cjs/sdk.js +1 -1
- package/dist/esm/sdk.js +5501 -5419
- package/dist/types/sdk.d.ts +6 -3
- package/dist/umd/sdk.js +1 -1
- package/package.json +2 -1
package/dist/cjs/sdk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e=Object.defineProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var t=(e=>(e.PHILIPS="PHILIPS",e.PHILIPS_OLD="PHILIPS_OLD",e.VESTEL="VESTEL",e.VESTEL_LEGACY="VESTEL_LEGACY",e.JVC="JVC",e.BROWSER="BROWSER",e.UNKNOWN="UNKNOWN",e))(t||{}),i=(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))(i||{});class n 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,n)}toString(){return`SDKError [${this.code}]: ${this.message}`}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}}function r(e,t,i,n){return[`${`[TitanSDK][${e}]`} ${t}`,...i,"\n",n]}function o(e,t){e}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){var t,i,n;this.logBuffer.push(e),this.logBuffer.length>this.maxBufferSize&&this.logBuffer.shift();if(("Gateway"===(null==(t=e.metadata)?void 0:t.source)||!0===(null==(i=e.metadata)?void 0:i.tunneled))&&"error"===e.level){const t=(null==(n=e.metadata)?void 0:n.caller)||"[Gateway]";o("error",r(e.module,e.message,e.args||[],t))}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 a(e){const t=(t,i,...n)=>{var a;const c=(()=>{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""}})(),l=(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:o}=(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}[${o}]`:`[${o}]`}catch{return"Unknown location"}})(new Error),d={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==(a=window.location)?void 0:a.href:void 0,caller:c}};s.addLogEntry(d);if(s.isDebugMode()||"error"===t){r(e,i,n,l);o(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 c(e){return a(e)}const l=(e,t)=>s.subscribe(e,t),d=e=>s.unsubscribe(e),u=(e,t,i)=>s.getHistory(e,t,i),g=()=>s.clear(),h=e=>s.addLogEntry(e),p=c("PlatformDetection");class f{strategies=[];register(e){this.strategies.push(e),this.strategies.sort(((e,t)=>t.getPriority()-e.getPriority()))}getStrategies(){return[...this.strategies]}}class m{canDetect(){return"undefined"!=typeof window&&("t9_core"in window||"vestel"===window.deviceBrand||navigator.userAgent.toLowerCase().includes("vestel"))}getPlatform(){return this.canDetect()?t.VESTEL:null}getPriority(){return 3}}class v{canDetect(){if("undefined"==typeof window)return!1;const e=navigator.userAgent,t=e.toLowerCase(),i=t.includes("vestel"),n=e.includes("MB181")||e.includes("MB180")||t.includes("mb181")||t.includes("mb180")||e.includes("Model/Vestel-MB181")||e.includes("Model/Vestel-MB180");return i&&n}getPlatform(){return this.canDetect()?t.VESTEL_LEGACY:null}getPriority(){return 20}}class S{canDetect(){if("undefined"==typeof window)return!1;if("undefined"==typeof navigator)return!1;const e=navigator.userAgent.toLowerCase();return["hkc","jvc"].some((t=>e.includes(t)))}getPlatform(){return this.canDetect()?t.JVC:null}getPriority(){return 6}}class y{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()?t.PHILIPS:null}getPriority(){return 5}}class b{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()?t.PHILIPS_OLD:null}getPriority(){return 10}}class w{canDetect(){return!0}getPlatform(){return t.BROWSER}getPriority(){return 1}}const T=new class{factory;lastDetectedPlatform=null;constructor(){this.factory=new f,this.factory.register(new S),this.factory.register(new y),this.factory.register(new m),this.factory.register(new v),this.factory.register(new b),this.factory.register(new w)}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 r=this.factory.getStrategies();for(const t of r)if(t.canDetect()){const i=t.getPlatform();if(null!==i){const n={platform:i,detectedBy:t.constructor.name,confidence:.9};return this.lastDetectedPlatform=n,e.debug&&p.info(`Platform detected as ${i}`),{...n}}}if(!1===e.fallbackToBrowser)throw new n("Could not detect platform and fallback is disabled",i.PLATFORM_NOT_DETECTED);const o={platform:t.BROWSER,detectedBy:"fallback",confidence:.1};return this.lastDetectedPlatform=o,e.debug&&p.info("Fallback to browser platform - no strategy matched"),{...o}}reset(){this.lastDetectedPlatform=null}},I={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"},E={TTS_SETTINGS_CHANGE:I.TTS_SETTINGS_CHANGE,TM_SETTINGS_CHANGE:I.TM_SETTINGS_CHANGE,LOG_ENTRY:I.LOG_ENTRY},D={enabled:!1,available:!1},C={enabled:!1,available:!1},A={tts:D,tm:C},P="TIMEOUT",R="NOT_SUPPORTED",M="INVALID_REQUEST",k="COMMUNICATION_ERROR",O="LAUNCH_FAILED",_="APP_NOT_FOUND",N="APP_NOT_AVAILABLE",L="INVALID_APP_CODE";var F=(e=>(e.PHILIPS="philips",e.VESTEL="vestel",e.BROWSER="browser",e))(F||{});class x{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 U(e,t,i="titanos"){return new Promise(((e,n)=>{const r=new x,o="deviceInfoCallback_"+Date.now()+"_"+Math.floor(1e4*Math.random());r.create(o,(t=>{e(t),r.removeGlobal(o)}));const s=`https://${t}/potamoi/v1/device_info?callback=${o}`,a=`https://smarttv.zeasn.tv/homepage_api/device/clientInfo?callback=${o}`,c=document.createElement("script");c.src="titanos"===i?s:a,c.type="text/javascript",c.onerror=()=>{n(new Error("Failed to load device info script.")),delete r.proxy[o]},document.head.appendChild(c),setTimeout((()=>{r.has(o)&&(n(new Error("Device info request timed out.")),delete r.proxy[o]),c.parentNode&&c.parentNode.removeChild(c)}),7e3)}))}const H=()=>{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)},V=1e4,K=[{time:3e4,message:"DOM still not ready after 30 seconds"},{time:6e4,message:"DOM still not ready after 1 minute"},{time:12e4,message:"DOM still not ready after 2 minutes"},{time:18e4,message:"DOM still not ready after 3 minutes"},{time:24e4,message:"DOM still not ready after 4 minutes"},{time:3e5,message:"DOM still not ready after 5 minutes - this may indicate serious page issues"}],B=c("DOM-Utils");function z(){return"undefined"!=typeof document&&!!document.body}const $=(e="en-US")=>"undefined"!=typeof navigator&&navigator.language&&navigator.language||e;const G=c("BaseBridge");class j{src="";isInitialized=!1;iframe=null;iframeOrigin="";pendingRequests=new Map;messageTimeout=1e4;iframeTimeout=3e3;connected=!1;debug=!1;initializationPromise=null;aborted=!1;initReject;MESSAGE_TYPES=I;eventHandlers=new Map;constructor(e){this.debug=(null==e?void 0:e.debug)||!1,(null==e?void 0:e.gatewayUrl)&&(this.src=e.gatewayUrl),G.debug("bridge: constructor",this.src)}async initialize(){if(this.isInitialized)return!0;if(this.initializationPromise)return G.debug("bridge: initialization already in progress, waiting..."),this.initializationPromise;G.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,G.debug("bridge: starting initialization process"),window.addEventListener("message",this.handleMessage.bind(this));let i=!1;const n=()=>{this.aborted||i||(i=!0,this.isInitialized=!0,G.debug("bridge initialized successfully"),e(!0))},r=()=>{this.aborted||i||(i=!0,G.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(n,r),i||(i=!0,G.warn("Bridge initialization timeout - setupIframe completed but LAUNCHER_READY not received"),this.isInitialized=!1,e(!1))}catch(o){if(i)return;i=!0,G.error("Failed to setup iframe:",o),this.isInitialized=!1,t(o)}})()}))}async sendMessage(e,t){this.isInitialized||await this.initialize();try{const r=this.prepareMessage(e,t);return new Promise(((e,t)=>{const o=setTimeout((()=>{this.pendingRequests.delete(r.requestId),t(new n("Bridge request timeout",i.TIMEOUT))}),this.messageTimeout);this.pendingRequests.set(r.requestId,{resolve:e,reject:t,timeout:o}),this.iframe&&this.iframe.contentWindow?(G.debug("bridge: sendMessage",r),this.iframe.contentWindow.postMessage(r,this.iframeOrigin||"*")):(clearTimeout(o),this.pendingRequests.delete(r.requestId),t(new n("Bridge iframe not available",i.COMMUNICATION_ERROR)))}))}catch(r){G.error("bridge: error sending message:",r);return(await Promise.resolve().then((()=>Pe)).then((e=>e.rollbarClient))).reportError(r instanceof Error?r:new Error("Unknown error"),{component:"SDK",operation:"sendMessage",requestId:this.prepareMessage(e,t).requestId}),Promise.reject({success:!1,type:e,error:{code:i.COMMUNICATION_ERROR,message:r instanceof Error?r.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&&G.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(E).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){G.error("Error handling message:",i)}}handleNotification(e){G.debug("bridge notification received:",e);const t=this.eventHandlers.get(e.type);t&&t.forEach((t=>{try{t(e.data)}catch(i){G.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 n(e.message,i,{operation:t,gatewayErrorCode:e.code,gatewayErrorMessage:e.message})}mapGatewayErrorCodeToSDK(e){switch(e){case O:case _:case N:case L:return i.INVALID_PARAMETER;case P:return i.TIMEOUT;case R:return i.NOT_SUPPORTED;case k:return i.COMMUNICATION_ERROR;case M:return i.INVALID_ARGUMENTS;default:return i.UNKNOWN}}getOperationFromMessageType(e){switch(e){case I.LAUNCH_APP_REQUEST:return"launchApp";case I.DEVICE_INFO_REQUEST:return"getDeviceInfo";case I.TTS_REQUEST_START_SPEAKING:return"startSpeaking";case I.TTS_REQUEST_STOP_SPEAKING:return"stopSpeaking";case I.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"),!z())try{await function(e=1e4){return new Promise(((t,i)=>{if(z())return void t();const n=Date.now();let r=0,o="initial";B.debug("Waiting for document.body:",{readyState:document.readyState,bodyExists:!!document.body,htmlExists:!!document.documentElement,headExists:!!document.head,timeout:e});let s=null,a=null,c=null;const l=[];function d(){a&&(clearInterval(a),a=null),s&&(s.disconnect(),s=null),c&&(clearTimeout(c),c=null),l.forEach(clearTimeout),l.length=0}const u=(e,t)=>{if(o!==e){const i=Date.now()-n;B.debug(`DOM strategy changed: ${o} → ${e}`,{elapsed:i,reason:t||"strategy switch",checkCount:r}),o=e}},g=(e,t="warn")=>{const i=Date.now()-n,o=Math.floor(i/6e4),s=Math.floor(i%6e4/1e3);"error"===t?B.error(`${e} after ${o}m ${s}s`,{elapsed:i,checkCount:r,readyState:document.readyState,bodyExists:!!document.body}):B.warn(`${e} after ${o}m ${s}s`,{elapsed:i,checkCount:r,readyState:document.readyState})},h=e=>{u("mutation-observer","DOMContentLoaded completed but body not ready"),s=new MutationObserver((()=>{r++;const e=Date.now()-n;z()&&(d(),B.debug("document.body ready via MutationObserver:",{elapsed:e,checkCount:r}),t())})),s.observe(document.documentElement,{childList:!0,subtree:!1}),c=setTimeout((()=>{z()||(g("DOM still not ready, switching to polling fallback"),u("polling","MutationObserver timeout"),a=setInterval((()=>{r++;const e=Date.now()-n;z()&&(d(),B.debug("document.body ready via polling fallback:",{elapsed:e,checkCount:r}),t())}),50))}),3e4)};if("loading"===document.readyState){u("dom-content-loaded","document still loading");const o=()=>{var e;clearTimeout(s);const i=Date.now()-n;z()?(d(),B.debug("document.body ready after DOMContentLoaded:",{elapsed:i}),t()):(B.warn("DOMContentLoaded fired but body still not ready:",{elapsed:i,childNodes:(null==(e=document.documentElement)?void 0:e.childNodes.length)||0}),h())},s=setTimeout((()=>{var e;document.removeEventListener("DOMContentLoaded",o),d();const t=Date.now()-n;B.error("Timeout waiting for document.body:",{elapsed:t,readyState:document.readyState,bodyExists:!!document.body,checkCount:r,html:!!document.documentElement,head:!!document.head,childNodesCount:(null==(e=document.documentElement)?void 0:e.childNodes.length)||0}),i(new Error(`Timeout waiting for document.body after ${t}ms. readyState: ${document.readyState}, checks: ${r}. Initialize SDK after DOMContentLoaded or use defer/async script.`))}),e);document.addEventListener("DOMContentLoaded",o,{once:!0})}else B.debug("DOM already loaded, using MutationObserver + polling"),h();K.forEach((({time:t,message:i})=>{if(t<e){const e=setTimeout((()=>{z()||g(i)}),t);l.push(e)}}))}))}(V)}catch(i){throw G.error("Document body unavailable:",{readyState:document.readyState,bodyExists:!!document.body,timeout:10}),new Error("Document body is not available. SDK initialized too early - ensure DOM is ready before calling getTitanSDK(). Consider initializing SDK after DOMContentLoaded event or in a defer/async script.")}document.body.appendChild(this.iframe),await new Promise((i=>{const n=setTimeout((()=>{this.aborted||(G.warn("Bridge iframe ready timeout - continuing anyway"),i())}),this.iframeTimeout),r=t=>{var o;this.aborted||t.data&&t.data.type===I.LAUNCHER_READY&&(null==(o=this.iframe)?void 0:o.contentWindow)===t.source&&(G.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===I.TRANSFER_DATA&&(null==(t=this.iframe)?void 0:t.contentWindow)===e.source&&G.debug("bridge transferData:",e.data)})),this.iframe&&(this.iframe.onload=()=>{this.aborted||G.debug("bridge iframe loaded: ",this.src)},this.iframe.onerror=()=>{this.aborted||(G.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(I.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(I.LAUNCH_APP_REQUEST,t)).success}onLogEntry(e){return this.registerEventHandler(I.LOG_ENTRY,(t=>{h({...t,metadata:{...t.metadata,source:"Gateway",tunneled:!0}}),e(t)}))}}const W=c("CSPDetector");let q=[];const Q=class{static getViolations(){return[...this.violations]}static clearViolations(){this.violations.length=0}static onViolation(e){return q.push(e),()=>{q=q.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 Y;((t,i,n)=>{i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n})(Q,"symbol"!=typeof(Y="violations")?Y+"":Y,[]),"undefined"!=typeof document&&document.addEventListener("securitypolicyviolation",(e=>{const t=`${e.violatedDirective}: ${e.blockedURI}`;Q.violations.push(t),W.warn("CSP Violation detected:",t);const i={directive:e.violatedDirective,blockedURI:e.blockedURI,originalEvent:e};q.forEach((e=>{try{e(i)}catch(t){W.error("CSPDetector listener error",t)}}))}));let J=Q;const Z=c("EnhancedBridge");function X(e,t){if(!["frame-src","child-src","connect-src"].includes(e.directive)||!e.blockedURI||!t)return!1;const i=e.blockedURI,n=e=>e.replace(/\/+$/,"").toLowerCase(),r=n(i),o=n(t),s=e=>{try{return new URL(e).hostname}catch{const t=e.match(/^(?:https?:\/\/)?([^\/]+)/);return t?t[1]:""}},a=s(i),c=s(t);return o.includes(r)||r.includes(o)||a&&c&&a===c||i.includes("titanos.tv")&&t.includes("titanos.tv")||i.includes("localhost")&&t.includes("localhost")}class ee extends j{bridgeHealthStatus={connected:!1,cspBlocked:!1,iframeCreated:!1,communicationWorking:!1,cspViolations:[]};cspUnsubscribe;cspViolationDetected=!1;cspViolationPromise;cspViolationResolver=null;constructor(e){super(e),this.bridgeHealthStatus.gatewayUrl=this.src,this.cspViolationPromise=new Promise((e=>{this.cspViolationResolver=e})),this.setupCspViolationListener()}setupCspViolationListener(){this.cspUnsubscribe=J.onViolation((e=>{if(Z.debug("CSP violation received in EnhancedBaseBridge:",{directive:e.directive,blockedURI:e.blockedURI,gatewayUrl:this.src,isBridgeViolation:X(e,this.src)}),X(e,this.src)){const t=`${e.directive}: ${e.blockedURI||"unknown"}`;this.bridgeHealthStatus.cspViolations.includes(t)||this.bridgeHealthStatus.cspViolations.push(t),Z.warn("CSP violation detected for bridge:",{directive:e.directive,blockedURI:e.blockedURI,gatewayUrl:this.src}),this.bridgeHealthStatus.cspBlocked=!0,this.bridgeHealthStatus.lastError=`CSP ${e.directive} blocked: ${e.blockedURI||"unknown"}`,!this.cspViolationDetected&&this.cspViolationResolver&&(this.cspViolationDetected=!0,Z.debug("Resolving CSP violation Promise"),this.cspViolationResolver(),this.cspViolationResolver=null)}}))}async initialize(){try{Z.debug("Starting enhanced bridge initialization");const e=await super.initialize();return this.bridgeHealthStatus.connected=!!e,!!e}catch(e){const t=e instanceof Error?e.message:"Unknown error";return this.bridgeHealthStatus.lastError=t,Z.error("Enhanced bridge initialization failed:",e),!1}}getBridgeHealth(){return{...this.bridgeHealthStatus,connected:this.isConnected(),iframeCreated:null!==this.iframe}}disconnect(){this.aborted||(super.disconnect(),this.bridgeHealthStatus.connected=!1,this.bridgeHealthStatus.communicationWorking=!1,this.cspUnsubscribe&&(this.cspUnsubscribe(),this.cspUnsubscribe=void 0),this.cspViolationDetected=!1,this.cspViolationPromise=new Promise((e=>{this.cspViolationResolver=e})),this.bridgeHealthStatus={connected:!1,cspBlocked:!1,iframeCreated:!1,communicationWorking:!1,gatewayUrl:this.src,cspViolations:[]},this.aborted=!0)}async setupIframe(e,t){try{Z.debug("Setting up bridge iframe"),await super.setupIframe(e,t),this.bridgeHealthStatus.iframeCreated=!0}catch(i){this.bridgeHealthStatus.iframeCreated=!1;const e=i instanceof Error?i.message:"Unknown error";throw this.bridgeHealthStatus.lastError=e,Z.error("Failed to setup iframe:",{error:e,gatewayUrl:this.src,documentReady:document.readyState,bodyExists:!!document.body}),i}}async executeBridgeFunction(e,t){const r=this.getBridgeHealth();if(!r.connected){if(t)return Z.debug("Bridge not connected, using fallback function"),await t();throw new n("Bridge not connected",i.COMMUNICATION_ERROR,{healthStatus:r})}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 waitForInitializationAttempt(){if(this.isConnected())return void Z.debug("Bridge already initialized, no need to wait");const e=this;if(e.initializationPromise){Z.debug("Bridge initialization in progress, waiting for completion...");try{await e.initializationPromise,Z.debug("Bridge initialization attempt completed")}catch{Z.debug("Bridge initialization attempt completed (with error)")}}else{Z.debug("No bridge initialization in progress, starting new attempt...");try{await this.initialize(),Z.debug("Bridge initialization attempt completed")}catch{Z.debug("Bridge initialization attempt completed (with error)")}}this.bridgeHealthStatus.iframeCreated&&!this.isConnected()&&(this.cspViolationDetected||this.bridgeHealthStatus.cspBlocked?Z.debug("CSP violation already detected, no need to wait"):(Z.debug("Iframe created but connection not established, waiting for CSP violation detection..."),await this.cspViolationPromise,Z.debug("CSP violation detection completed (or connection established)")))}}class te extends ee{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 ie=new x;class ne extends ee{constructor(e){var t,i;if(null==e?void 0:e.gatewayUrl)super({gatewayUrl:e.gatewayUrl});else{let e="app";if(ie.proxy.jwt&&!ie.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)))}})(ie.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=ie.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||D}async getTMSettings(){return(await this.getA11ySettings()).tm||C}async getA11ySettings(){const e=await this.sendMessage(I.TTS_REQUEST_SETTINGS,void 0);return e.success&&"data"in e?e.data:A}async startSpeaking(e){this.isInitialized||await this.initialize();return(await this.sendMessage(I.TTS_REQUEST_START_SPEAKING,e)).success}async stopSpeaking(){return(await this.sendMessage(I.TTS_REQUEST_STOP_SPEAKING,void 0)).success}onTTSSettingsChange(e){return this.registerEventHandler(I.TTS_SETTINGS_CHANGE,(t=>{e(t)}))}onTMSettingsChange(e){return this.registerEventHandler(I.TM_SETTINGS_CHANGE,(t=>{e(t)}))}}const re={HIGH:["button","link","heading","listitem"],MEDIUM:["textbox","combobox","checkbox","radio","slider"],LOW:["list","navigation","main","dialog","grid"]},oe=c("AriaProcessor");class se{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 oe.warn("Interactive element without accessible name:",e),null;const n=this.getAccessibleDescription(e),r=this.computeElementState(e),o=this.computePositionInfo(e,t),s=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:o,actions:s,tvProperties:a};return oe.debug("Processed accessibility element:",{role:t,name:i.substring(0,50),state:r,tvOptimized:!!a}),c}catch(t){return oe.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 o=e.getAttribute("aria-disabled")||e.getAttribute("disabled");null!==o&&(t.disabled="true"===o||""===o);const s=e.getAttribute("aria-invalid");null!==s&&(t.invalid="true"===s||s);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')),o=n.indexOf(t)+1,s=r.indexOf(e)+1;if(o>0&&s>0)return{position:s,setSize:r.length,row:o,column:s,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||(re.HIGH.includes(t)?i.priority="high":re.MEDIUM.includes(t)?i.priority="medium":i.priority="low"),Object.keys(i).length>0?i:void 0}isRelevantForTV(e){return[...re.HIGH,...re.MEDIUM,...re.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 ae=c("DOMMonitor");class ce{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 se(e)}updateConfig(e){this.config={...e},this.ariaProcessor.updateConfig(e)}async startFocusTracking(){if(this.isTracking)return void ae.debug("Focus tracking already active");ae.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,ae.info("Focus tracking started")}async startLiveRegionMonitoring(e){this.liveRegionHandler=e,ae.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"]}),ae.info("Live region monitoring started")}async stop(){ae.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,ae.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){ae.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&&ae.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){ae.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),ae.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(" "),o="true"===e.getAttribute("aria-busy");return{element:e,politeness:i,atomic:n,relevant:r,busy:o}}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){ae.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 le=c("AnnouncementProcessor");class de{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 le.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 le.debug("TTS stop result:",e),e}return le.debug("No stopTtsFunction available"),!0}catch(e){return le.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 o=this.getActionAnnouncement(e.actions||[]);return o&&t.push(o),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(),le.debug("Announced:",{text:e.text.join(" ").substring(0,100),priority:e.priority,success:t}),t}catch(i){return le.error("Error speaking announcement:",i),!1}}delay(e){return new Promise((t=>setTimeout(t,e)))}}const ue=c("AccessibilityReader");class ge{config;isActive=!1;domMonitor;ariaProcessor;announcementProcessor;currentElement=null;liveRegions=new Map;constructor(e,t,i){this.config={...e},this.ariaProcessor=new se(e),this.announcementProcessor=new de(e,t,i),this.domMonitor=new ce(e,this.handleFocusChange.bind(this))}async start(){if(this.isActive)return ue.debug("Accessibility Reader already active"),!0;try{ue.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,ue.info("Accessibility Reader started successfully"),!0}catch(e){return ue.error("Failed to start Accessibility Reader:",e),!1}}async stop(){if(!this.isActive)return ue.debug("Accessibility Reader not active"),!0;try{return ue.info("Stopping Accessibility Reader"),await this.domMonitor.stop(),this.currentElement=null,this.liveRegions.clear(),this.isActive=!1,ue.info("Accessibility Reader stopped"),!0}catch(e){return ue.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 ue.info("Accessibility Reader configuration updated",this.config),!0}catch(t){return ue.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):(ue.debug("Accessibility Reader not active, skipping announcement"),!1)}async stopAnnouncement(){return this.isActive?await this.announcementProcessor.stopAnnouncement():(ue.debug("Accessibility Reader not active, skipping stop"),!1)}getCurrentElement(){return this.currentElement}async handleFocusChange(e){var t,i;try{ue.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){ue.error("Error handling focus change:",n)}}async handleLiveRegionChange(e,t){try{if(ue.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){ue.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){ue.error("Error announcing element:",t)}}}const he=c("AccessibilityService");class pe{bridge;reader=null;ttsSettings=D;tmSettings=C;constructor(e){this.bridge=e,this.bridge.onTTSSettingsChange((e=>{this.ttsSettings=e})),this.bridge.onTMSettingsChange((e=>{this.tmSettings=e}))}async startSpeaking(e){if("string"==typeof e&&(e=[e]),await this.isTTSEnabled())try{return await this.bridge.startSpeaking(e)}catch(t){return he.error("Error starting speaking:",t),!1}return!0}async stopSpeaking(){if(await this.isTTSEnabled())try{return await this.bridge.stopSpeaking()}catch(e){return he.error("Error stopping speaking:",e),!1}return!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 ge(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.bridge.onTTSSettingsChange(e)}onTMSettingsChange(e){return this.bridge.onTMSettingsChange(e)}async getTTSSettings(){try{const e=await this.bridge.getTTSSettings();return this.ttsSettings=e,e}catch(e){return he.error("Error getting TTS settings from bridge:",e),this.ttsSettings}}async getTMSettings(){try{const e=await this.bridge.getTMSettings();return this.tmSettings=e,e}catch(e){return he.error("Error getting TM settings from bridge:",e),this.tmSettings}}async isTTSEnabled(){return(await this.getTTSSettings()).enabled}async isTMEnabled(){return(await this.getTMSettings()).enabled}}class fe{config;waitReady=new Promise((()=>{}));waitReadyResolver;constructor(e){this.config=e,this.waitReady=new Promise((e=>{this.waitReadyResolver=e}))}logError(...e){this.config.debug}}var me,ve={exports:{}};var Se,ye,be=(me||(me=1,Se=ve,ye=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 o={compressToBase64:function(e){if(null==e)return"";var i=o._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:o._decompress(e.length,32,(function(i){return r(t,e.charAt(i))}))},compressToUTF16:function(t){return null==t?"":o._compress(t,15,(function(t){return e(t+32)}))+" "},decompressFromUTF16:function(e){return null==e?"":""==e?null:o._decompress(e.length,16384,(function(t){return e.charCodeAt(t)-32}))},compressToUint8Array:function(e){for(var t=o.compress(e),i=new Uint8Array(2*t.length),n=0,r=t.length;n<r;n++){var s=t.charCodeAt(n);i[2*n]=s>>>8,i[2*n+1]=s%256}return i},decompressFromUint8Array:function(t){if(null==t)return o.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 s=[];return i.forEach((function(t){s.push(e(t))})),o.decompress(s.join(""))},compressToEncodedURIComponent:function(e){return null==e?"":o._compress(e,6,(function(e){return i.charAt(e)}))},decompressFromEncodedURIComponent:function(e){return null==e?"":""==e?null:(e=e.replace(/ /g,"+"),o._decompress(e.length,32,(function(t){return r(i,e.charAt(t))})))},compress:function(t){return o._compress(t,16,(function(t){return e(t)}))},_compress:function(e,t,i){if(null==e)return"";var n,r,o,s={},a={},c="",l="",d="",u=2,g=3,h=2,p=[],f=0,m=0;for(o=0;o<e.length;o+=1)if(c=e.charAt(o),Object.prototype.hasOwnProperty.call(s,c)||(s[c]=g++,a[c]=!0),l=d+c,Object.prototype.hasOwnProperty.call(s,l))d=l;else{if(Object.prototype.hasOwnProperty.call(a,d)){if(d.charCodeAt(0)<256){for(n=0;n<h;n++)f<<=1,m==t-1?(m=0,p.push(i(f)),f=0):m++;for(r=d.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<h;n++)f=f<<1|r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r=0;for(r=d.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==--u&&(u=Math.pow(2,h),h++),delete a[d]}else for(r=s[d],n=0;n<h;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;0==--u&&(u=Math.pow(2,h),h++),s[l]=g++,d=String(c)}if(""!==d){if(Object.prototype.hasOwnProperty.call(a,d)){if(d.charCodeAt(0)<256){for(n=0;n<h;n++)f<<=1,m==t-1?(m=0,p.push(i(f)),f=0):m++;for(r=d.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<h;n++)f=f<<1|r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r=0;for(r=d.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==--u&&(u=Math.pow(2,h),h++),delete a[d]}else for(r=s[d],n=0;n<h;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;0==--u&&(u=Math.pow(2,h),h++)}for(r=2,n=0;n<h;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:o._decompress(e.length,32768,(function(t){return e.charCodeAt(t)}))},_decompress:function(t,i,n){var r,o,s,a,c,l,d,u=[],g=4,h=4,p=3,f="",m=[],v={val:n(0),position:i,index:1};for(r=0;r<3;r+=1)u[r]=r;for(s=0,c=Math.pow(2,2),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;switch(s){case 0:for(s=0,c=Math.pow(2,8),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;d=e(s);break;case 1:for(s=0,c=Math.pow(2,16),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;d=e(s);break;case 2:return""}for(u[3]=d,o=d,m.push(d);;){if(v.index>t)return"";for(s=0,c=Math.pow(2,p),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;switch(d=s){case 0:for(s=0,c=Math.pow(2,8),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;u[h++]=e(s),d=h-1,g--;break;case 1:for(s=0,c=Math.pow(2,16),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;u[h++]=e(s),d=h-1,g--;break;case 2:return m.join("")}if(0==g&&(g=Math.pow(2,p),p++),u[d])f=u[d];else{if(d!==h)return null;f=o+o.charAt(0)}m.push(f),u[h++]=o+f.charAt(0),o=f,0==--g&&(g=Math.pow(2,p),p++)}}};return o}(),null!=Se?Se.exports=ye:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",(function(){return ye}))),ve.exports);const we="1.9.0",Te=c("RollbarClient"),Ie=["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 Ee=new class{config=null;windowWrapper=new x;lastAPICallTime=0;API_THROTTLE_MS=1e3;sessionId="";isSDKError(e){return e instanceof n||e instanceof Error&&"SDKError"===e.name}initialize(e){if(this.config=e,!e.enabled)return Te.info("Rollbar disabled - error reporting will be skipped"),void(this.sessionId=this.generateSessionId());this.sessionId=this.generateSessionId(),e.accessToken?Te.info("Rollbar initialized - using API",{environment:e.environment||"development",sessionId:this.sessionId}):Te.info("Rollbar initialized without token - will use API with Nginx proxy (server should add 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 Ie.some((e=>(null==t?void 0:t.toLowerCase().includes(e.toLowerCase()))||(null==i?void 0:i.toLowerCase().includes(e.toLowerCase()))||n.includes(e.toLowerCase())))}parseStackTrace(e){var t;if(!e)return[];const i=[],n=e.split("\n").slice(1);for(const r of n){const e=r.match(/at\s+(?:(\S+)\s+\()?([^(]+):(\d+):(\d+)\)?/);e&&i.push({method:e[1]||void 0,filename:null==(t=e[2])?void 0:t.trim(),lineno:parseInt(e[3],10),colno:parseInt(e[4],10)})}return i}async sendErrorToRollbarAPI(e,t,i){var n,r,o,s,a,c;const l=Date.now();if(l-this.lastAPICallTime<this.API_THROTTLE_MS)return Te.debug("Throttling API call",{timeSinceLastCall:l-this.lastAPICallTime}),null;this.lastAPICallTime=l,(null==(n=this.config)?void 0:n.accessToken)||Te.debug("Sending error to Rollbar API without token - relying on server-side token via proxy");try{const n="string"==typeof e?e:e.message||"Unknown error",l="object"==typeof e?e.stack:void 0,d={data:{level:i,environment:(null==(r=this.config)?void 0:r.environment)||"development",body:{message:{body:n},...l&&{trace_chain:[{frames:this.parseStackTrace(l).reverse()}]}},custom:{component:t.component||"SDK",...t.operation&&{operation:t.operation},version:t.version||we,userAgent:t.userAgent||("undefined"!=typeof navigator?navigator.userAgent:"unknown"),...t.url&&{url:t.url}}}};(null==(o=this.config)?void 0:o.accessToken)&&(d.access_token=this.config.accessToken);const u={"Content-Type":"application/json"};(null==(s=this.config)?void 0:s.accessToken)&&(u["X-Rollbar-Access-Token"]=this.config.accessToken);const g=await window.fetch("https://sdk.titanos.tv/logs/",{method:"POST",headers:u,body:JSON.stringify(d)});if(!g.ok)return Te.error("Failed to send error to Rollbar API",{status:g.status,statusText:g.statusText}),null;const h=await g.json(),p=(null==(a=null==h?void 0:h.result)?void 0:a.uuid)||(null==h?void 0:h.uuid)||(null==(c=null==h?void 0:h.result)?void 0:c.id)||null;return Te.info(("critical"===i?"Critical error":"Error")+" sent to Rollbar API",{message:n,component:t.component,rollbarId:p}),p}catch(d){return Te.error("Failed to send error to Rollbar API",{error:d,originalError:e}),null}}async buildErrorContext(e,t){var i,n;const r=await this.getDeviceContext(),o={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==(i=window.location)?void 0:i.href:void 0,userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",sessionId:this.sessionId,errorStack:"object"==typeof e?e.stack:void 0,version:"undefined"!=typeof window&&(null==(n=this.windowWrapper.get("TitanSDK"))?void 0:n.VERSION)||we,...r,...t},s=u().filter((e=>!e.module.includes("RollbarClient")&&!e.message.includes("Rollbar")&&"debug"!==e.level)).slice(-20);return o.logs=s.map((e=>`[${e.timestamp}] ${e.module}: ${e.message}${e.args&&e.args.length>0?"\n Args: "+JSON.stringify(e.args):""}`)).join("\n"),o}async reportError(e,t,i="error"){var n,r;if(!(null==(n=this.config)?void 0:n.enabled)||!e)return Promise.resolve(null);if(!this.isSDKError(e))return Promise.resolve(null);if(this.shouldIgnoreError(e))return Promise.resolve(null);try{const n=await this.buildErrorContext(e,t);return this.sendErrorToRollbarAPI(e,n,i)}catch(o){Te.error(`Failed to build error context for ${i} error`,{error:o});const n={component:(null==t?void 0:t.component)||"SDK",operation:null==t?void 0:t.operation,version:we,userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",url:"undefined"!=typeof window?null==(r=window.location)?void 0:r.href:void 0,timestamp:Date.now(),sessionId:this.sessionId,...t};return this.sendErrorToRollbarAPI(e,n,i)}}collectSDKUsage(e,t,i,n){var r,o;if(!(null==(r=this.config)?void 0:r.enabled))return;const s={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==(o=window.location)?void 0:o.href:void 0};Te.info("SDK function execution",s)}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"}destroy(){this.config=null,this.sessionId="",this.lastAPICallTime=0}isInitialized(){var e;return!0===(null==(e=this.config)?void 0:e.enabled)}},De={};function Ce(e){const t={},i=/jwt|token|authorization|cookie|password|secret/i;return Object.keys(e).forEach((n=>{const r=e[n];i.test(n)?t[n]="[REDACTED]":t[n]=(e=>{if("string"==typeof e)return e.length>500?`${e.slice(0,500)}…`:e;if(Array.isArray(e))return e.slice(-50).map((e=>"string"==typeof e&&e.length>500?`${e.slice(0,500)}…`:e));return e})(r)})),t}function Ae(e,t,r,o={}){try{const s=Date.now();if(s-(De[e]||0)<5e3)return Promise.resolve(null);De[e]=s;const a={userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",component:t,operation:r,context:o?Ce(o):void 0,version:we};Te.error("SDK_CRITICAL",{code:e,component:t,operation:r,...a.context?{context:a.context}:{}});const c=new n(e,i.UNKNOWN,{component:t,operation:r,...a.context?{context:a.context}:{}});return Ee.reportError(c,a,"critical")}catch{return Promise.resolve(null)}}const Pe=Object.freeze(Object.defineProperty({__proto__:null,reportCriticalCode:Ae,rollbarClient:Ee},Symbol.toStringTag,{value:"Module"})),Re=c("TVPlatform");class Me extends fe{DEFAULT_DEVICE_INFO={};bridge;isInitialized=!1;CACHE_KEY="titansdk";CACHE_EXPIRY=6048e5;constructor(e,t){if(super(e),null!=t)this.bridge=t;else if(null===t)this.waitReadyResolver(!0);else{const e={gatewayUrl:this.config.gatewayUrl};this.bridge=new ee(e)}this.bridge&&this.initializeBridgeSafely()}async initializeBridgeSafely(){if(this.bridge){try{await this.bridge.initialize()&&(this.isInitialized=!0)}catch(e){Re.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||t.lastVersion!==we?(localStorage.removeItem(this.CACHE_KEY),null):(Re.debug("Device info loaded from localStorage cache"),t)}catch(e){return Re.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 x;try{n=be.decompressFromEncodedURIComponent(i),n&&Re.debug("Device info loaded from URL parameter (lz-string)")}catch(e){Re.debug("lz-string decompression failed, trying base64")}if(!n)try{const e=r.get("atob");if(!e)return Re.warn("atob function not available"),null;n=e(decodeURIComponent(i)),Re.debug("Device info loaded from URL parameter (base64)")}catch(t){return Re.warn("Both lz-string and base64 decoding failed"),null}if(!n)return Re.warn("Failed to decode URL parameter"),null;return JSON.parse(n)}catch(i){return Re.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 Re.warn("Skipping cache save - invalid or empty device info");const t={data:e,timestamp:Date.now(),lastVersion:we};localStorage.setItem(this.CACHE_KEY,JSON.stringify(t)),Re.debug("Device info saved to localStorage cache")}catch(t){Re.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:D,tm:C};if(!1!==this.config.useCache){const e=this.getFromLocalStorage();if(e)return this.waitReadyResolver(!0),{deviceInfo:e.data,tts:D,tm:C}}else this.config.debug&&Re.debug("Debug mode: skipping cache, fetching fresh data from iframe");if(!this.bridge)return{deviceInfo:null,tts:D,tm:C};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.deviceInfo&&this.saveToLocalStorage(e.deviceInfo),e}),(async()=>{Re.warn("Bridge unavailable, returning fallback device info");const e={deviceInfo:null,tts:D,tm:C};return Ae("SDK_BRIDGE_FALLBACK","SDK","bridge.executeWithFallback",{reason:"bridge unavailable",platformId:this.getId(),isInitialized:this.isInitialized}),e}))}catch(t){return Re.warn("Failed to get device info from bridge:",t),Ae("SDK_BRIDGE_FALLBACK","SDK","bridge.executeWithFallback",{reason:"bridge exception",platformId:this.getId(),isInitialized:this.isInitialized,error:t instanceof Error?t.message:String(t)}),{deviceInfo:null,tts:D,tm:C}}}isTV(){return"undefined"!=typeof window&&(navigator.userAgent.includes("TV")||navigator.userAgent.includes("SmartTV")||navigator.userAgent.includes("SMART-TV")||window.location.href.includes("file://"))}}const ke=new x,Oe=new x;function _e(){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 Ne(){try{if(void 0!==ke.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 Le(){try{const e=(new x).get("navigator"),t=void 0!==e&&"function"==typeof e.requestMediaKeySystemAccess,i=Oe.has("MSMediaKeys");return{supportWebSocket:Oe.has("WebSocket"),supportEME:t||i,hasStorage:Oe.has("localStorage")&&Oe.has("sessionStorage")}}catch(e){return{supportWebSocket:!1,supportEME:!1,hasStorage:!1}}}const Fe=new x;function xe(){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=Fe.has("MediaKeys"),i=Fe.has("WebKitMediaKeys"),n=Fe.has("MSMediaKeys");return e=t||i||n?"EME":e,{drmMethod:e}}catch(t){return{drmMethod:""}}}function Ue(){try{const e=Fe.has("MediaKeys"),t=Fe.has("WebKitMediaKeys"),i=Fe.has("MSMediaKeys");return{supportEME:e||t||i}}catch(e){return{supportEME:!1}}}const He=c("PhilipsCapabilities");async function Ve(e){const t=function(){try{const e={support3d:!1,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportUHD:!1,supportFHD:!0,supportHDR_HDR10:!1,supportHDR_DV:!1,supportHDR:"unknown",supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportAdobeHDS:!1,supportWidevineClassic:!1,supportDolbyAtmos:"unknown"},t=Ke.get("ols3DSupport");t&&t()&&(e.support3d=!0);const i=Ke.get("olsAtmosSupport");i&&"function"==typeof i&&i()?e.supportDolbyAtmos=!0:e.supportDolbyAtmos=!1,e.supportKeyNumeric=!0,e.supportKeyColor=!0,e.supportMultiscreen=!1,e.supportMultiAudio=!0,e.supportTTMLInband=!0,e.supportTTMLOutofband=!0,e.supportFHD=!0;const n=Ke.get("olsUHD");n&&n()&&(e.supportUHD=n()),e.supportHDR_HDR10=!0;const r=Ke.get("olsDVSupport");return r&&r()&&(e.supportHDR_DV=!0),e.supportHDR=e.supportHDR_HDR10||e.supportHDR_DV||!1,e}catch(e){return He.error("Error detecting SmartTV API capabilities:",e),{support3d:!1,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportUHD:!1,supportFHD:!0,supportHDR_HDR10:!1,supportHDR_DV:!1,supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportAdobeHDS:!1,supportHDR:"unknown",supportWidevineClassic:!1,supportDolbyAtmos:"unknown"}}}();return{os:"Linux",browserEngine:"Blink",...t,...Le(),..._e(),...xe(),...Ue(),...Ne(),supportFairplay:!1,supportPrimetime:!1,supportClearKey:!0,supportPlayready:!0,supportWidevineModular:!0}}const Ke=new x;const Be=c("PhilipsCompat");class ze extends Me{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:H(),language:"en"}};constructor(e,t){super(e,t)}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product},i=this.formatBridgeResponse(e,t),n=(i.Product.platform,await Ve());return{...i,Capability:n}}catch(e){throw Be.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.mac||Ae("SDK_BRIDGE_NO_MAC","SDK","formatBridgeResponse",{deviceInfo:e.deviceInfo}),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 $e=c("PhilipsDeviceInfoService");class Ge{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 $e.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const je=c("PhilipsAppControlService");class We{bridge;constructor(e){this.bridge=e}async launch(e,t){return await this.bridge.executeWithFallback((()=>this.bridge.launchApp({appId:e,deepLink:t})),(async()=>(je.warn("Function unavailable, app launch failed gracefully",{appId:e,deepLink:t}),!1)))}}const qe=e=>{const{available:t,...i}=e;if("scale"in i){const{enabled:e,scale:t}=i;return{enabled:e,...void 0!==t&&{scale:t}}}const{enabled:n}=i;return{enabled:n}};class Qe{subscribe(e,t){const i=l(e,t);return()=>{d(i)}}getHistory(){return u()}clear(){g()}}class Ye{bridge;accessibilityService;deviceInfoService;appControlService;constructor(e,t,i,n){this.bridge=e,this.accessibilityService=t,this.deviceInfoService=i,this.appControlService=n}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()=>qe(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>qe(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange((t=>{e(qe(t))})),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange((t=>{e(qe(t))}))};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new Qe}get dev(){return{isBridgeConnected:async()=>{try{return this.bridge.isConnected()}catch(e){return!1}}}}}const Je=c("PhilipsSDK");class Ze extends Ye{constructor(e){const t=new ne({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new pe(t),new Ge(e,t),new We(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),await this.bridge.waitForInitializationAttempt(),this.bridge.isConnected()||Je.warn("Bridge initialization completed but bridge is not connected. Some features may not work correctly."),!0}catch(e){throw Je.error("TitanSDK initialization failed:",e),e}}}const Xe=c("ChromeTTS");class et{voices=[];currentVoice=null;settings={available:!0,enabled:!0,rate:1,volume:1};speechSynthesis;constructor(){const e=new x;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,o;if(!("speechSynthesis"in window))return;const s=null==(e=this.speechSynthesis)?void 0:e.getVoices();this.voices=null==s?void 0:s.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]),Xe.info(`Initialized with ${null==(r=this.voices)?void 0:r.length} voices, using ${null==(o=this.currentVoice)?void 0:o.voiceName}`)}getTTSSettings(){return this.settings}getTMSettings(){return{available:!0,enabled:!1,scale:1}}getSettings(){return{tts:this.getTTSSettings(),tm:this.getTMSettings()}}startSpeaking(e){return Xe.info("Starting speaking:",e),!(!("speechSynthesis"in window)||!e||0===e.length)&&(e.forEach(((e,t)=>{var i,n,r,o;if(!e)return;const s=new SpeechSynthesisUtterance(e);if(s.rate=this.settings.rate??1,s.volume=this.settings.volume??1,s.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&&(s.voice=e)}0===t&&(null==(r=this.speechSynthesis)||r.cancel()),null==(o=this.speechSynthesis)||o.speak(s)})),!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 tt=c("VestelTTS"),it=e=>({available:!0,enabled:e.enabled,rate:e.rate,pitch:e.pitch,volume:e.level});class nt extends et{vestelSettings={available:!0,enabled:!1,rate:1,volume:1};windowApi=new x;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 tt.warn("TTSHelper not available during initialization");const n={onSuccess:e=>{this.vestelSettings=it(e),this.settingsInitialized=!0},onError:e=>{tt.error("Error initializing TTS settings:",e),this.settingsInitialized=!0}},r={onSuccess:e=>{this.vestelSettings=it(e)},onError:e=>{tt.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=>{tt.info("Current TTS settings:",e,e.toString()),this.vestelSettings=it(e)},onError:e=>{tt.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 tt.warn("TTSHelper not available"),()=>{};const n={onSuccess:t=>{tt.info("TTS settings changed:",t,t.toString()),e(it(t)),this.settingsInitialized=!0},onError:e=>{tt.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 rt=c("AccessibilityService");class ot{tts;reader=null;constructor(){this.tts=new nt}async startSpeaking(e){if("string"==typeof e&&(e=[e]),await this.isTTSEnabled())try{return this.tts.startSpeaking(e),!0}catch(t){return rt.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 rt.warn("Cannot enable Reader: TTS not supported"),!1;if(!(await this.isTTSEnabled()))return rt.warn("Cannot enable Reader: TTS not enabled"),!1;this.reader=new ge(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(rt.info("Reader enabled"),!0)}catch(t){return rt.error("Error enabling Reader:",t),!1}}async disableReader(){try{if(this.reader){const e=await this.reader.stop();return this.reader=null,e&&rt.info("Reader disabled"),e}return rt.debug("Reader was not active"),!0}catch(e){return rt.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 rt.error("Error checking TTS support:",e),!1}}async isTextMagnificationSupported(){try{return(await this.getTMSettings()).available}catch(e){return rt.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}}function st(e){const t=function(){var e;try{const t=document.createElement("object");t.style.display="none",t.setAttribute("id","sysinfo"),t.setAttribute("type","systeminfoobject"),document.body.appendChild(t);const i=t;return{support3d:Boolean(i.has3D),supportUHD:"3840x2160"===(null==(e=i.panelinfo)?void 0:e.toLowerCase()),supportFHD:!0}}catch(t){return{support3d:!1,supportUHD:!1,supportFHD:!0}}}(),i=Le(),n=_e(),r=xe(),o=Ue(),s=Ne(),a={os:"Linux",browserEngine:"Blink",hasStorage:!0,support3d:!1,supportUHD:!0,supportFHD:!0,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,supportKeyNumeric:!0,supportKeyColor:!0,supportFairplay:!1,supportAdobeHDS:!1,supportPrimetime:!1,supportClearKey:!0,supportWidevineClassic:!0,supportDolbyAtmos:!0,supportMultiscreen:!0,supportMultiAudio:!0,supportTTMLInband:!0,supportTTMLOutofband:!0};return"MB191"===e&&(a.supportHDR_DV=!1,a.supportHDR_HDR10=!0,a.supportDolbyAtmos=!1),{...a,...t,...i,...n,...r,...o,...s}}const at=c("VestelCompat");class ct extends Me{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:H(),language:"en"}};constructor(e,t){super(e,t)}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=await this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product},i=this.formatBridgeResponse(e,t),n=st(i.Product.platform);return{...i,Capability:n}}catch(e){at.error("Error getting device info:",e);const t=st();return{Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product,Capability:t}}}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 lt=c("VestelDeviceInfoService");class dt{platform;info;bridge;constructor(e,t){this.platform=new ct(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 lt.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const ut=c("VestelAppControlService");class gt{bridge;constructor(e){this.bridge=e}async launch(e,t){return await this.bridge.executeWithFallback((()=>this.bridge.launchApp({appId:e,deepLink:t})),(async()=>(ut.warn("Function unavailable, app launch failed gracefully",{appId:e,deepLink:t}),!1)))}}const ht=c("VestelSDK");class pt extends Ye{constructor(e){const t=new te({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new ot,new dt(e,t),new gt(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),!0}catch(e){throw ht.error("TitanSDK initialization failed:",e),e}}}const ft=c("GeocodingService");class mt{static REQUEST_TIMEOUT=5e3;static MAX_RETRIES=1;static async getCountry(){try{return await this.fetchWithRetry()}catch(e){return ft.warn("Failed to get country from geocoding service:",e),"UNKNOWN"}}static async fetchWithRetry(){let e=null;for(let i=0;i<=this.MAX_RETRIES;i++)try{const e=await this.fetchFromAPI();if("UNKNOWN"!==e)return e}catch(t){e=t,i<this.MAX_RETRIES&&(ft.debug(`Geocoding attempt ${i+1} failed, retrying...`),await new Promise((e=>setTimeout(e,500))))}if(e)throw e;return"UNKNOWN"}static async fetchFromAPI(){if("undefined"==typeof window||void 0===window.fetch)throw new Error("Fetch API is not available");const e=new AbortController,t=setTimeout((()=>e.abort()),this.REQUEST_TIMEOUT);try{const i="https://geoip.app.titanos.tv/",n=await window.fetch(i,{method:"GET",signal:e.signal,headers:{Accept:"application/json"}});if(clearTimeout(t),!n.ok)throw new Error(`Geocoding API returned status ${n.status}: ${n.statusText}`);const r=await n.json();if(!r||"string"!=typeof r.market)throw new Error("Invalid geocoding response format");const o=r.market.toUpperCase();return ft.debug("Country fetched from geocoding service:",o),o}catch(i){if(clearTimeout(t),i instanceof Error){if("AbortError"===i.name)throw new Error("Geocoding request timeout");throw i}throw new Error("Unknown error during geocoding request")}}}const vt=c("VestelLegacyOIPFService");class St{cachedOIPFObject=null;getOIPFObject(){if(this.cachedOIPFObject)return this.cachedOIPFObject;if("undefined"==typeof document)return vt.warn("Document not available for OIPF access"),null;try{const e=document.createElement("object");return e.type="application/oipfConfiguration",e.style.display="none",document.body.appendChild(e),this.cachedOIPFObject=e,e}catch(e){return vt.warn("Failed to create OIPF object:",e),null}}async accessOIPFObject(e){try{const t=this.getOIPFObject();return t?e(t):null}catch(t){return vt.warn("Failed to access OIPF object:",t),null}}cleanup(){if(this.cachedOIPFObject&&this.cachedOIPFObject.parentNode)try{document.body.removeChild(this.cachedOIPFObject)}catch(e){vt.warn("Failed to cleanup OIPF object:",e)}this.cachedOIPFObject=null}async getMACAddress(){return this.accessOIPFObject((e=>{var t,i;let n=(null==(t=e.configuration)?void 0:t.macAddress)||(null==(i=e.localSystem)?void 0:i.serialNumber)||null;return n&&function(e){if(!e||"string"!=typeof e)return!1;const t=e.replace(/[:\-\.]/g,"").toUpperCase();return/^[0-9A-F]{12}$/.test(t)}(n)?(vt.debug("MAC address retrieved from OIPF:",n),n):(n&&vt.debug("MAC address format invalid:",n),null)}))}async getFirmwareVersion(){return this.accessOIPFObject((e=>{var t;const i=(null==(t=e.localSystem)?void 0:t.softwareVersion)||null;return i?(vt.debug("Firmware version retrieved from OIPF:",i),i):null}))}async getCountryId(){return this.accessOIPFObject((e=>{var t;const i=(null==(t=e.configuration)?void 0:t.countryId)||null;return i?(vt.debug("Country ID retrieved from OIPF:",i),i):null}))}}const yt=c("VestelLegacyCompat"),bt={alb:"AL",arg:"AR",arm:"AM",aut:"AT",aze:"AZ",bhs:"BS",blr:"BY",bel:"BE",bra:"BR",bgr:"BG",chl:"CL",col:"CO",cri:"CR",hrv:"HR",cze:"CZ",dnk:"DK",ecu:"EC",slv:"SV",est:"EE",fin:"FI",fra:"FR",geo:"GE",deu:"DE",grc:"GR",gtm:"GT",hnd:"HN",hun:"HU",isl:"IS",irl:"IE",isr:"IL",ita:"IT",kaz:"KZ",lva:"LV",lie:"LI",ltu:"LT",lux:"LU",mne:"ME",nld:"NL",nic:"NI",mkd:"MK",nor:"NO",pry:"PY",per:"PE",pol:"PL",prt:"PT",rou:"RO",rus:"RU",smr:"SM",srb:"RS",svk:"SK",svn:"SI",esp:"ES",swe:"SE",che:"CH",tur:"TR",ukr:"UA",gbr:"GB",ury:"UY"};class wt extends Me{deviceInfo=null;deviceInfoPromise=null;oipfService=new St;DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"Vestel",brand:"JVC"},Product:{platform:"TitanOS",year:"2025",deviceID:"vestel-legacy-device",firmwareVersion:"0.0.0.0",firmwareComponentID:"",mac:"",WhaleAdID:H(),language:"en"}};constructor(e,t){super(e,null)}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent,t=e.toLowerCase(),i=t.includes("vestel"),n=e.includes("MB181")||e.includes("MB180")||t.includes("mb181")||t.includes("mb180")||e.includes("Model/Vestel-MB181")||e.includes("Model/Vestel-MB180");return i&&n}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product};if(!e.deviceInfo){const e=await this.fetchDeviceInfoFromOIPF();if(e){this.saveToLocalStorage(e);const i=this.formatBridgeResponse({deviceInfo:e,tts:D,tm:C},t),n=i.Product.platform,r=await st(n);return{...i,Capability:r}}const i=await st();return{...t,Capability:i}}const i=this.formatBridgeResponse(e,t),n=i.Product.platform,r=await st(n);return{...i,Capability:r}}catch(e){yt.warn("Error getting device info:",e);const t=await st();return{Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product,Capability:t}}}async fetchDeviceInfoFromOIPF(){try{const e=this.parseUserAgent(),t=await this.oipfService.getMACAddress(),i=await this.oipfService.getFirmwareVersion();let n=await this.getCountryFromGeocoding();if(!n||"UNKNOWN"===n){const e=await this.oipfService.getCountryId();n=e?this.convertOIPFCountryToISO(e):"UNKNOWN"}const r=t||H(),o=i||e.firmwareVersion,s={profileId:`vestel_legacy_${e.boardName}`,deviceId:r,model:e.boardName,year:e.deviceYear,firmwareVersion:o,country:n,language:$("en"),brand:F.VESTEL,platformName:F.VESTEL,mac:t||"",ifa:"",ifaType:""};return yt.debug("Device info fetched from OIPF:",s),s}catch(e){return yt.warn("Error fetching device info from OIPF:",e),null}}parseUserAgent(){var e;const t=navigator.userAgent;let i=t.match(/Model\/Vestel-(MB\d{3})/i);i||(i=t.match(/MB\d{3}/i));const n=i?(null==(e=i[1])?void 0:e.toUpperCase())||i[0].toUpperCase():"MB181";let r=t.match(/(\d+\.\d+\.\d+\.\d+)/);r||(r=t.match(/(\d+\.\d+\.\d+)/));const o=r?r[1]:"0.0.0.0";let s=t.match(/_TV_[^_]+_(\d{4})_/);s||(s=t.match(/(20\d{2})/));return{boardName:n,firmwareVersion:o,deviceYear:s?s[1]:"2025"}}async getCountryFromGeocoding(){try{const e=await mt.getCountry();return yt.debug("Country retrieved from geocoding service:",e),e}catch(e){return yt.warn("Failed to get country from geocoding service:",e),"UNKNOWN"}}convertOIPFCountryToISO(e){if(!e||"string"!=typeof e)return"UNKNOWN";const t=e.toLowerCase().trim(),i=bt[t];return i?(yt.debug(`Converted OIPF country code '${e}' to ISO '${i}'`),i):/^[A-Z]{2}$/.test(e)?e:(yt.warn(`Unknown OIPF country code '${e}', returning as is`),e.toUpperCase())}formatBridgeResponse(e,t){return e.deviceInfo?(t.Product.firmwareVersion=e.deviceInfo.firmwareVersion,t.Product.country=e.deviceInfo.country,t.Product.deviceID=e.deviceInfo.deviceId,t.Product.platform=e.deviceInfo.model,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=e.deviceInfo.profileId||"",t):t}getPriority(){return 95}getId(){return"vestel-legacy"}}class Tt{platform;info=null;bridge;isInitialized=!1;constructor(e,t){this.platform=e,this.bridge=t}async initialize(){try{this.getLogger().debug("Initializing Device Info Service"),await this.getDeviceInfo(),this.isInitialized=!0,this.getLogger().debug("Device Info Service initialized")}catch(e){throw this.getLogger().error("Failed to initialize Device Info Service:",e),e}}async getDeviceInfo(){try{const e=await this.platform.getDeviceInfo();return this.info=e,this.info}catch(e){throw this.getLogger().error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}isReady(){return this.isInitialized&&null!==this.info}}const It=c("VestelLegacyDeviceInfoService");class Et extends Tt{constructor(e){super(new wt(e))}getLogger(){return It}}const Dt=c("VestelLegacyAccessibilityService");class Ct{reader=null;async startSpeaking(e){return!1}async stopSpeaking(){return!1}async enableReader(e){return Dt.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 D}async getTMSettings(){return C}async isTTSEnabled(){return!1}async isTMEnabled(){return!1}}const At=c("VestelLegacyAppControlService");class Pt{async launchApp(e,t){return At.warn("App launching not supported on legacy Vestel devices"),!1}}const Rt=c("VestelLegacySDK");class Mt{accessibilityService;deviceInfoService;appControlService;loggingService;constructor(e){this.accessibilityService=new Ct,this.deviceInfoService=new Et(e),this.appControlService=new Pt,this.loggingService=new Qe}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()=>qe(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>qe(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>()=>{},onTMSettingsChange:e=>()=>{}};apps={launch:async(e,t)=>{try{return await this.appControlService.launchApp(e,t),!0}catch(i){return Rt.error("Failed to launch app:",i),!1}}};get logging(){return this.loggingService}async init(){try{return Rt.debug("Initializing Vestel Legacy SDK"),await this.deviceInfoService.initialize(),Rt.debug("Vestel Legacy SDK initialized successfully"),!0}catch(e){return Rt.error("Failed to initialize Vestel Legacy SDK:",e),!1}}async getCapabilities(){return this.deviceInfoService.getCapabilities()}isReady(){return this.deviceInfoService.isReady()}getVersion(){return"1.0.0"}getPlatform(){return"vestel-legacy"}}const kt="titanSDK_tts_settings",Ot="titanSDK_tm_settings",_t=c("BrowserAccessibilityService");class Nt{reader=null;chromeTTS;windowMock;mockStorage;ttsSettings;tmSettings;constructor(e,t,i=!1){this.windowMock=e,this.mockStorage=t,this.chromeTTS=new et,this.ttsSettings=this.loadTTSSettings(),this.tmSettings=this.loadTMSettings()}loadTTSSettings(){try{const e=localStorage.getItem(kt);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(kt,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 _t.info("TTS is disabled in settings"),!1;const t=Array.isArray(e)?e.join(" "):e,i=this.chromeTTS.startSpeaking([t]);return i&&_t.info("🔊 Speaking:",t),i}catch(t){return _t.error("Error starting speech:",t),!1}}async stopSpeaking(){try{const e=this.chromeTTS.stopSpeaking();return e&&_t.info("🔇 Speech stopped"),e}catch(e){return _t.error("Error stopping speech:",e),!1}}async enableReader(e){try{if(!(await this.isTTSSupported()))return _t.warn("Cannot enable Reader: TTS not supported"),!1;this.reader=new ge(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(_t.info("Reader enabled"),!0)}catch(t){return _t.error("Error enabling Reader:",t),!1}}async disableReader(){try{return!!this.reader&&(await this.reader.stop(),this.reader=null,_t.info("Reader disabled"),!0)}catch(e){return _t.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(),_t.info("TTS settings updated:",this.ttsSettings)}updateTMSettings(e){this.tmSettings={...this.tmSettings,...e},this.saveTMSettings(),_t.info("TM settings updated:",this.tmSettings)}}const Lt=c("BrowserPlatform");class Ft extends fe{constructor(e){super(e),this.waitReady=new Promise((e=>{this.waitReadyResolver=e})),this.waitReadyResolver(!0)}async canHandle(){return!0}async getDeviceInfo(){return Lt.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,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportFHD:!1,supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportFairplay:!1,supportAdobeHDS:!1,supportPrimetime:!1,supportClearKey:!1,supportWidevineClassic:!1,supportDolbyAtmos:!1,supportHDR_HDR10:!1,supportHDR_DV:!1}}}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 xt=c("BrowserDeviceInfoService");class Ut{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 Ft(n)}async getDeviceInfo(){try{const e=await this.platform.getDeviceInfo();return this.info=e,this.info}catch(e){throw xt.error("Error getting device info:",e),e}}async getCapabilities(){try{return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}catch(e){throw xt.error("Error getting device capabilities:",e),e}}}const Ht=c("BrowserAppControlService");class Vt{windowMock;constructor(e){this.windowMock=e}async launch(e,t){Ht.debug(`Launching app: ${e} with deepLink: ${t||"none"}`);const r=this.windowMock||window;if(!r||"function"!=typeof r.open)throw new n("Cannot open new window for app launch (window.open not available)",i.NOT_SUPPORTED,{operation:"launch",appId:e,deepLink:t,platform:"browser"});try{return r.open(t||e,"_blank"),Ht.info(`Opened new tab for app: ${e}`),!0}catch(o){throw Ht.error("Error opening new window for app launch:",o),new n(`Failed to launch app: ${e}`,i.COMMUNICATION_ERROR,{operation:"launch",appId:e,deepLink:t,platform:"browser",originalError:o})}}}const Kt=c("BrowserSDK");class Bt{accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new Nt(null==e?void 0:e.windowMock,null==e?void 0:e.mockStorage,(null==e?void 0:e.dev)||!1),this.deviceInfoService=new Ut(e,null==e?void 0:e.windowMock,null==e?void 0:e.mockStorage),this.appControlService=new Vt(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)&&Kt.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()=>qe(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>qe(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange((t=>{e(qe(t))})),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange((t=>{e(qe(t))}))};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new Qe}get dev(){const e={simulateError(e){switch(e){case"sdk":{const e=new n("Test SDK error for Rollbar integration",i.UNKNOWN,{operation:"dev-api-sdk-error",component:"SDK"});throw Ee.reportError(e,{operation:"dev-api-sdk-error",component:"SDK"}),e}case"bridge":{const e=new n("Test bridge communication error",i.COMMUNICATION_ERROR,{operation:"dev-api-bridge-error",component:"SDK"});return Ee.reportError(e,{operation:"dev-api-bridge-error",component:"SDK"}),Promise.reject(e)}case"async":return new Promise(((e,t)=>{setTimeout((()=>{const e=new n("Test async error after timeout",i.TIMEOUT,{operation:"dev-api-async-error",component:"SDK"});Ee.reportError(e,{operation:"dev-api-async-error",component:"SDK"}),t(e)}),100)}));default:{const t=new n(`Unknown error type: ${e}`,i.UNKNOWN,{operation:"dev-api-unknown-error",component:"SDK"});throw Ee.reportError(t,{operation:"dev-api-unknown-error",component:"SDK"}),t}}},async simulateGatewayError(e,t){const r=new n(`Gateway error simulation not supported in browser platform. Error type: ${e}, message: ${t||"default"}`,i.NOT_SUPPORTED,{operation:"dev-api-gateway-error",component:"SDK"});throw Ee.reportError(r,{operation:"dev-api-gateway-error",component:"SDK"},"critical"===e?"critical":"error"),r}};return{updateTTSSettings:e=>{this.accessibilityService.updateTTSSettings(e)},updateTMSettings:e=>{this.accessibilityService.updateTMSettings(e)},simulateError:e.simulateError,simulateGatewayError:e.simulateGatewayError}}async init(){try{return Kt.debug("BrowserSDK initialization started"),Kt.info("BrowserSDK initialized successfully"),!0}catch(e){throw Kt.error("BrowserSDK initialization failed:",e),e}}}class zt extends ze{DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"HKC",brand:"JVC"},Product:{platform:"TitanOS",year:"2026",deviceID:"jvc-device",firmwareVersion:"1.0.0",firmwareComponentID:"",mac:"",WhaleAdID:H(),language:"en"}};constructor(e,t){super(e,t)}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent.toLowerCase();return["hkc","jvc"].some((t=>e.includes(t)))}getId(){return"jvc"}}const $t=c("JVCDeviceInfoService");class Gt{platform;info;bridge;constructor(e,t){this.platform=new zt(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 $t.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const jt=c("JVCSDK");class Wt extends Ye{constructor(e){const t=new ne({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new pe(t),new Gt(e,t),new We(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),await this.bridge.waitForInitializationAttempt(),this.bridge.isConnected()||jt.warn("Bridge initialization completed but bridge is not connected. Some features may not work correctly."),!0}catch(e){throw jt.error("TitanSDK initialization failed:",e),e}}}const qt=c("AccessibilityService");class Qt{reader=null;async startSpeaking(e){return!1}async stopSpeaking(){return!1}async enableReader(e){return qt.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 D}async getTMSettings(){return C}async isTTSEnabled(){return!1}async isTMEnabled(){return!1}}const Yt=c("PhilipsLegacyPlatform");class Jt extends Me{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:H(),language:"en"}};constructor(e,t){super(e,null)}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product};if(!e.deviceInfo){const e=await this.fetchDeviceInfo();if(e){this.saveToLocalStorage(e);const i=this.formatBridgeResponse({deviceInfo:e,tts:D,tm:C},t),n=(i.Product.platform,await Ve());return{...i,Capability:n}}const i=await Ve();return{...t,Capability:i}}const i=this.formatBridgeResponse(e,t),n=(i.Product.platform,await Ve());return{...i,Capability:n}}catch(e){throw Yt.warn("Error getting device info:",e),e}}async fetchDeviceInfo(){var e;try{const t="app.titanos.tv",i=await Promise.race([U(0,t,"zeasn"),new Promise((e=>{setTimeout((()=>{Yt.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:$("en"),brand:F.PHILIPS,platformName:F.PHILIPS,mac:decodeURIComponent(i.datas.cookies.mac||""),ifa:"",ifaType:""}}catch(t){return Yt.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 Zt{platform;info;constructor(e){this.platform=new Jt(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 Xt{async launch(e,t){return!1}}class ei{accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new Qt,this.deviceInfoService=new Zt(e),this.appControlService=new Xt}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()=>qe(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>qe(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 Qe}async init(){return!0}}const ti=c("SmartTvA_API"),ii=(e,t)=>{var i,n,r,o;try{if(!t)return ti.warn(`Device info not available, cannot check capability: ${e}`),!1;const s=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=s.platform)?void 0:i.toLowerCase().includes("dolby"))||(null==(n=a.brand)?void 0:n.toLowerCase().includes("dolby"))));case"atmos":return Boolean((null==(r=s.platform)?void 0:r.toLowerCase().includes("atmos"))||(null==(o=a.brand)?void 0:o.toLowerCase().includes("dolby")));default:return ti.warn(`Unknown device capability: ${e}`),!1}}catch(s){return ti.error(`Error checking device capability ${e}:`,s),!1}},ni=async e=>{if("undefined"==typeof window)return void ti.warn("Window object not available, cannot attach SmartTvA_API");if("object"==typeof window.SmartTvA_API)return void ti.info("SmartTvA_API already exists on window, skipping initialization");const t=await(async e=>{ti.info("Initializing SmartTvA_API with TitanSDK");let t=null;try{ti.info("Waiting for device info to be ready..."),t=await e.deviceInfo.getDeviceInfo(),ti.info("Device info is ready, proceeding with SmartTvA_API initialization")}catch(i){ti.warn("Failed to get device info during SmartTvA_API initialization:",i)}return{exit:()=>{ti.info("SmartTvA_API.exit() called"),window.close()},hasCapability:(e,...i)=>{switch(ti.debug(`SmartTvA_API.hasCapability('${e}', ${i.join(", ")})`),e){case"3DSupport":return ii("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 ii("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(!ii("uhd",t))return!1;switch(e){case"HDR10":case"DA":case"HDR10+":return!0;case"DV":return ii("dolby-vision",t);default:return!1}}return!1;case"8K":case"WidevineClassic":case"AdobeHDS":return!1;case"ATMOS":return ii("atmos",t);default:return ti.warn(`Unknown capability requested: ${e}`),!1}}}})(e);Object.defineProperty(window,"SmartTvA_API",{value:t,writable:!1,configurable:!0}),ti.info("SmartTvA_API successfully attached to window object")},ri=c("WrapperUtils");function oi(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=>{ri.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=>{ri.error("Failed to set up TM settings change handler:",e)})),()=>{i&&i()}}}}function si(e){return{launch:async(t,i)=>(await e()).apps.launch(t,i)}}const ai=c("AnalyticsService");class ci{sdkVersion;constructor(e){this.sdkVersion=e}getEventUrl(){return"https://sdk.titanos.tv/events"}async track(e){if("undefined"==typeof window||void 0===window.fetch)return Promise.resolve();try{const t={event_name:e.eventName,event_type:e.eventType,event_params:e.eventParams,event_timestamp:(new Date).toISOString().replace("T"," ").slice(0,-1)};await window.fetch(this.getEventUrl(),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(t){ai.warn("TitanSDK: Usage tracking event failed to send.",t)}}trackUsage(){const e={eventName:"sdk",eventType:"sdk-initialized",eventParams:{appHostname:window.location.hostname,sdkVersion:this.sdkVersion}};return this.track(e)}}const li=c("SDK"),di={debug:!1,useLegacyDeviceInfo:!1,legacyDeviceInfoTimeout:5e3,fallbackToBrowser:!0},ui="TITAN_SDK_USAGE_SENT";let gi=null,hi=null,pi=null,fi=null,mi=!1;const vi=async()=>{if(!gi)throw new n("SDK not created. Call getTitanSDK() first.",i.NOT_INITIALIZED);if(!pi)throw li.error("SDK initialization not started"),new n("SDK initialization not started.",i.NOT_INITIALIZED);if(!(await pi))throw new n("SDK initialization failed.",i.UNKNOWN);return gi},Si=e=>{if(hi)return hi;const r={...di,...e};if(s.setDebugMode(r.debug??!1),!mi){const e="",t=!1;Ee.initialize({accessToken:e,enabled:t}),mi=!0}const o=T.detectPlatform(r).platform;li.info("Platform detected:",o);try{switch(o){case t.JVC:gi=new Wt(r);break;case t.PHILIPS:gi=new Ze(r);break;case t.PHILIPS_OLD:gi=new ei(r);break;case t.VESTEL:gi=new pt(r);break;case t.VESTEL_LEGACY:gi=new Mt(r);break;case t.BROWSER:default:o!==t.BROWSER&&r.debug&&li.warn(`Platform ${o} detected but no specific SDK found, using BrowserSDK as fallback.`),gi=new Bt(r)}if(!gi)throw new n("Failed to create SDK instance after platform detection",i.UNKNOWN)}catch(d){throw li.error("Error creating SDK instance:",d),new n(`Failed to create SDK instance after platform detection: ${d}`,i.UNKNOWN)}pi=gi.init(),li.info("SDK Version:",we);const a={VERSION:we,isReady:pi,deviceInfo:(c=vi,l=e=>{fi=e},{getDeviceInfo:async()=>{const e=await c(),t=await e.deviceInfo.getDeviceInfo();return null==l||l(t),t}}),accessibility:oi(vi),apps:si(vi)};var c,l;return r.debug&&(li.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=>{ri.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()}}}(vi)),r.dev&&(r.debug&&li.info("🔧 [DEV MODE] TitanSDK dev access enabled"),o===t.BROWSER&&r.dev&&(li.info("Available dev methods:"),li.info(" sdk.dev.updateTTSSettings({ enabled: true, rate: 1.5 })"),li.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}}}(vi)),hi=a,pi.then((async()=>{try{fi=await gi.deviceInfo.getDeviceInfo();const e=new ci(we);if(!(()=>{try{return!("undefined"==typeof window||!window.localStorage)&&"1"===window.localStorage.getItem(ui)}catch{return!1}})())try{await e.trackUsage(),(()=>{try{if("undefined"==typeof window||!window.localStorage)return;window.localStorage.setItem(ui,"1")}catch{}})()}catch{}}catch(d){r.debug&&li.warn("Failed to pre-cache device info:",d)}})).catch((e=>{li.error(`Initialization failed for platform ${o}:`,e)})),hi},yi=async()=>{const e=await vi(),t=await e.deviceInfo.getDeviceInfo();return fi=t,t};if("undefined"!=typeof document&&document.addEventListener("securitypolicyviolation",(e=>{J.getViolations()})),"undefined"!=typeof window)if(window.TitanSDK&&window.TitanSDK.deviceInfo)li.info("TitanSDK already exists on window, skipping initialization"),li.info("You can still create a new SDK instance using window.getTitanSDK(options)"),window.getTitanSDK=Si;else{const e=()=>{window.onDeviceInfoReady=function(e){yi().then((t=>e(t))).catch((t=>e({},String(t))))},Object.defineProperty(window,"DeviceInfo",{get:()=>{if(fi)return fi;if(gi&&hi)try{return gi.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=>{try{const t=null==localStorage?void 0:localStorage.getItem(e);return t?JSON.parse(t):{}}catch(t){return s.isDebugMode()&&li.error(`Failed to parse localStorage key ${e}:`,t),{}}},i=(new x).get("TITAN_SDK_PARAMS")||t("TITAN_SDK_PARAMS");i&&li.info("Initializing TitanSDK with params:",i),window.TitanSDK=Si(i),e(),ni(window.TitanSDK).catch((e=>{li.error("Failed to initialize SmartTvA_API:",e)}))}exports.VERSION=we,exports.getDeviceInfo=yi,exports.getTitanSDK=Si;
|
|
1
|
+
"use strict";var e=Object.defineProperty;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var t=(e=>(e.PHILIPS="PHILIPS",e.PHILIPS_OLD="PHILIPS_OLD",e.JVC_VESTEL="JVC_VESTEL",e.JVC_VESTEL_LEGACY="JVC_VESTEL_LEGACY",e.JVC_HKC="JVC_HKC",e.AOC="AOC",e.BROWSER="BROWSER",e.UNKNOWN="UNKNOWN",e))(t||{});function i(e,t,i,n){return[`${`[TitanSDK][${e}]`} ${t}`,...i,"\n",n]}function n(e,t){e}const r=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){var t,r,o;this.logBuffer.push(e),this.logBuffer.length>this.maxBufferSize&&this.logBuffer.shift();if(("Gateway"===(null==(t=e.metadata)?void 0:t.source)||!0===(null==(r=e.metadata)?void 0:r.tunneled))&&"error"===e.level){const t=(null==(o=e.metadata)?void 0:o.caller)||"[Gateway]";n("error",i(e.module,e.message,e.args||[],t))}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,o,...s)=>{var a;const c=(()=>{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""}})(),l=(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:o}=(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}[${o}]`:`[${o}]`}catch{return"Unknown location"}})(new Error),d={id:`${e}-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,timestamp:Date.now(),level:t,module:e,message:o,args:s,metadata:{url:"undefined"!=typeof window?null==(a=window.location)?void 0:a.href:void 0,caller:c}};r.addLogEntry(d);if(r.isDebugMode()||"error"===t){i(e,o,s,l);n(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)=>r.subscribe(e,t),unsubscribe:e=>r.unsubscribe(e),getHistory:(e,t,i)=>r.getHistory(e,t,i),clear:()=>r.clear()}}function s(e){return o(e)}const a=(e,t)=>r.subscribe(e,t),c=e=>r.unsubscribe(e),l=(e,t,i)=>r.getHistory(e,t,i),d=()=>r.clear(),u=e=>r.addLogEntry(e);class g{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 h(e,t,i="titanos"){return new Promise((e,n)=>{const r=new g,o="deviceInfoCallback_"+Date.now()+"_"+Math.floor(1e4*Math.random());r.create(o,t=>{e(t),r.removeGlobal(o)});const s=`https://${t}/potamoi/v1/device_info?callback=${o}`,a=`https://smarttv.zeasn.tv/homepage_api/device/clientInfo?callback=${o}`,c=document.createElement("script");c.src="titanos"===i?s:a,c.type="text/javascript",c.onerror=()=>{n(new Error("Failed to load device info script.")),delete r.proxy[o]},document.head.appendChild(c),setTimeout(()=>{r.has(o)&&(n(new Error("Device info request timed out.")),delete r.proxy[o]),c.parentNode&&c.parentNode.removeChild(c)},7e3)})}const p=()=>{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)},f=1e4,m=[{time:3e4,message:"DOM still not ready after 30 seconds"},{time:6e4,message:"DOM still not ready after 1 minute"},{time:12e4,message:"DOM still not ready after 2 minutes"},{time:18e4,message:"DOM still not ready after 3 minutes"},{time:24e4,message:"DOM still not ready after 4 minutes"},{time:3e5,message:"DOM still not ready after 5 minutes - this may indicate serious page issues"}],v=s("DOM-Utils");function S(){return"undefined"!=typeof document&&!!document.body}const y=(e="en-US")=>"undefined"!=typeof navigator&&navigator.language&&navigator.language||e;function b(e){return e.includes("MB190")||e.includes("MB191")||/MB19[01]/.test(e)}function w(e){return e.toLowerCase().includes("jvc")||/\(JVC[,\s)]/.test(e)||/JVC[-_]/.test(e)}const T="1.10.0";var I=(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))(I||{});class E 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,E)}toString(){return`SDKError [${this.code}]: ${this.message}`}toJSON(){return{name:this.name,code:this.code,message:this.message,details:this.details}}}const D=s("RollbarClient"),C=["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 A=new class{config=null;windowWrapper=new g;lastAPICallTime=0;API_THROTTLE_MS=1e3;sessionId="";isSDKError(e){return e instanceof E||e instanceof Error&&"SDKError"===e.name}initialize(e){if(this.config=e,!e.enabled)return D.info("Rollbar disabled - error reporting will be skipped"),void(this.sessionId=this.generateSessionId());this.sessionId=this.generateSessionId(),e.accessToken?D.info("Rollbar initialized - using API",{environment:e.environment||"development",sessionId:this.sessionId}):D.info("Rollbar initialized without token - will use API with Nginx proxy (server should add 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 C.some(e=>(null==t?void 0:t.toLowerCase().includes(e.toLowerCase()))||(null==i?void 0:i.toLowerCase().includes(e.toLowerCase()))||n.includes(e.toLowerCase()))}parseStackTrace(e){var t;if(!e)return[];const i=[],n=e.split("\n").slice(1);for(const r of n){const e=r.match(/at\s+(?:(\S+)\s+\()?([^(]+):(\d+):(\d+)\)?/);e&&i.push({method:e[1]||void 0,filename:null==(t=e[2])?void 0:t.trim(),lineno:parseInt(e[3],10),colno:parseInt(e[4],10)})}return i}async sendErrorToRollbarAPI(e,t,i){var n,r,o,s,a,c;const l=Date.now();if(l-this.lastAPICallTime<this.API_THROTTLE_MS)return D.debug("Throttling API call",{timeSinceLastCall:l-this.lastAPICallTime}),null;this.lastAPICallTime=l,(null==(n=this.config)?void 0:n.accessToken)||D.debug("Sending error to Rollbar API without token - relying on server-side token via proxy");try{const n="string"==typeof e?e:e.message||"Unknown error",l="object"==typeof e?e.stack:void 0,d={data:{level:i,environment:(null==(r=this.config)?void 0:r.environment)||"development",body:{message:{body:n},...l&&{trace_chain:[{frames:this.parseStackTrace(l).reverse()}]}},custom:{component:t.component||"SDK",...t.operation&&{operation:t.operation},version:t.version||T,userAgent:t.userAgent||("undefined"!=typeof navigator?navigator.userAgent:"unknown"),...t.url&&{url:t.url}}}};(null==(o=this.config)?void 0:o.accessToken)&&(d.access_token=this.config.accessToken);const u={"Content-Type":"application/json"};(null==(s=this.config)?void 0:s.accessToken)&&(u["X-Rollbar-Access-Token"]=this.config.accessToken);const g=await window.fetch("https://sdk.titanos.tv/logs/",{method:"POST",headers:u,body:JSON.stringify(d)});if(!g.ok)return D.error("Failed to send error to Rollbar API",{status:g.status,statusText:g.statusText}),null;const h=await g.json(),p=(null==(a=null==h?void 0:h.result)?void 0:a.uuid)||(null==h?void 0:h.uuid)||(null==(c=null==h?void 0:h.result)?void 0:c.id)||null;return D.info(("critical"===i?"Critical error":"Error")+" sent to Rollbar API",{message:n,component:t.component,rollbarId:p}),p}catch(d){return D.error("Failed to send error to Rollbar API",{error:d,originalError:e}),null}}async buildErrorContext(e,t){var i,n;const r=await this.getDeviceContext(),o={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==(i=window.location)?void 0:i.href:void 0,userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",sessionId:this.sessionId,errorStack:"object"==typeof e?e.stack:void 0,version:"undefined"!=typeof window&&(null==(n=this.windowWrapper.get("TitanSDK"))?void 0:n.VERSION)||T,...r,...t},s=l().filter(e=>!e.module.includes("RollbarClient")&&!e.message.includes("Rollbar")&&"debug"!==e.level).slice(-20);return o.logs=s.map(e=>`[${e.timestamp}] ${e.module}: ${e.message}${e.args&&e.args.length>0?"\n Args: "+JSON.stringify(e.args):""}`).join("\n"),o}async reportError(e,t,i="error"){var n,r;if(!(null==(n=this.config)?void 0:n.enabled)||!e)return Promise.resolve(null);if(!this.isSDKError(e))return Promise.resolve(null);if(this.shouldIgnoreError(e))return Promise.resolve(null);try{const n=await this.buildErrorContext(e,t);return this.sendErrorToRollbarAPI(e,n,i)}catch(o){D.error(`Failed to build error context for ${i} error`,{error:o});const n={component:(null==t?void 0:t.component)||"SDK",operation:null==t?void 0:t.operation,version:T,userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",url:"undefined"!=typeof window?null==(r=window.location)?void 0:r.href:void 0,timestamp:Date.now(),sessionId:this.sessionId,...t};return this.sendErrorToRollbarAPI(e,n,i)}}collectSDKUsage(e,t,i,n){var r,o;if(!(null==(r=this.config)?void 0:r.enabled))return;const s={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==(o=window.location)?void 0:o.href:void 0};D.info("SDK function execution",s)}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"}destroy(){this.config=null,this.sessionId="",this.lastAPICallTime=0}isInitialized(){var e;return!0===(null==(e=this.config)?void 0:e.enabled)}},R={};function P(e){const t={},i=/jwt|token|authorization|cookie|password|secret/i;return Object.keys(e).forEach(n=>{const r=e[n];i.test(n)?t[n]="[REDACTED]":t[n]=(e=>{if("string"==typeof e)return e.length>500?`${e.slice(0,500)}…`:e;if(Array.isArray(e))return e.slice(-50).map(e=>"string"==typeof e&&e.length>500?`${e.slice(0,500)}…`:e);return e})(r)}),t}function M(e,t,i,n={}){try{const r=Date.now();if(r-(R[e]||0)<5e3)return Promise.resolve(null);R[e]=r;const o={userAgent:"undefined"!=typeof navigator?navigator.userAgent:"unknown",component:t,operation:i,context:n?P(n):void 0,version:T};D.error("SDK_CRITICAL",{code:e,component:t,operation:i,...o.context?{context:o.context}:{}});const s=new E(e,I.UNKNOWN,{component:t,operation:i,...o.context?{context:o.context}:{}});return A.reportError(s,o,"critical")}catch{return Promise.resolve(null)}}const k=Object.freeze(Object.defineProperty({__proto__:null,reportCriticalCode:M,rollbarClient:A},Symbol.toStringTag,{value:"Module"})),O=s("CSPDetector");let _=[];const N=class{static getViolations(){return[...this.violations]}static clearViolations(){this.violations.length=0}static onViolation(e){return _.push(e),()=>{_=_.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 L;((t,i,n)=>{i in t?e(t,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[i]=n})(N,"symbol"!=typeof(L="violations")?L+"":L,[]),"undefined"!=typeof document&&document.addEventListener("securitypolicyviolation",e=>{const t=`${e.violatedDirective}: ${e.blockedURI}`;N.violations.push(t),O.warn("CSP Violation detected:",t);const i={directive:e.violatedDirective,blockedURI:e.blockedURI,originalEvent:e};_.forEach(e=>{try{e(i)}catch(t){O.error("CSPDetector listener error",t)}})});let F=N;const H=s("PlatformDetection");class x{strategies=[];register(e){this.strategies.push(e),this.strategies.sort((e,t)=>t.getPriority()-e.getPriority())}getStrategies(){return[...this.strategies]}}class U{canDetect(){return"undefined"!=typeof window&&("t9_core"in window||"vestel"===window.deviceBrand||navigator.userAgent.toLowerCase().includes("vestel"))}getPlatform(){return this.canDetect()?t.JVC_VESTEL:null}getPriority(){return 3}}class V{canDetect(){if("undefined"==typeof window)return!1;const e=navigator.userAgent,t=e.toLowerCase(),i=t.includes("vestel"),n=e.includes("MB181")||e.includes("MB180")||t.includes("mb181")||t.includes("mb180")||e.includes("Model/Vestel-MB181")||e.includes("Model/Vestel-MB180");return i&&n}getPlatform(){return this.canDetect()?t.JVC_VESTEL_LEGACY:null}getPriority(){return 20}}class K{canDetect(){if("undefined"==typeof window)return!1;if("undefined"==typeof navigator)return!1;const e=navigator.userAgent,t=w(e),i=b(e);return t&&!i}getPlatform(){return this.canDetect()?t.JVC_HKC:null}getPriority(){return 8}}class B{canDetect(){if("undefined"==typeof window)return!1;if("undefined"==typeof navigator)return!1;const e=navigator.userAgent.toLowerCase();return/\(aoc,\s*[^)]+\)/i.test(e)}getPlatform(){return this.canDetect()?t.AOC:null}getPriority(){return 6}}class z{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()?t.PHILIPS:null}getPriority(){return 5}}class ${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()?t.PHILIPS_OLD:null}getPriority(){return 10}}class G{canDetect(){return!0}getPlatform(){return t.BROWSER}getPriority(){return 1}}const j=new class{factory;lastDetectedPlatform=null;constructor(){this.factory=new x,this.factory.register(new K),this.factory.register(new B),this.factory.register(new z),this.factory.register(new U),this.factory.register(new V),this.factory.register(new $),this.factory.register(new G)}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 i=this.factory.getStrategies();for(const t of i)if(t.canDetect()){const i=t.getPlatform();if(null!==i){const n={platform:i,detectedBy:t.constructor.name,confidence:.9};return this.lastDetectedPlatform=n,e.debug&&H.info(`Platform detected as ${i}`),{...n}}}if(!1===e.fallbackToBrowser)throw new E("Could not detect platform and fallback is disabled",I.PLATFORM_NOT_DETECTED);const n={platform:t.BROWSER,detectedBy:"fallback",confidence:.1};return this.lastDetectedPlatform=n,e.debug&&H.info("Fallback to browser platform - no strategy matched"),{...n}}reset(){this.lastDetectedPlatform=null}},W=s("SmartTvA_API"),q=(e,t)=>{var i,n,r,o;try{if(!t)return W.warn(`Device info not available, cannot check capability: ${e}`),!1;const s=t.Product||{},a=t.Channel||{},c=t.Capability||{};switch(e){case"3d":return Boolean(c.support3d);case"uhd":return Boolean(c.supportUHD);case"hdr10":return Boolean(c.supportHDR_HDR10);case"hdr10plus":return Boolean(c.supportHDR_HDR10Plus);case"hlg":return Boolean(c.supportHDR_HLG);case"dolby-vision":return Boolean(c.supportHDR&&((null==(i=s.platform)?void 0:i.toLowerCase().includes("dolby"))||(null==(n=a.brand)?void 0:n.toLowerCase().includes("dolby"))));case"atmos":return Boolean((null==(r=s.platform)?void 0:r.toLowerCase().includes("atmos"))||(null==(o=a.brand)?void 0:o.toLowerCase().includes("dolby")));default:return W.warn(`Unknown device capability: ${e}`),!1}}catch(s){return W.error(`Error checking device capability ${e}:`,s),!1}},Q=async e=>{if("undefined"==typeof window)return void W.warn("Window object not available, cannot attach SmartTvA_API");if("object"==typeof window.SmartTvA_API)return void W.info("SmartTvA_API already exists on window, skipping initialization");const t=await(async e=>{W.info("Initializing SmartTvA_API with TitanSDK");let t=null;try{W.info("Waiting for device info to be ready..."),t=await e.deviceInfo.getDeviceInfo(),W.info("Device info is ready, proceeding with SmartTvA_API initialization")}catch(i){W.warn("Failed to get device info during SmartTvA_API initialization:",i)}return{exit:()=>{W.info("SmartTvA_API.exit() called"),window.close()},hasCapability:(e,...i)=>{switch(W.debug(`SmartTvA_API.hasCapability('${e}', ${i.join(", ")})`),e){case"3DSupport":return q("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 q("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(!q("uhd",t))return!1;switch(e){case"HDR10":return q("hdr10",t);case"HDR10+":return q("hdr10plus",t);case"HLG":return q("hlg",t);case"DV":return q("dolby-vision",t);default:return!1}}return!1;case"8K":case"WidevineClassic":case"AdobeHDS":return!1;case"ATMOS":return q("atmos",t);default:return W.warn(`Unknown capability requested: ${e}`),!1}}}})(e);Object.defineProperty(window,"SmartTvA_API",{value:t,writable:!1,configurable:!0}),W.info("SmartTvA_API successfully attached to window object")};class J{config;waitReady=new Promise(()=>{});waitReadyResolver;constructor(e){this.config=e,this.waitReady=new Promise(e=>{this.waitReadyResolver=e})}logError(...e){this.config.debug}}const 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"},Z={TTS_SETTINGS_CHANGE:Y.TTS_SETTINGS_CHANGE,TM_SETTINGS_CHANGE:Y.TM_SETTINGS_CHANGE,LOG_ENTRY:Y.LOG_ENTRY},X={enabled:!1,available:!1},ee={enabled:!1,available:!1},te={tts:X,tm:ee},ie="TIMEOUT",ne="NOT_SUPPORTED",re="INVALID_REQUEST",oe="COMMUNICATION_ERROR",se="LAUNCH_FAILED",ae="APP_NOT_FOUND",ce="APP_NOT_AVAILABLE",le="INVALID_APP_CODE";var de=(e=>(e.PHILIPS="philips",e.VESTEL="vestel",e.BROWSER="browser",e))(de||{});const ue=s("BaseBridge");class ge{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),ue.debug("bridge: constructor",this.src)}async initialize(){if(this.isInitialized)return!0;if(this.initializationPromise)return ue.debug("bridge: initialization already in progress, waiting..."),this.initializationPromise;ue.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,ue.debug("bridge: starting initialization process"),window.addEventListener("message",this.handleMessage.bind(this));let i=!1;const n=()=>{this.aborted||i||(i=!0,this.isInitialized=!0,ue.debug("bridge initialized successfully"),e(!0))},r=()=>{this.aborted||i||(i=!0,ue.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(n,r),i||(i=!0,ue.warn("Bridge initialization timeout - setupIframe completed but LAUNCHER_READY not received"),this.isInitialized=!1,e(!1))}catch(o){if(i)return;i=!0,ue.error("Failed to setup iframe:",o),this.isInitialized=!1,t(o)}})()})}async sendMessage(e,t){this.isInitialized||await this.initialize();try{const i=this.prepareMessage(e,t);return new Promise((e,t)=>{const n=setTimeout(()=>{this.pendingRequests.delete(i.requestId),t(new E("Bridge request timeout",I.TIMEOUT))},this.messageTimeout);this.pendingRequests.set(i.requestId,{resolve:e,reject:t,timeout:n}),this.iframe&&this.iframe.contentWindow?(ue.debug("bridge: sendMessage",i),this.iframe.contentWindow.postMessage(i,this.iframeOrigin||"*")):(clearTimeout(n),this.pendingRequests.delete(i.requestId),t(new E("Bridge iframe not available",I.COMMUNICATION_ERROR)))})}catch(i){ue.error("bridge: error sending message:",i);return(await Promise.resolve().then(()=>k).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:I.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&&ue.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(Z).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){ue.error("Error handling message:",i)}}handleNotification(e){ue.debug("bridge notification received:",e);const t=this.eventHandlers.get(e.type);t&&t.forEach(t=>{try{t(e.data)}catch(i){ue.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 E(e.message,i,{operation:t,gatewayErrorCode:e.code,gatewayErrorMessage:e.message})}mapGatewayErrorCodeToSDK(e){switch(e){case se:case ae:case ce:case le:return I.INVALID_PARAMETER;case ie:return I.TIMEOUT;case ne:return I.NOT_SUPPORTED;case oe:return I.COMMUNICATION_ERROR;case re:return I.INVALID_ARGUMENTS;default:return I.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"),!S())try{await function(e=1e4){return new Promise((t,i)=>{if(S())return void t();const n=Date.now();let r=0,o="initial";v.debug("Waiting for document.body:",{readyState:document.readyState,bodyExists:!!document.body,htmlExists:!!document.documentElement,headExists:!!document.head,timeout:e});let s=null,a=null,c=null;const l=[];function d(){a&&(clearInterval(a),a=null),s&&(s.disconnect(),s=null),c&&(clearTimeout(c),c=null),l.forEach(clearTimeout),l.length=0}const u=(e,t)=>{if(o!==e){const i=Date.now()-n;v.debug(`DOM strategy changed: ${o} → ${e}`,{elapsed:i,reason:t||"strategy switch",checkCount:r}),o=e}},g=(e,t="warn")=>{const i=Date.now()-n,o=Math.floor(i/6e4),s=Math.floor(i%6e4/1e3);"error"===t?v.error(`${e} after ${o}m ${s}s`,{elapsed:i,checkCount:r,readyState:document.readyState,bodyExists:!!document.body}):v.warn(`${e} after ${o}m ${s}s`,{elapsed:i,checkCount:r,readyState:document.readyState})},h=e=>{u("mutation-observer","DOMContentLoaded completed but body not ready"),s=new MutationObserver(()=>{r++;const e=Date.now()-n;S()&&(d(),v.debug("document.body ready via MutationObserver:",{elapsed:e,checkCount:r}),t())}),s.observe(document.documentElement,{childList:!0,subtree:!1}),c=setTimeout(()=>{S()||(g("DOM still not ready, switching to polling fallback"),u("polling","MutationObserver timeout"),a=setInterval(()=>{r++;const e=Date.now()-n;S()&&(d(),v.debug("document.body ready via polling fallback:",{elapsed:e,checkCount:r}),t())},50))},3e4)};if("loading"===document.readyState){u("dom-content-loaded","document still loading");const o=()=>{var e;clearTimeout(s);const i=Date.now()-n;S()?(d(),v.debug("document.body ready after DOMContentLoaded:",{elapsed:i}),t()):(v.warn("DOMContentLoaded fired but body still not ready:",{elapsed:i,childNodes:(null==(e=document.documentElement)?void 0:e.childNodes.length)||0}),h())},s=setTimeout(()=>{var e;document.removeEventListener("DOMContentLoaded",o),d();const t=Date.now()-n;v.error("Timeout waiting for document.body:",{elapsed:t,readyState:document.readyState,bodyExists:!!document.body,checkCount:r,html:!!document.documentElement,head:!!document.head,childNodesCount:(null==(e=document.documentElement)?void 0:e.childNodes.length)||0}),i(new Error(`Timeout waiting for document.body after ${t}ms. readyState: ${document.readyState}, checks: ${r}. Initialize SDK after DOMContentLoaded or use defer/async script.`))},e);document.addEventListener("DOMContentLoaded",o,{once:!0})}else v.debug("DOM already loaded, using MutationObserver + polling"),h();m.forEach(({time:t,message:i})=>{if(t<e){const e=setTimeout(()=>{S()||g(i)},t);l.push(e)}})})}(f)}catch(i){throw ue.error("Document body unavailable:",{readyState:document.readyState,bodyExists:!!document.body,timeout:10}),new Error("Document body is not available. SDK initialized too early - ensure DOM is ready before calling getTitanSDK(). Consider initializing SDK after DOMContentLoaded event or in a defer/async script.")}document.body.appendChild(this.iframe),await new Promise(i=>{const n=setTimeout(()=>{this.aborted||(ue.warn("Bridge iframe ready timeout - continuing anyway"),i())},this.iframeTimeout),r=t=>{var o;this.aborted||t.data&&t.data.type===Y.LAUNCHER_READY&&(null==(o=this.iframe)?void 0:o.contentWindow)===t.source&&(ue.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&&ue.debug("bridge transferData:",e.data)}),this.iframe&&(this.iframe.onload=()=>{this.aborted||ue.debug("bridge iframe loaded: ",this.src)},this.iframe.onerror=()=>{this.aborted||(ue.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=>{u({...t,metadata:{...t.metadata,source:"Gateway",tunneled:!0}}),e(t)})}}const he=s("EnhancedBridge");function pe(e,t){if(!["frame-src","child-src","connect-src"].includes(e.directive)||!e.blockedURI||!t)return!1;const i=e.blockedURI,n=e=>e.replace(/\/+$/,"").toLowerCase(),r=n(i),o=n(t),s=e=>{try{return new URL(e).hostname}catch{const t=e.match(/^(?:https?:\/\/)?([^\/]+)/);return t?t[1]:""}},a=s(i),c=s(t);return o.includes(r)||r.includes(o)||a&&c&&a===c||i.includes("titanos.tv")&&t.includes("titanos.tv")||i.includes("localhost")&&t.includes("localhost")}class fe extends ge{bridgeHealthStatus={connected:!1,cspBlocked:!1,iframeCreated:!1,communicationWorking:!1,cspViolations:[]};cspUnsubscribe;cspViolationDetected=!1;cspViolationPromise;cspViolationResolver=null;constructor(e){super(e),this.bridgeHealthStatus.gatewayUrl=this.src,this.cspViolationPromise=new Promise(e=>{this.cspViolationResolver=e}),this.setupCspViolationListener()}setupCspViolationListener(){this.cspUnsubscribe=F.onViolation(e=>{if(he.debug("CSP violation received in EnhancedBaseBridge:",{directive:e.directive,blockedURI:e.blockedURI,gatewayUrl:this.src,isBridgeViolation:pe(e,this.src)}),pe(e,this.src)){const t=`${e.directive}: ${e.blockedURI||"unknown"}`;this.bridgeHealthStatus.cspViolations.includes(t)||this.bridgeHealthStatus.cspViolations.push(t),he.warn("CSP violation detected for bridge:",{directive:e.directive,blockedURI:e.blockedURI,gatewayUrl:this.src}),this.bridgeHealthStatus.cspBlocked=!0,this.bridgeHealthStatus.lastError=`CSP ${e.directive} blocked: ${e.blockedURI||"unknown"}`,!this.cspViolationDetected&&this.cspViolationResolver&&(this.cspViolationDetected=!0,he.debug("Resolving CSP violation Promise"),this.cspViolationResolver(),this.cspViolationResolver=null)}})}async initialize(){try{he.debug("Starting enhanced bridge initialization");const e=await super.initialize();return this.bridgeHealthStatus.connected=!!e,!!e}catch(e){const t=e instanceof Error?e.message:"Unknown error";return this.bridgeHealthStatus.lastError=t,he.error("Enhanced bridge initialization failed:",e),!1}}getBridgeHealth(){return{...this.bridgeHealthStatus,connected:this.isConnected(),iframeCreated:null!==this.iframe}}disconnect(){this.aborted||(super.disconnect(),this.bridgeHealthStatus.connected=!1,this.bridgeHealthStatus.communicationWorking=!1,this.cspUnsubscribe&&(this.cspUnsubscribe(),this.cspUnsubscribe=void 0),this.cspViolationDetected=!1,this.cspViolationPromise=new Promise(e=>{this.cspViolationResolver=e}),this.bridgeHealthStatus={connected:!1,cspBlocked:!1,iframeCreated:!1,communicationWorking:!1,gatewayUrl:this.src,cspViolations:[]},this.aborted=!0)}async setupIframe(e,t){try{he.debug("Setting up bridge iframe"),await super.setupIframe(e,t),this.bridgeHealthStatus.iframeCreated=!0}catch(i){this.bridgeHealthStatus.iframeCreated=!1;const e=i instanceof Error?i.message:"Unknown error";throw this.bridgeHealthStatus.lastError=e,he.error("Failed to setup iframe:",{error:e,gatewayUrl:this.src,documentReady:document.readyState,bodyExists:!!document.body}),i}}async executeBridgeFunction(e,t){const i=this.getBridgeHealth();if(!i.connected){if(t)return he.debug("Bridge not connected, using fallback function"),await t();throw new E("Bridge not connected",I.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 waitForInitializationAttempt(){if(this.isConnected())return void he.debug("Bridge already initialized, no need to wait");const e=this;if(e.initializationPromise){he.debug("Bridge initialization in progress, waiting for completion...");try{await e.initializationPromise,he.debug("Bridge initialization attempt completed")}catch{he.debug("Bridge initialization attempt completed (with error)")}}else{he.debug("No bridge initialization in progress, starting new attempt...");try{await this.initialize(),he.debug("Bridge initialization attempt completed")}catch{he.debug("Bridge initialization attempt completed (with error)")}}this.bridgeHealthStatus.iframeCreated&&!this.isConnected()&&(this.cspViolationDetected||this.bridgeHealthStatus.cspBlocked?he.debug("CSP violation already detected, no need to wait"):(he.debug("Iframe created but connection not established, waiting for CSP violation detection..."),await this.cspViolationPromise,he.debug("CSP violation detection completed (or connection established)")))}}var me,ve={exports:{}};var Se,ye,be=(me||(me=1,Se=ve,ye=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 o={compressToBase64:function(e){if(null==e)return"";var i=o._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:o._decompress(e.length,32,function(i){return r(t,e.charAt(i))})},compressToUTF16:function(t){return null==t?"":o._compress(t,15,function(t){return e(t+32)})+" "},decompressFromUTF16:function(e){return null==e?"":""==e?null:o._decompress(e.length,16384,function(t){return e.charCodeAt(t)-32})},compressToUint8Array:function(e){for(var t=o.compress(e),i=new Uint8Array(2*t.length),n=0,r=t.length;n<r;n++){var s=t.charCodeAt(n);i[2*n]=s>>>8,i[2*n+1]=s%256}return i},decompressFromUint8Array:function(t){if(null==t)return o.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 s=[];return i.forEach(function(t){s.push(e(t))}),o.decompress(s.join(""))},compressToEncodedURIComponent:function(e){return null==e?"":o._compress(e,6,function(e){return i.charAt(e)})},decompressFromEncodedURIComponent:function(e){return null==e?"":""==e?null:(e=e.replace(/ /g,"+"),o._decompress(e.length,32,function(t){return r(i,e.charAt(t))}))},compress:function(t){return o._compress(t,16,function(t){return e(t)})},_compress:function(e,t,i){if(null==e)return"";var n,r,o,s={},a={},c="",l="",d="",u=2,g=3,h=2,p=[],f=0,m=0;for(o=0;o<e.length;o+=1)if(c=e.charAt(o),Object.prototype.hasOwnProperty.call(s,c)||(s[c]=g++,a[c]=!0),l=d+c,Object.prototype.hasOwnProperty.call(s,l))d=l;else{if(Object.prototype.hasOwnProperty.call(a,d)){if(d.charCodeAt(0)<256){for(n=0;n<h;n++)f<<=1,m==t-1?(m=0,p.push(i(f)),f=0):m++;for(r=d.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<h;n++)f=f<<1|r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r=0;for(r=d.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==--u&&(u=Math.pow(2,h),h++),delete a[d]}else for(r=s[d],n=0;n<h;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;0==--u&&(u=Math.pow(2,h),h++),s[l]=g++,d=String(c)}if(""!==d){if(Object.prototype.hasOwnProperty.call(a,d)){if(d.charCodeAt(0)<256){for(n=0;n<h;n++)f<<=1,m==t-1?(m=0,p.push(i(f)),f=0):m++;for(r=d.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<h;n++)f=f<<1|r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r=0;for(r=d.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==--u&&(u=Math.pow(2,h),h++),delete a[d]}else for(r=s[d],n=0;n<h;n++)f=f<<1|1&r,m==t-1?(m=0,p.push(i(f)),f=0):m++,r>>=1;0==--u&&(u=Math.pow(2,h),h++)}for(r=2,n=0;n<h;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:o._decompress(e.length,32768,function(t){return e.charCodeAt(t)})},_decompress:function(t,i,n){var r,o,s,a,c,l,d,u=[],g=4,h=4,p=3,f="",m=[],v={val:n(0),position:i,index:1};for(r=0;r<3;r+=1)u[r]=r;for(s=0,c=Math.pow(2,2),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;switch(s){case 0:for(s=0,c=Math.pow(2,8),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;d=e(s);break;case 1:for(s=0,c=Math.pow(2,16),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;d=e(s);break;case 2:return""}for(u[3]=d,o=d,m.push(d);;){if(v.index>t)return"";for(s=0,c=Math.pow(2,p),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;switch(d=s){case 0:for(s=0,c=Math.pow(2,8),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;u[h++]=e(s),d=h-1,g--;break;case 1:for(s=0,c=Math.pow(2,16),l=1;l!=c;)a=v.val&v.position,v.position>>=1,0==v.position&&(v.position=i,v.val=n(v.index++)),s|=(a>0?1:0)*l,l<<=1;u[h++]=e(s),d=h-1,g--;break;case 2:return m.join("")}if(0==g&&(g=Math.pow(2,p),p++),u[d])f=u[d];else{if(d!==h)return null;f=o+o.charAt(0)}m.push(f),u[h++]=o+f.charAt(0),o=f,0==--g&&(g=Math.pow(2,p),p++)}}};return o}(),null!=Se?Se.exports=ye:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return ye})),ve.exports);const we=s("TVPlatform");class Te extends J{DEFAULT_DEVICE_INFO={};bridge;isInitialized=!1;CACHE_KEY="titansdk";CACHE_EXPIRY=6048e5;constructor(e,t){if(super(e),null!=t)this.bridge=t;else if(null===t)this.waitReadyResolver(!0);else{const e={gatewayUrl:this.config.gatewayUrl};this.bridge=new fe(e)}this.bridge&&this.initializeBridgeSafely()}async initializeBridgeSafely(){if(this.bridge){try{await this.bridge.initialize()&&(this.isInitialized=!0)}catch(e){we.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||t.lastVersion!==T?(localStorage.removeItem(this.CACHE_KEY),null):(we.debug("Device info loaded from localStorage cache"),t)}catch(e){return we.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 g;try{n=be.decompressFromEncodedURIComponent(i),n&&we.debug("Device info loaded from URL parameter (lz-string)")}catch(e){we.debug("lz-string decompression failed, trying base64")}if(!n)try{const e=r.get("atob");if(!e)return we.warn("atob function not available"),null;n=e(decodeURIComponent(i)),we.debug("Device info loaded from URL parameter (base64)")}catch(t){return we.warn("Both lz-string and base64 decoding failed"),null}if(!n)return we.warn("Failed to decode URL parameter"),null;return JSON.parse(n)}catch(i){return we.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 we.warn("Skipping cache save - invalid or empty device info");const t={data:e,timestamp:Date.now(),lastVersion:T};localStorage.setItem(this.CACHE_KEY,JSON.stringify(t)),we.debug("Device info saved to localStorage cache")}catch(t){we.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:X,tm:ee};if(!1!==this.config.useCache){const e=this.getFromLocalStorage();if(e)return this.waitReadyResolver(!0),{deviceInfo:e.data,tts:X,tm:ee}}else this.config.debug&&we.debug("Debug mode: skipping cache, fetching fresh data from iframe");if(!this.bridge)return{deviceInfo:null,tts:X,tm:ee};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.deviceInfo&&this.saveToLocalStorage(e.deviceInfo),e},async()=>{we.warn("Bridge unavailable, returning fallback device info");const e={deviceInfo:null,tts:X,tm:ee};return M("SDK_BRIDGE_FALLBACK","SDK","bridge.executeWithFallback",{reason:"bridge unavailable",platformId:this.getId(),isInitialized:this.isInitialized}),e})}catch(t){return we.warn("Failed to get device info from bridge:",t),M("SDK_BRIDGE_FALLBACK","SDK","bridge.executeWithFallback",{reason:"bridge exception",platformId:this.getId(),isInitialized:this.isInitialized,error:t instanceof Error?t.message:String(t)}),{deviceInfo:null,tts:X,tm:ee}}}isTV(){return"undefined"!=typeof window&&(navigator.userAgent.includes("TV")||navigator.userAgent.includes("SmartTV")||navigator.userAgent.includes("SMART-TV")||window.location.href.includes("file://"))}}const Ie=new g,Ee=new g;function De(){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!==Ie.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 Ae(){try{const e=(new g).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 Re=new g;function Pe(){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=Re.has("MediaKeys"),i=Re.has("WebKitMediaKeys"),n=Re.has("MSMediaKeys");return e=t||i||n?"EME":e,{drmMethod:e}}catch(t){return{drmMethod:""}}}function Me(){try{const e=Re.has("MediaKeys"),t=Re.has("WebKitMediaKeys"),i=Re.has("MSMediaKeys");return{supportEME:e||t||i}}catch(e){return{supportEME:!1}}}const ke=s("PhilipsCapabilities");async function Oe(e){const t=function(){try{const e={support3d:!1,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportUHD:!1,supportFHD:!0,supportHDR_HDR10:!1,supportHDR_DV:!1,supportHDR_HLG:!1,supportHDR_HDR10Plus:!1,supportHDR:"unknown",supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportAdobeHDS:!1,supportWidevineClassic:!1,supportDolbyAtmos:"unknown"},t=_e.get("ols3DSupport");t&&t()&&(e.support3d=!0);const i=_e.get("olsAtmosSupport");i&&"function"==typeof i&&i()?e.supportDolbyAtmos=!0:e.supportDolbyAtmos=!1,e.supportKeyNumeric=!0,e.supportKeyColor=!0,e.supportMultiscreen=!1,e.supportMultiAudio=!0,e.supportTTMLInband=!0,e.supportTTMLOutofband=!0,e.supportFHD=!0;const n=_e.get("olsUHD");n&&n()&&(e.supportUHD=n(),e.supportHDR_HDR10Plus=!0),e.supportHDR_HDR10=!0,e.supportHDR_HLG=!0;const r=_e.get("olsDVSupport");return r&&r()&&(e.supportHDR_DV=!0),e.supportHDR=e.supportHDR_HDR10||e.supportHDR_DV||e.supportHDR_HLG||e.supportHDR_HDR10Plus||!1,e}catch(e){return ke.error("Error detecting SmartTV API capabilities:",e),{support3d:!1,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportUHD:!1,supportFHD:!0,supportHDR_HDR10:!1,supportHDR_DV:!1,supportHDR_HLG:!1,supportHDR_HDR10Plus:!1,supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportAdobeHDS:!1,supportHDR:"unknown",supportWidevineClassic:!1,supportDolbyAtmos:"unknown"}}}();return{os:"Linux",browserEngine:"Blink",...t,...Ae(),...De(),...Pe(),...Me(),...Ce(),supportFairplay:!1,supportPrimetime:!1,supportClearKey:!0,supportPlayready:!0,supportWidevineModular:!0,supportWidevineClassic:!0}}const _e=new g;const Ne=s("PhilipsCompat");class Le extends Te{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:p(),language:"en"}};constructor(e,t){super(e,t)}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product},i=this.formatBridgeResponse(e,t),n=(i.Product.platform,await Oe());return{...i,Capability:n}}catch(e){throw Ne.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.mac||M("SDK_BRIDGE_NO_MAC","SDK","formatBridgeResponse",{deviceInfo:e.deviceInfo}),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"}}class Fe extends Le{DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"TPV",brand:"AOC"},Product:{platform:"TitanOS",year:"2026",deviceID:"aoc-device",firmwareVersion:"1.0.0",firmwareComponentID:"",mac:"",WhaleAdID:p(),language:"en"}};constructor(e,t){super(e,t)}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent.toLowerCase();return/\(aoc,\s*[^)]+\)/i.test(e)}getId(){return"aoc"}}const He=new g;class xe extends fe{constructor(e){var t,i;if(null==e?void 0:e.gatewayUrl)super({gatewayUrl:e.gatewayUrl});else{let e="app";if(He.proxy.jwt&&!He.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)))}})(He.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=He.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||X}async getTMSettings(){return(await this.getA11ySettings()).tm||ee}async getA11ySettings(){const e=await this.sendMessage(Y.TTS_REQUEST_SETTINGS,void 0);return e.success&&"data"in e?e.data:te}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 Ue={HIGH:["button","link","heading","listitem"],MEDIUM:["textbox","combobox","checkbox","radio","slider"],LOW:["list","navigation","main","dialog","grid"]},Ve=s("AriaProcessor");class Ke{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 Ve.warn("Interactive element without accessible name:",e),null;const n=this.getAccessibleDescription(e),r=this.computeElementState(e),o=this.computePositionInfo(e,t),s=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:o,actions:s,tvProperties:a};return Ve.debug("Processed accessibility element:",{role:t,name:i.substring(0,50),state:r,tvOptimized:!!a}),c}catch(t){return Ve.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 o=e.getAttribute("aria-disabled")||e.getAttribute("disabled");null!==o&&(t.disabled="true"===o||""===o);const s=e.getAttribute("aria-invalid");null!==s&&(t.invalid="true"===s||s);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')),o=n.indexOf(t)+1,s=r.indexOf(e)+1;if(o>0&&s>0)return{position:s,setSize:r.length,row:o,column:s,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||(Ue.HIGH.includes(t)?i.priority="high":Ue.MEDIUM.includes(t)?i.priority="medium":i.priority="low"),Object.keys(i).length>0?i:void 0}isRelevantForTV(e){return[...Ue.HIGH,...Ue.MEDIUM,...Ue.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 Be=s("DOMMonitor");class ze{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 Ke(e)}updateConfig(e){this.config={...e},this.ariaProcessor.updateConfig(e)}async startFocusTracking(){if(this.isTracking)return void Be.debug("Focus tracking already active");Be.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,Be.info("Focus tracking started")}async startLiveRegionMonitoring(e){this.liveRegionHandler=e,Be.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"]}),Be.info("Live region monitoring started")}async stop(){Be.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,Be.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){Be.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&&Be.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){Be.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),Be.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(" "),o="true"===e.getAttribute("aria-busy");return{element:e,politeness:i,atomic:n,relevant:r,busy:o}}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){Be.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 $e=s("AnnouncementProcessor");class Ge{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 $e.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 $e.debug("TTS stop result:",e),e}return $e.debug("No stopTtsFunction available"),!0}catch(e){return $e.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 o=this.getActionAnnouncement(e.actions||[]);return o&&t.push(o),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(),$e.debug("Announced:",{text:e.text.join(" ").substring(0,100),priority:e.priority,success:t}),t}catch(i){return $e.error("Error speaking announcement:",i),!1}}delay(e){return new Promise(t=>setTimeout(t,e))}}const je=s("AccessibilityReader");class We{config;isActive=!1;domMonitor;ariaProcessor;announcementProcessor;currentElement=null;liveRegions=new Map;constructor(e,t,i){this.config={...e},this.ariaProcessor=new Ke(e),this.announcementProcessor=new Ge(e,t,i),this.domMonitor=new ze(e,this.handleFocusChange.bind(this))}async start(){if(this.isActive)return je.debug("Accessibility Reader already active"),!0;try{je.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,je.info("Accessibility Reader started successfully"),!0}catch(e){return je.error("Failed to start Accessibility Reader:",e),!1}}async stop(){if(!this.isActive)return je.debug("Accessibility Reader not active"),!0;try{return je.info("Stopping Accessibility Reader"),await this.domMonitor.stop(),this.currentElement=null,this.liveRegions.clear(),this.isActive=!1,je.info("Accessibility Reader stopped"),!0}catch(e){return je.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 je.info("Accessibility Reader configuration updated",this.config),!0}catch(t){return je.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):(je.debug("Accessibility Reader not active, skipping announcement"),!1)}async stopAnnouncement(){return this.isActive?await this.announcementProcessor.stopAnnouncement():(je.debug("Accessibility Reader not active, skipping stop"),!1)}getCurrentElement(){return this.currentElement}async handleFocusChange(e){var t,i;try{je.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){je.error("Error handling focus change:",n)}}async handleLiveRegionChange(e,t){try{if(je.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){je.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){je.error("Error announcing element:",t)}}}const qe=s("AccessibilityService");class Qe{bridge;reader=null;ttsSettings=X;tmSettings=ee;constructor(e){this.bridge=e,this.bridge.onTTSSettingsChange(e=>{this.ttsSettings=e}),this.bridge.onTMSettingsChange(e=>{this.tmSettings=e})}async startSpeaking(e){if("string"==typeof e&&(e=[e]),await this.isTTSEnabled())try{return await this.bridge.startSpeaking(e)}catch(t){return qe.error("Error starting speaking:",t),!1}return!0}async stopSpeaking(){if(await this.isTTSEnabled())try{return await this.bridge.stopSpeaking()}catch(e){return qe.error("Error stopping speaking:",e),!1}return!0}async enableReader(e){try{if(!(await this.isTTSSupported()))return qe.warn("Cannot enable Reader: TTS not supported"),!1;if(!(await this.isTTSEnabled()))return qe.warn("Cannot enable Reader: TTS not enabled"),!1;this.reader=new We(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(qe.info("Reader enabled"),!0)}catch(t){return qe.error("Error enabling Reader:",t),!1}}async disableReader(){try{if(this.reader){const e=await this.reader.stop();return this.reader=null,e&&qe.info("Reader disabled"),e}return qe.debug("Reader was not active"),!0}catch(e){return qe.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 qe.error("Error checking TTS support:",e),!1}}async isTextMagnificationSupported(){try{return(await this.getTMSettings()).available}catch(e){return qe.error("Error checking magnification support:",e),!1}}onTTSSettingsChange(e){return this.bridge.onTTSSettingsChange(e)}onTMSettingsChange(e){return this.bridge.onTMSettingsChange(e)}async getTTSSettings(){try{const e=await this.bridge.getTTSSettings();return this.ttsSettings=e,e}catch(e){return qe.error("Error getting TTS settings from bridge:",e),this.ttsSettings}}async getTMSettings(){try{const e=await this.bridge.getTMSettings();return this.tmSettings=e,e}catch(e){return qe.error("Error getting TM settings from bridge:",e),this.tmSettings}}async isTTSEnabled(){return(await this.getTTSSettings()).enabled}async isTMEnabled(){return(await this.getTMSettings()).enabled}}const Je=s("AOCDeviceInfoService");class Ye{platform;info;bridge;constructor(e,t){this.platform=new Fe(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 Je.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const Ze=s("PhilipsAppControlService");class Xe{bridge;constructor(e){this.bridge=e}async launch(e,t){return await this.bridge.executeWithFallback(()=>this.bridge.launchApp({appId:e,deepLink:t}),async()=>(Ze.warn("Function unavailable, app launch failed gracefully",{appId:e,deepLink:t}),!1))}}const et=e=>{const{available:t,...i}=e;if("scale"in i){const{enabled:e,scale:t}=i;return{enabled:e,...void 0!==t&&{scale:t}}}const{enabled:n}=i;return{enabled:n}};class tt{subscribe(e,t){const i=a(e,t);return()=>{c(i)}}getHistory(){return l()}clear(){d()}}class it{bridge;accessibilityService;deviceInfoService;appControlService;constructor(e,t,i,n){this.bridge=e,this.accessibilityService=t,this.deviceInfoService=i,this.appControlService=n}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()=>et(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>et(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange(t=>{e(et(t))}),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange(t=>{e(et(t))})};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new tt}get dev(){return{isBridgeConnected:async()=>{try{return this.bridge.isConnected()}catch(e){return!1}}}}}const nt=s("AOCSDK");class rt extends it{constructor(e){const t=new xe({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new Qe(t),new Ye(e,t),new Xe(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),await this.bridge.waitForInitializationAttempt(),this.bridge.isConnected()||nt.warn("Bridge initialization completed but bridge is not connected. Some features may not work correctly."),!0}catch(e){throw nt.error("TitanSDK initialization failed:",e),e}}}const ot=s("ChromeTTS");class st{voices=[];currentVoice=null;settings={available:!0,enabled:!0,rate:1,volume:1};speechSynthesis;constructor(){const e=new g;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,o;if(!("speechSynthesis"in window))return;const s=null==(e=this.speechSynthesis)?void 0:e.getVoices();this.voices=null==s?void 0:s.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]),ot.info(`Initialized with ${null==(r=this.voices)?void 0:r.length} voices, using ${null==(o=this.currentVoice)?void 0:o.voiceName}`)}getTTSSettings(){return this.settings}getTMSettings(){return{available:!0,enabled:!1,scale:1}}getSettings(){return{tts:this.getTTSSettings(),tm:this.getTMSettings()}}startSpeaking(e){return ot.info("Starting speaking:",e),!(!("speechSynthesis"in window)||!e||0===e.length)&&(e.forEach((e,t)=>{var i,n,r,o;if(!e)return;const s=new SpeechSynthesisUtterance(e);if(s.rate=this.settings.rate??1,s.volume=this.settings.volume??1,s.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&&(s.voice=e)}0===t&&(null==(r=this.speechSynthesis)||r.cancel()),null==(o=this.speechSynthesis)||o.speak(s)}),!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 at="titanSDK_tts_settings",ct="titanSDK_tm_settings",lt=s("BrowserAccessibilityService");class dt{reader=null;chromeTTS;windowMock;mockStorage;ttsSettings;tmSettings;constructor(e,t,i=!1){this.windowMock=e,this.mockStorage=t,this.chromeTTS=new st,this.ttsSettings=this.loadTTSSettings(),this.tmSettings=this.loadTMSettings()}loadTTSSettings(){try{const e=localStorage.getItem(at);if(e)return{...this.getDefaultTTSSettings(),...JSON.parse(e)}}catch(e){}return this.getDefaultTTSSettings()}loadTMSettings(){try{const e=localStorage.getItem(ct);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(at,JSON.stringify(this.ttsSettings))}catch(e){}}saveTMSettings(){try{localStorage.setItem(ct,JSON.stringify(this.tmSettings))}catch(e){}}async startSpeaking(e){try{if(!this.ttsSettings.enabled)return lt.info("TTS is disabled in settings"),!1;const t=Array.isArray(e)?e.join(" "):e,i=this.chromeTTS.startSpeaking([t]);return i&<.info("🔊 Speaking:",t),i}catch(t){return lt.error("Error starting speech:",t),!1}}async stopSpeaking(){try{const e=this.chromeTTS.stopSpeaking();return e&<.info("🔇 Speech stopped"),e}catch(e){return lt.error("Error stopping speech:",e),!1}}async enableReader(e){try{if(!(await this.isTTSSupported()))return lt.warn("Cannot enable Reader: TTS not supported"),!1;this.reader=new We(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(lt.info("Reader enabled"),!0)}catch(t){return lt.error("Error enabling Reader:",t),!1}}async disableReader(){try{return!!this.reader&&(await this.reader.stop(),this.reader=null,lt.info("Reader disabled"),!0)}catch(e){return lt.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(),lt.info("TTS settings updated:",this.ttsSettings)}updateTMSettings(e){this.tmSettings={...this.tmSettings,...e},this.saveTMSettings(),lt.info("TM settings updated:",this.tmSettings)}}const ut=s("BrowserPlatform");class gt extends J{constructor(e){super(e),this.waitReady=new Promise(e=>{this.waitReadyResolver=e}),this.waitReadyResolver(!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,supportKeyNumeric:!1,supportKeyColor:!1,supportMultiscreen:!1,supportFHD:!1,supportMultiAudio:!1,supportTTMLInband:!1,supportTTMLOutofband:!1,supportFairplay:!1,supportAdobeHDS:!1,supportPrimetime:!1,supportClearKey:!1,supportWidevineClassic:!1,supportDolbyAtmos:!1,supportHDR_HDR10:!1,supportHDR_DV:!1,supportHDR_HLG:!1,supportHDR_HDR10Plus:!1}}}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=s("BrowserDeviceInfoService");class pt{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 gt(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 ft=s("BrowserAppControlService");class mt{windowMock;constructor(e){this.windowMock=e}async launch(e,t){ft.debug(`Launching app: ${e} with deepLink: ${t||"none"}`);const i=this.windowMock||window;if(!i||"function"!=typeof i.open)throw new E("Cannot open new window for app launch (window.open not available)",I.NOT_SUPPORTED,{operation:"launch",appId:e,deepLink:t,platform:"browser"});try{return i.open(t||e,"_blank"),ft.info(`Opened new tab for app: ${e}`),!0}catch(n){throw ft.error("Error opening new window for app launch:",n),new E(`Failed to launch app: ${e}`,I.COMMUNICATION_ERROR,{operation:"launch",appId:e,deepLink:t,platform:"browser",originalError:n})}}}const vt=s("BrowserSDK");class St{accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new dt(null==e?void 0:e.windowMock,null==e?void 0:e.mockStorage,(null==e?void 0:e.dev)||!1),this.deviceInfoService=new pt(e,null==e?void 0:e.windowMock,null==e?void 0:e.mockStorage),this.appControlService=new mt(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)&&vt.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()=>et(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>et(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>this.accessibilityService.onTTSSettingsChange(t=>{e(et(t))}),onTMSettingsChange:e=>this.accessibilityService.onTMSettingsChange(t=>{e(et(t))})};apps={launch:(e,t)=>this.appControlService.launch(e,t)};get logging(){return new tt}get dev(){const e={simulateError(e){switch(e){case"sdk":{const e=new E("Test SDK error for Rollbar integration",I.UNKNOWN,{operation:"dev-api-sdk-error",component:"SDK"});throw A.reportError(e,{operation:"dev-api-sdk-error",component:"SDK"}),e}case"bridge":{const e=new E("Test bridge communication error",I.COMMUNICATION_ERROR,{operation:"dev-api-bridge-error",component:"SDK"});return A.reportError(e,{operation:"dev-api-bridge-error",component:"SDK"}),Promise.reject(e)}case"async":return new Promise((e,t)=>{setTimeout(()=>{const e=new E("Test async error after timeout",I.TIMEOUT,{operation:"dev-api-async-error",component:"SDK"});A.reportError(e,{operation:"dev-api-async-error",component:"SDK"}),t(e)},100)});default:{const t=new E(`Unknown error type: ${e}`,I.UNKNOWN,{operation:"dev-api-unknown-error",component:"SDK"});throw A.reportError(t,{operation:"dev-api-unknown-error",component:"SDK"}),t}}},async simulateGatewayError(e,t){const i=new E(`Gateway error simulation not supported in browser platform. Error type: ${e}, message: ${t||"default"}`,I.NOT_SUPPORTED,{operation:"dev-api-gateway-error",component:"SDK"});throw A.reportError(i,{operation:"dev-api-gateway-error",component:"SDK"},"critical"===e?"critical":"error"),i}};return{updateTTSSettings:e=>{this.accessibilityService.updateTTSSettings(e)},updateTMSettings:e=>{this.accessibilityService.updateTMSettings(e)},simulateError:e.simulateError,simulateGatewayError:e.simulateGatewayError}}async init(){try{return vt.debug("BrowserSDK initialization started"),vt.info("BrowserSDK initialized successfully"),!0}catch(e){throw vt.error("BrowserSDK initialization failed:",e),e}}}const yt=s("PhilipsDeviceInfoService");class bt{platform;info;bridge;constructor(e,t){this.platform=new Le(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 yt.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const wt=s("JVCHKCSDK");class Tt extends it{constructor(e){const t=new xe({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new Qe(t),new bt(e,t),new Xe(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),await this.bridge.waitForInitializationAttempt(),this.bridge.isConnected()||wt.warn("Bridge initialization completed but bridge is not connected. Some features may not work correctly."),!0}catch(e){throw wt.error("JVC-HKC SDK initialization failed:",e),e}}}class It extends fe{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 Et=s("PhilipsSDK");class Dt extends it{constructor(e){const t=new xe({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new Qe(t),new bt(e,t),new Xe(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),await this.bridge.waitForInitializationAttempt(),this.bridge.isConnected()||Et.warn("Bridge initialization completed but bridge is not connected. Some features may not work correctly."),!0}catch(e){throw Et.error("TitanSDK initialization failed:",e),e}}}const Ct=s("AccessibilityService");class At{reader=null;async startSpeaking(e){return!1}async stopSpeaking(){return!1}async enableReader(e){return Ct.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 X}async getTMSettings(){return ee}async isTTSEnabled(){return!1}async isTMEnabled(){return!1}}const Rt=s("PhilipsLegacyPlatform");class Pt extends Te{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:p(),language:"en"}};constructor(e,t){super(e,null)}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product};if(!e.deviceInfo){const e=await this.fetchDeviceInfo();if(e){this.saveToLocalStorage(e);const i=this.formatBridgeResponse({deviceInfo:e,tts:X,tm:ee},t),n=(i.Product.platform,await Oe());return{...i,Capability:n}}const i=await Oe();return{...t,Capability:i}}const i=this.formatBridgeResponse(e,t),n=(i.Product.platform,await Oe());return{...i,Capability:n}}catch(e){throw Rt.warn("Error getting device info:",e),e}}async fetchDeviceInfo(){var e;try{const t="app.titanos.tv",i=await Promise.race([h(0,t,"zeasn"),new Promise(e=>{setTimeout(()=>{Rt.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:y("en"),brand:de.PHILIPS,platformName:de.PHILIPS,mac:decodeURIComponent(i.datas.cookies.mac||""),ifa:"",ifaType:""}}catch(t){return Rt.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 Mt{platform;info;constructor(e){this.platform=new Pt(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 kt{async launch(e,t){return!1}}class Ot{accessibilityService;deviceInfoService;appControlService;constructor(e){this.accessibilityService=new At,this.deviceInfoService=new Mt(e),this.appControlService=new kt}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()=>et(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>et(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 tt}async init(){return!0}}const _t=s("VestelTTS"),Nt=e=>({available:!0,enabled:e.enabled,rate:e.rate,pitch:e.pitch,volume:e.level});class Lt extends st{vestelSettings={available:!0,enabled:!1,rate:1,volume:1};windowApi=new g;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 _t.warn("TTSHelper not available during initialization");const n={onSuccess:e=>{this.vestelSettings=Nt(e),this.settingsInitialized=!0},onError:e=>{_t.error("Error initializing TTS settings:",e),this.settingsInitialized=!0}},r={onSuccess:e=>{this.vestelSettings=Nt(e)},onError:e=>{_t.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=>{_t.info("Current TTS settings:",e,e.toString()),this.vestelSettings=Nt(e)},onError:e=>{_t.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 _t.warn("TTSHelper not available"),()=>{};const n={onSuccess:t=>{_t.info("TTS settings changed:",t,t.toString()),e(Nt(t)),this.settingsInitialized=!0},onError:e=>{_t.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 Ft=s("AccessibilityService");class Ht{tts;reader=null;constructor(){this.tts=new Lt}async startSpeaking(e){if("string"==typeof e&&(e=[e]),await this.isTTSEnabled())try{return this.tts.startSpeaking(e),!0}catch(t){return Ft.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 Ft.warn("Cannot enable Reader: TTS not supported"),!1;if(!(await this.isTTSEnabled()))return Ft.warn("Cannot enable Reader: TTS not enabled"),!1;this.reader=new We(e,this.startSpeaking.bind(this),this.stopSpeaking.bind(this));return!!(await this.reader.start())&&(Ft.info("Reader enabled"),!0)}catch(t){return Ft.error("Error enabling Reader:",t),!1}}async disableReader(){try{if(this.reader){const e=await this.reader.stop();return this.reader=null,e&&Ft.info("Reader disabled"),e}return Ft.debug("Reader was not active"),!0}catch(e){return Ft.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 Ft.error("Error checking TTS support:",e),!1}}async isTextMagnificationSupported(){try{return(await this.getTMSettings()).available}catch(e){return Ft.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}}function xt(e){const t=function(){var e;try{const t=document.createElement("object");t.style.display="none",t.setAttribute("id","sysinfo"),t.setAttribute("type","systeminfoobject"),document.body.appendChild(t);const i=t;return{support3d:Boolean(i.has3D),supportUHD:"3840x2160"===(null==(e=i.panelinfo)?void 0:e.toLowerCase()),supportFHD:!0}}catch(t){return{support3d:!1,supportUHD:!1,supportFHD:!0}}}(),i=Ae(),n=De(),r=Pe(),o=Me(),s=Ce(),a={os:"Linux",browserEngine:"Blink",hasStorage:!0,support3d:!1,supportUHD:!0,supportFHD:!0,supportHDR:!0,supportHDR_HDR10:!0,supportHDR_DV:!0,supportHDR_HLG:!0,supportHDR_HDR10Plus:!0,supportWebSocket:!0,supportPlayready:!0,supportWidevineModular:!0,supportAppleHLS:!0,supportMSSmoothStreaming:!1,supportMSSInitiator:!1,supportMPEG_DASH:!0,drmMethod:"widevine",supportOIPF:!1,supportEME:!0,supportKeyNumeric:!0,supportKeyColor:!0,supportFairplay:!1,supportAdobeHDS:!1,supportPrimetime:!1,supportClearKey:!0,supportWidevineClassic:!0,supportDolbyAtmos:!0,supportMultiscreen:!0,supportMultiAudio:!0,supportTTMLInband:!0,supportTTMLOutofband:!0};return"MB191"===e&&(a.supportHDR_DV=!1,a.supportDolbyAtmos=!1,a.supportHDR_HDR10Plus=!1),{...a,...t,...i,...n,...r,...o,...s}}const Ut=s("JVCVestelCompat");class Vt extends Te{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:p(),language:"en"}};constructor(e,t){super(e,t)}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent,t=e.toLowerCase(),i=b(e),n=t.includes("vestel"),r=w(e);return i&&n&&r}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product},i=this.formatBridgeResponse(e,t),n=xt(i.Product.platform);return{...i,Capability:n}}catch(e){Ut.error("Error getting device info:",e);const t=xt();return{Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product,Capability:t}}}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 Kt=s("VestelDeviceInfoService");class Bt{platform;info;bridge;constructor(e,t){this.platform=new Vt(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 Kt.error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}}const zt=s("VestelAppControlService");class $t{bridge;constructor(e){this.bridge=e}async launch(e,t){return await this.bridge.executeWithFallback(()=>this.bridge.launchApp({appId:e,deepLink:t}),async()=>(zt.warn("Function unavailable, app launch failed gracefully",{appId:e,deepLink:t}),!1))}}const Gt=s("JVCVestelSDK");class jt extends it{constructor(e){const t=new It({gatewayUrl:null==e?void 0:e.gatewayUrl,debug:null==e?void 0:e.debug});super(t,new Ht,new Bt(e,t),new $t(t))}async init(){try{return await this.deviceInfo.getDeviceInfo(),!0}catch(e){throw Gt.error("TitanSDK initialization failed:",e),e}}}const Wt=s("GeocodingService");class qt{static REQUEST_TIMEOUT=5e3;static MAX_RETRIES=1;static async getCountry(){try{return await this.fetchWithRetry()}catch(e){return Wt.warn("Failed to get country from geocoding service:",e),"UNKNOWN"}}static async fetchWithRetry(){let e=null;for(let i=0;i<=this.MAX_RETRIES;i++)try{const e=await this.fetchFromAPI();if("UNKNOWN"!==e)return e}catch(t){e=t,i<this.MAX_RETRIES&&(Wt.debug(`Geocoding attempt ${i+1} failed, retrying...`),await new Promise(e=>setTimeout(e,500)))}if(e)throw e;return"UNKNOWN"}static async fetchFromAPI(){if("undefined"==typeof window||void 0===window.fetch)throw new Error("Fetch API is not available");const e=new AbortController,t=setTimeout(()=>e.abort(),this.REQUEST_TIMEOUT);try{const i="https://geoip.app.titanos.tv/",n=await window.fetch(i,{method:"GET",signal:e.signal,headers:{Accept:"application/json"}});if(clearTimeout(t),!n.ok)throw new Error(`Geocoding API returned status ${n.status}: ${n.statusText}`);const r=await n.json();if(!r||"string"!=typeof r.market)throw new Error("Invalid geocoding response format");const o=r.market.toUpperCase();return Wt.debug("Country fetched from geocoding service:",o),o}catch(i){if(clearTimeout(t),i instanceof Error){if("AbortError"===i.name)throw new Error("Geocoding request timeout");throw i}throw new Error("Unknown error during geocoding request")}}}const Qt=s("VestelLegacyOIPFService");class Jt{cachedOIPFObject=null;getOIPFObject(){if(this.cachedOIPFObject)return this.cachedOIPFObject;if("undefined"==typeof document)return Qt.warn("Document not available for OIPF access"),null;try{const e=document.createElement("object");return e.type="application/oipfConfiguration",e.style.display="none",document.body.appendChild(e),this.cachedOIPFObject=e,e}catch(e){return Qt.warn("Failed to create OIPF object:",e),null}}async accessOIPFObject(e){try{const t=this.getOIPFObject();return t?e(t):null}catch(t){return Qt.warn("Failed to access OIPF object:",t),null}}cleanup(){if(this.cachedOIPFObject&&this.cachedOIPFObject.parentNode)try{document.body.removeChild(this.cachedOIPFObject)}catch(e){Qt.warn("Failed to cleanup OIPF object:",e)}this.cachedOIPFObject=null}async getMACAddress(){return this.accessOIPFObject(e=>{var t,i;let n=(null==(t=e.configuration)?void 0:t.macAddress)||(null==(i=e.localSystem)?void 0:i.serialNumber)||null;return n&&function(e){if(!e||"string"!=typeof e)return!1;const t=e.replace(/[:\-\.]/g,"").toUpperCase();return/^[0-9A-F]{12}$/.test(t)}(n)?(Qt.debug("MAC address retrieved from OIPF:",n),n):(n&&Qt.debug("MAC address format invalid:",n),null)})}async getFirmwareVersion(){return this.accessOIPFObject(e=>{var t;const i=(null==(t=e.localSystem)?void 0:t.softwareVersion)||null;return i?(Qt.debug("Firmware version retrieved from OIPF:",i),i):null})}async getCountryId(){return this.accessOIPFObject(e=>{var t;const i=(null==(t=e.configuration)?void 0:t.countryId)||null;return i?(Qt.debug("Country ID retrieved from OIPF:",i),i):null})}}const Yt=s("VestelLegacyCompat"),Zt={alb:"AL",arg:"AR",arm:"AM",aut:"AT",aze:"AZ",bhs:"BS",blr:"BY",bel:"BE",bra:"BR",bgr:"BG",chl:"CL",col:"CO",cri:"CR",hrv:"HR",cze:"CZ",dnk:"DK",ecu:"EC",slv:"SV",est:"EE",fin:"FI",fra:"FR",geo:"GE",deu:"DE",grc:"GR",gtm:"GT",hnd:"HN",hun:"HU",isl:"IS",irl:"IE",isr:"IL",ita:"IT",kaz:"KZ",lva:"LV",lie:"LI",ltu:"LT",lux:"LU",mne:"ME",nld:"NL",nic:"NI",mkd:"MK",nor:"NO",pry:"PY",per:"PE",pol:"PL",prt:"PT",rou:"RO",rus:"RU",smr:"SM",srb:"RS",svk:"SK",svn:"SI",esp:"ES",swe:"SE",che:"CH",tur:"TR",ukr:"UA",gbr:"GB",ury:"UY"};class Xt extends Te{deviceInfo=null;deviceInfoPromise=null;oipfService=new Jt;DEFAULT_DEVICE_INFO={Channel:{appStore:"TitanOS",vendor:"Vestel",brand:"JVC"},Product:{platform:"TitanOS",year:"2025",deviceID:"vestel-legacy-device",firmwareVersion:"0.0.0.0",firmwareComponentID:"",mac:"",WhaleAdID:p(),language:"en"}};constructor(e,t){super(e,null)}async canHandle(){if(this.config.forcePlatform===this.getId())return!0;const e=navigator.userAgent,t=e.toLowerCase(),i=t.includes("vestel"),n=e.includes("MB181")||e.includes("MB180")||t.includes("mb181")||t.includes("mb180")||e.includes("Model/Vestel-MB181")||e.includes("Model/Vestel-MB180");return i&&n}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 this.getBaseDeviceInfo(),t={Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product};if(!e.deviceInfo){const e=await this.fetchDeviceInfoFromOIPF();if(e){this.saveToLocalStorage(e);const i=this.formatBridgeResponse({deviceInfo:e,tts:X,tm:ee},t),n=i.Product.platform,r=await xt(n);return{...i,Capability:r}}const i=await xt();return{...t,Capability:i}}const i=this.formatBridgeResponse(e,t),n=i.Product.platform,r=await xt(n);return{...i,Capability:r}}catch(e){Yt.warn("Error getting device info:",e);const t=await xt();return{Channel:this.DEFAULT_DEVICE_INFO.Channel,Product:this.DEFAULT_DEVICE_INFO.Product,Capability:t}}}async fetchDeviceInfoFromOIPF(){try{const e=this.parseUserAgent(),t=await this.oipfService.getMACAddress(),i=await this.oipfService.getFirmwareVersion();let n=await this.getCountryFromGeocoding();if(!n||"UNKNOWN"===n){const e=await this.oipfService.getCountryId();n=e?this.convertOIPFCountryToISO(e):"UNKNOWN"}const r=t||p(),o=i||e.firmwareVersion,s={profileId:`vestel_legacy_${e.boardName}`,deviceId:r,model:e.boardName,year:e.deviceYear,firmwareVersion:o,country:n,language:y("en"),brand:de.VESTEL,platformName:de.VESTEL,mac:t||"",ifa:"",ifaType:""};return Yt.debug("Device info fetched from OIPF:",s),s}catch(e){return Yt.warn("Error fetching device info from OIPF:",e),null}}parseUserAgent(){var e;const t=navigator.userAgent;let i=t.match(/Model\/Vestel-(MB\d{3})/i);i||(i=t.match(/MB\d{3}/i));const n=i?(null==(e=i[1])?void 0:e.toUpperCase())||i[0].toUpperCase():"MB181";let r=t.match(/(\d+\.\d+\.\d+\.\d+)/);r||(r=t.match(/(\d+\.\d+\.\d+)/));const o=r?r[1]:"0.0.0.0";let s=t.match(/_TV_[^_]+_(\d{4})_/);s||(s=t.match(/(20\d{2})/));return{boardName:n,firmwareVersion:o,deviceYear:s?s[1]:"2025"}}async getCountryFromGeocoding(){try{const e=await qt.getCountry();return Yt.debug("Country retrieved from geocoding service:",e),e}catch(e){return Yt.warn("Failed to get country from geocoding service:",e),"UNKNOWN"}}convertOIPFCountryToISO(e){if(!e||"string"!=typeof e)return"UNKNOWN";const t=e.toLowerCase().trim(),i=Zt[t];return i?(Yt.debug(`Converted OIPF country code '${e}' to ISO '${i}'`),i):/^[A-Z]{2}$/.test(e)?e:(Yt.warn(`Unknown OIPF country code '${e}', returning as is`),e.toUpperCase())}formatBridgeResponse(e,t){return e.deviceInfo?(t.Product.firmwareVersion=e.deviceInfo.firmwareVersion,t.Product.country=e.deviceInfo.country,t.Product.deviceID=e.deviceInfo.deviceId,t.Product.platform=e.deviceInfo.model,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=e.deviceInfo.profileId||"",t):t}getPriority(){return 95}getId(){return"vestel-legacy"}}class ei{platform;info=null;bridge;isInitialized=!1;constructor(e,t){this.platform=e,this.bridge=t}async initialize(){try{this.getLogger().debug("Initializing Device Info Service"),await this.getDeviceInfo(),this.isInitialized=!0,this.getLogger().debug("Device Info Service initialized")}catch(e){throw this.getLogger().error("Failed to initialize Device Info Service:",e),e}}async getDeviceInfo(){try{const e=await this.platform.getDeviceInfo();return this.info=e,this.info}catch(e){throw this.getLogger().error("Failed to get device info:",e),e}}async getCapabilities(){return this.info||(this.info=await this.getDeviceInfo()),this.info.Capability}isReady(){return this.isInitialized&&null!==this.info}}const ti=s("VestelLegacyDeviceInfoService");class ii extends ei{constructor(e){super(new Xt(e))}getLogger(){return ti}}const ni=s("VestelLegacyAccessibilityService");class ri{reader=null;async startSpeaking(e){return!1}async stopSpeaking(){return!1}async enableReader(e){return ni.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 X}async getTMSettings(){return ee}async isTTSEnabled(){return!1}async isTMEnabled(){return!1}}const oi=s("VestelLegacyAppControlService");class si{async launchApp(e,t){return oi.warn("App launching not supported on legacy Vestel devices"),!1}}const ai=s("VestelLegacySDK");class ci{accessibilityService;deviceInfoService;appControlService;loggingService;constructor(e){this.accessibilityService=new ri,this.deviceInfoService=new ii(e),this.appControlService=new si,this.loggingService=new tt}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()=>et(await this.accessibilityService.getTTSSettings()),getTMSettings:async()=>et(await this.accessibilityService.getTMSettings()),startSpeaking:e=>this.accessibilityService.startSpeaking(e),stopSpeaking:()=>this.accessibilityService.stopSpeaking(),onTTSSettingsChange:e=>()=>{},onTMSettingsChange:e=>()=>{}};apps={launch:async(e,t)=>{try{return await this.appControlService.launchApp(e,t),!0}catch(i){return ai.error("Failed to launch app:",i),!1}}};get logging(){return this.loggingService}async init(){try{return ai.debug("Initializing Vestel Legacy SDK"),await this.deviceInfoService.initialize(),ai.debug("Vestel Legacy SDK initialized successfully"),!0}catch(e){return ai.error("Failed to initialize Vestel Legacy SDK:",e),!1}}async getCapabilities(){return this.deviceInfoService.getCapabilities()}isReady(){return this.deviceInfoService.isReady()}getVersion(){return"1.0.0"}getPlatform(){return"vestel-legacy"}}const li=s("AnalyticsService");class di{sdkVersion;constructor(e){this.sdkVersion=e}getEventUrl(){return"https://sdk.titanos.tv/events"}async track(e){if("undefined"==typeof window||void 0===window.fetch)return Promise.resolve();try{const t={event_name:e.eventName,event_type:e.eventType,event_params:e.eventParams,event_timestamp:(new Date).toISOString().replace("T"," ").slice(0,-1)};await window.fetch(this.getEventUrl(),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}catch(t){li.warn("TitanSDK: Usage tracking event failed to send.",t)}}trackUsage(){const e={eventName:"sdk",eventType:"sdk-initialized",eventParams:{appHostname:window.location.hostname,sdkVersion:this.sdkVersion}};return this.track(e)}}const ui=s("WrapperUtils");function gi(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=>{ui.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=>{ui.error("Failed to set up TM settings change handler:",e)}),()=>{i&&i()}}}}function hi(e){return{launch:async(t,i)=>(await e()).apps.launch(t,i)}}const pi=s("SDK"),fi={debug:!1,useLegacyDeviceInfo:!1,legacyDeviceInfoTimeout:5e3,fallbackToBrowser:!0},mi="TITAN_SDK_USAGE_SENT";let vi=null,Si=null,yi=null,bi=null,wi=!1;const Ti=async()=>{if(!vi)throw new E("SDK not created. Call getTitanSDK() first.",I.NOT_INITIALIZED);if(!yi)throw pi.error("SDK initialization not started"),new E("SDK initialization not started.",I.NOT_INITIALIZED);if(!(await yi))throw new E("SDK initialization failed.",I.UNKNOWN);return vi},Ii=e=>{if(Si)return Si;const i={...fi,...e};if(r.setDebugMode(i.debug??!1),!wi){const e="",t=!1;A.initialize({accessToken:e,enabled:t}),wi=!0}const n=j.detectPlatform(i).platform;pi.info("Platform detected:",n);try{switch(n){case t.AOC:vi=new rt(i);break;case t.JVC_HKC:vi=new Tt(i);break;case t.PHILIPS:vi=new Dt(i);break;case t.PHILIPS_OLD:vi=new Ot(i);break;case t.JVC_VESTEL:vi=new jt(i);break;case t.JVC_VESTEL_LEGACY:vi=new ci(i);break;case t.BROWSER:default:n!==t.BROWSER&&i.debug&&pi.warn(`Platform ${n} detected but no specific SDK found, using BrowserSDK as fallback.`),vi=new St(i)}if(!vi)throw new E("Failed to create SDK instance after platform detection",I.UNKNOWN)}catch(c){throw pi.error("Error creating SDK instance:",c),new E(`Failed to create SDK instance after platform detection: ${c}`,I.UNKNOWN)}yi=vi.init(),pi.info("SDK Version:",T);const o={VERSION:T,isReady:yi,deviceInfo:(s=Ti,a=e=>{bi=e},{getDeviceInfo:async()=>{const e=await s(),t=await e.deviceInfo.getDeviceInfo();return null==a||a(t),t}}),accessibility:gi(Ti),apps:hi(Ti)};var s,a;return i.debug&&(pi.info("🔧 [DEBUG MODE] TitanSDK debug access enabled"),o.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=>{ui.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()}}}(Ti)),i.dev&&(i.debug&&pi.info("🔧 [DEV MODE] TitanSDK dev access enabled"),n===t.BROWSER&&i.dev&&(pi.info("Available dev methods:"),pi.info(" sdk.dev.updateTTSSettings({ enabled: true, rate: 1.5 })"),pi.info(" sdk.dev.updateTMSettings({ enabled: true, scale: 1.8 })")),o.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}}}(Ti)),Si=o,yi.then(async()=>{try{bi=await vi.deviceInfo.getDeviceInfo();const e=new di(T);if(!(()=>{try{return!("undefined"==typeof window||!window.localStorage)&&"1"===window.localStorage.getItem(mi)}catch{return!1}})())try{await e.trackUsage(),(()=>{try{if("undefined"==typeof window||!window.localStorage)return;window.localStorage.setItem(mi,"1")}catch{}})()}catch{}}catch(c){i.debug&&pi.warn("Failed to pre-cache device info:",c)}}).catch(e=>{pi.error(`Initialization failed for platform ${n}:`,e)}),Si},Ei=async()=>{const e=await Ti(),t=await e.deviceInfo.getDeviceInfo();return bi=t,t};if("undefined"!=typeof document&&document.addEventListener("securitypolicyviolation",e=>{F.getViolations()}),"undefined"!=typeof window)if(window.TitanSDK&&window.TitanSDK.deviceInfo)pi.info("TitanSDK already exists on window, skipping initialization"),pi.info("You can still create a new SDK instance using window.getTitanSDK(options)"),window.getTitanSDK=Ii;else{const e=()=>{window.onDeviceInfoReady=function(e){Ei().then(t=>e(t)).catch(t=>e({},String(t)))},Object.defineProperty(window,"DeviceInfo",{get:()=>{if(bi)return bi;if(vi&&Si)try{return vi.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=>{try{const t=null==localStorage?void 0:localStorage.getItem(e);return t?JSON.parse(t):{}}catch(t){return r.isDebugMode()&&pi.error(`Failed to parse localStorage key ${e}:`,t),{}}},i=(new g).get("TITAN_SDK_PARAMS")||t("TITAN_SDK_PARAMS");i&&pi.info("Initializing TitanSDK with params:",i),window.TitanSDK=Ii(i),e(),Q(window.TitanSDK).catch(e=>{pi.error("Failed to initialize SmartTvA_API:",e)})}exports.VERSION=T,exports.getDeviceInfo=Ei,exports.getTitanSDK=Ii;
|