/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./src/sos-shim/serviceWorker/sw.ts");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./src/sos-shim/serviceWorker/constants.ts":
/*!*************************************************!*\
  !*** ./src/sos-shim/serviceWorker/constants.ts ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/** Shared between the fileSystem, the serving helper, and the service worker — keep in sync. */\nexports.VIRTUAL_PREFIX = '/__smilfs__/';\nexports.FS_DB_NAME = 'smil-fs';\nexports.FS_STORE = 'files';\n\n//# sourceURL=webpack:///./src/sos-shim/serviceWorker/constants.ts?");

/***/ }),

/***/ "./src/sos-shim/serviceWorker/sw.ts":
/*!******************************************!*\
  !*** ./src/sos-shim/serviceWorker/sw.ts ***!
  \******************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
eval("\n\nvar __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {\n  function adopt(value) {\n    return value instanceof P ? value : new P(function (resolve) {\n      resolve(value);\n    });\n  }\n  return new (P || (P = Promise))(function (resolve, reject) {\n    function fulfilled(value) {\n      try {\n        step(generator.next(value));\n      } catch (e) {\n        reject(e);\n      }\n    }\n    function rejected(value) {\n      try {\n        step(generator[\"throw\"](value));\n      } catch (e) {\n        reject(e);\n      }\n    }\n    function step(result) {\n      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);\n    }\n    step((generator = generator.apply(thisArg, _arguments || [])).next());\n  });\n};\nvar __generator = this && this.__generator || function (thisArg, body) {\n  var _ = {\n      label: 0,\n      sent: function sent() {\n        if (t[0] & 1) throw t[1];\n        return t[1];\n      },\n      trys: [],\n      ops: []\n    },\n    f,\n    y,\n    t,\n    g;\n  return g = {\n    next: verb(0),\n    \"throw\": verb(1),\n    \"return\": verb(2)\n  }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function () {\n    return this;\n  }), g;\n  function verb(n) {\n    return function (v) {\n      return step([n, v]);\n    };\n  }\n  function step(op) {\n    if (f) throw new TypeError(\"Generator is already executing.\");\n    while (_) try {\n      if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n      if (y = 0, t) op = [op[0] & 2, t.value];\n      switch (op[0]) {\n        case 0:\n        case 1:\n          t = op;\n          break;\n        case 4:\n          _.label++;\n          return {\n            value: op[1],\n            done: false\n          };\n        case 5:\n          _.label++;\n          y = op[1];\n          op = [0];\n          continue;\n        case 7:\n          op = _.ops.pop();\n          _.trys.pop();\n          continue;\n        default:\n          if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {\n            _ = 0;\n            continue;\n          }\n          if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {\n            _.label = op[1];\n            break;\n          }\n          if (op[0] === 6 && _.label < t[1]) {\n            _.label = t[1];\n            t = op;\n            break;\n          }\n          if (t && _.label < t[2]) {\n            _.label = t[2];\n            _.ops.push(op);\n            break;\n          }\n          if (t[2]) _.ops.pop();\n          _.trys.pop();\n          continue;\n      }\n      op = body.call(thisArg, _);\n    } catch (e) {\n      op = [6, e];\n      y = 0;\n    } finally {\n      f = t = 0;\n    }\n    if (op[0] & 5) throw op[1];\n    return {\n      value: op[0] ? op[1] : void 0,\n      done: true\n    };\n  }\n};\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\n/**\n * Media-serving service worker. Intercepts requests under VIRTUAL_PREFIX and serves the bytes\n * straight from the fileSystem's IndexedDB, with HTTP Range support (206) for video seeking and\n * working relative paths for widget assets. Built as a separate webpack entry (__smil_sw.js).\n *\n * `self`/`clients`/`skipWaiting` are service-worker globals not in the dom lib; accessed via an\n * `any` cast to avoid pulling the conflicting webworker lib into the program.\n */\nvar constants_1 = __webpack_require__(/*! ./constants */ \"./src/sos-shim/serviceWorker/constants.ts\");\nvar ctx = self;\n// App-shell cache (PWA): precache the bundle so the player loads with NO network — required for offline\n// in a plain browser / on a bucket (the native Android/Electron shells serve the bundle from a local\n// server instead, so they don't need this). The native side still serves media from IndexedDB (below).\nvar SHELL_CACHE = 'smil-shell-v1';\n// NOTE: /config.json is deliberately NOT precached — it is device-specific (pairing URL, etc.) and must\n// never be frozen by the SW, or a device would boot stale config offline. Config is always network-only.\nvar SHELL_ASSETS = ['/', '/index.html', '/index.js'];\n// Media-only mode (?shell=0): native shells serve their own bundle, so the SW does ONLY media plane work\n// and never touches the app shell — no precache, no runtime caching, no fetch interception of GETs.\nfunction shellEnabled() {\n  try {\n    return new URL(ctx.location.href).searchParams.get('shell') !== '0';\n  } catch (_a) {\n    return true;\n  }\n}\nvar SHELL_ON = shellEnabled();\n// Only these app-shell paths (plus same-origin scripts/styles) are runtime-cached. Everything else —\n// notably /config.json and any device API — goes straight to the network and is never frozen.\nfunction isShellRequest(url, request) {\n  if (url.pathname === '/config.json') {\n    return false;\n  }\n  if (request.mode === 'navigate') {\n    return true;\n  }\n  if (SHELL_ASSETS.indexOf(url.pathname) !== -1) {\n    return true;\n  }\n  return /\\.(?:js|css|woff2?|ttf|png|svg|ico)$/.test(url.pathname);\n}\nctx.addEventListener('install', function (event) {\n  ctx.skipWaiting();\n  if (!SHELL_ON) {\n    return;\n  }\n  event.waitUntil(function () {\n    return __awaiter(void 0, void 0, void 0, function () {\n      var cache_1, _a;\n      return __generator(this, function (_b) {\n        switch (_b.label) {\n          case 0:\n            _b.trys.push([0, 3,, 4]);\n            return [4 /*yield*/, ctx.caches.open(SHELL_CACHE)];\n          case 1:\n            cache_1 = _b.sent();\n            // add individually so one 404 doesn't abort the whole precache\n            return [4 /*yield*/, Promise.all(SHELL_ASSETS.map(function (a) {\n              return cache_1.add(new Request(a, {\n                cache: 'reload'\n              }))[\"catch\"](function () {\n                return undefined;\n              });\n            }))];\n          case 2:\n            // add individually so one 404 doesn't abort the whole precache\n            _b.sent();\n            return [3 /*break*/, 4];\n          case 3:\n            _a = _b.sent();\n            return [3 /*break*/, 4];\n          case 4:\n            return [2 /*return*/];\n        }\n      });\n    });\n  }());\n});\nctx.addEventListener('activate', function (event) {\n  return event.waitUntil(function () {\n    return __awaiter(void 0, void 0, void 0, function () {\n      var keys, _a;\n      return __generator(this, function (_b) {\n        switch (_b.label) {\n          case 0:\n            _b.trys.push([0, 3,, 4]);\n            return [4 /*yield*/, ctx.caches.keys()];\n          case 1:\n            keys = _b.sent();\n            return [4 /*yield*/, Promise.all(keys.filter(function (k) {\n              return k !== SHELL_CACHE;\n            }).map(function (k) {\n              return ctx.caches[\"delete\"](k);\n            }))];\n          case 2:\n            _b.sent();\n            return [3 /*break*/, 4];\n          case 3:\n            _a = _b.sent();\n            return [3 /*break*/, 4];\n          case 4:\n            return [4 /*yield*/, ctx.clients.claim()];\n          case 5:\n            _b.sent();\n            return [2 /*return*/];\n        }\n      });\n    });\n  }());\n});\nctx.addEventListener('fetch', function (event) {\n  var url;\n  try {\n    url = new URL(event.request.url);\n  } catch (_a) {\n    return;\n  }\n  if (url.origin !== ctx.location.origin) {\n    return; // cross-origin (tenant media etc.) — let the network/CORS handle it\n  }\n  // media plane: serve straight from IndexedDB with Range support\n  if (url.pathname.indexOf(constants_1.VIRTUAL_PREFIX) === 0) {\n    event.respondWith(serve(event.request, url));\n    return;\n  }\n  // app shell: network-first so online stays fresh, fall back to cache so offline still boots. Only on\n  // browser/bucket (SHELL_ON) and only for true shell paths — config/API requests pass through untouched.\n  if (SHELL_ON && event.request.method === 'GET' && isShellRequest(url, event.request)) {\n    event.respondWith(appShell(event.request));\n  }\n});\n/** Network-first with cache fallback for the app shell; navigations fall back to the cached index. */\nfunction appShell(request) {\n  return __awaiter(this, void 0, void 0, function () {\n    var fresh, cache, _a, _b, cached, index, _c;\n    return __generator(this, function (_d) {\n      switch (_d.label) {\n        case 0:\n          _d.trys.push([0, 6,, 12]);\n          return [4 /*yield*/, fetch(request)];\n        case 1:\n          fresh = _d.sent();\n          if (!(fresh && fresh.ok)) return [3 /*break*/, 5];\n          _d.label = 2;\n        case 2:\n          _d.trys.push([2, 4,, 5]);\n          return [4 /*yield*/, ctx.caches.open(SHELL_CACHE)];\n        case 3:\n          cache = _d.sent();\n          cache.put(request, fresh.clone());\n          return [3 /*break*/, 5];\n        case 4:\n          _a = _d.sent();\n          return [3 /*break*/, 5];\n        case 5:\n          return [2 /*return*/, fresh];\n        case 6:\n          _b = _d.sent();\n          return [4 /*yield*/, ctx.caches.match(request)];\n        case 7:\n          cached = _d.sent();\n          if (cached) {\n            return [2 /*return*/, cached];\n          }\n          if (!(request.mode === 'navigate')) return [3 /*break*/, 11];\n          return [4 /*yield*/, ctx.caches.match('/index.html')];\n        case 8:\n          _c = _d.sent();\n          if (_c) return [3 /*break*/, 10];\n          return [4 /*yield*/, ctx.caches.match('/')];\n        case 9:\n          _c = _d.sent();\n          _d.label = 10;\n        case 10:\n          index = _c;\n          if (index) {\n            return [2 /*return*/, index];\n          }\n          _d.label = 11;\n        case 11:\n          return [2 /*return*/, new Response('offline', {\n            status: 504\n          })];\n        case 12:\n          return [2 /*return*/];\n      }\n    });\n  });\n}\nfunction serve(request, url) {\n  return __awaiter(this, void 0, void 0, function () {\n    var path, blob, type, rangeHeader, match, hasStart, start, end, n;\n    return __generator(this, function (_a) {\n      switch (_a.label) {\n        case 0:\n          path = url.pathname.slice(constants_1.VIRTUAL_PREFIX.length).split('/').map(function (segment) {\n            return decodeURIComponent(segment);\n          }).join('/');\n          return [4 /*yield*/, readBlob(path)];\n        case 1:\n          blob = _a.sent();\n          if (!blob) {\n            return [2 /*return*/, new Response('Not found', {\n              status: 404\n            })];\n          }\n          type = blob.type || 'application/octet-stream';\n          rangeHeader = request.headers.get('range');\n          if (rangeHeader) {\n            match = /bytes=(\\d*)-(\\d*)/.exec(rangeHeader);\n            hasStart = !!(match && match[1]);\n            start = void 0;\n            end = void 0;\n            if (!hasStart && match && match[2]) {\n              n = parseInt(match[2], 10);\n              end = blob.size - 1;\n              start = isNaN(n) ? 0 : Math.max(0, blob.size - n);\n            } else {\n              start = hasStart ? parseInt(match[1], 10) : 0;\n              end = match && match[2] ? parseInt(match[2], 10) : blob.size - 1;\n            }\n            if (isNaN(start) || start < 0) {\n              start = 0;\n            }\n            if (isNaN(end) || end >= blob.size) {\n              end = blob.size - 1;\n            }\n            if (start > end) {\n              return [2 /*return*/, new Response(null, {\n                status: 416,\n                headers: {\n                  'Content-Range': \"bytes */\" + blob.size\n                }\n              })];\n            }\n            return [2 /*return*/, new Response(blob.slice(start, end + 1, type), {\n              status: 206,\n              headers: {\n                'Content-Type': type,\n                'Accept-Ranges': 'bytes',\n                'Content-Range': \"bytes \" + start + \"-\" + end + \"/\" + blob.size,\n                'Content-Length': String(end - start + 1),\n                // always read fresh from IndexedDB — a virtual path can be reused for new bytes after a\n                // re-download, so the browser's HTTP cache in front of the SW must not retain old media\n                'Cache-Control': 'no-store'\n              }\n            })];\n          }\n          return [2 /*return*/, new Response(blob, {\n            status: 200,\n            headers: {\n              'Content-Type': type,\n              'Accept-Ranges': 'bytes',\n              'Content-Length': String(blob.size),\n              'Cache-Control': 'no-store'\n            }\n          })];\n      }\n    });\n  });\n}\nfunction readBlob(path) {\n  return new Promise(function (resolve) {\n    var open = indexedDB.open(constants_1.FS_DB_NAME, 1);\n    open.onupgradeneeded = function () {\n      // If the SW happens to open the DB first, create the store so the version matches.\n      var db = open.result;\n      if (!db.objectStoreNames.contains(constants_1.FS_STORE)) {\n        db.createObjectStore(constants_1.FS_STORE, {\n          keyPath: 'path'\n        });\n      }\n    };\n    open.onsuccess = function () {\n      try {\n        var req_1 = open.result.transaction(constants_1.FS_STORE, 'readonly').objectStore(constants_1.FS_STORE).get(path);\n        req_1.onsuccess = function () {\n          var record = req_1.result;\n          resolve(record && record.blob ? record.blob : null);\n        };\n        req_1.onerror = function () {\n          return resolve(null);\n        };\n      } catch (_a) {\n        resolve(null);\n      }\n    };\n    open.onerror = function () {\n      return resolve(null);\n    };\n  });\n}\n\n//# sourceURL=webpack:///./src/sos-shim/serviceWorker/sw.ts?");

/***/ })

/******/ });