stormcloud-video-player 0.8.23 → 0.8.24

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.
@@ -1510,1175 +1510,1226 @@ function publishMQTT(topic, payload) {
1510
1510
  return false;
1511
1511
  }
1512
1512
  }
1513
- // src/utils/tracking.ts
1514
- var cachedBrowserId = null;
1515
- function getClientInfo() {
1516
- var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
1513
+ // src/utils/vastEnvironmentSignals.ts
1514
+ var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
1515
+ var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
1516
+ var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
1517
+ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
1518
+ var AIRY_APP_NAME = "AiryTV Movies & TV";
1519
+ var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
1520
+ var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
1521
+ var PLAYER_ID_STORAGE_KEY = "stormcloud.player.id";
1522
+ var LG_TEST_APP_ID = "com.hulu.plus";
1523
+ var LG_TEST_APP_NAME = "Hulu";
1524
+ var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
1525
+ var _lgTestDeviceId;
1526
+ function getLgTestDeviceId() {
1527
+ if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
1528
+ return _lgTestDeviceId;
1529
+ }
1530
+ function isLgWebOS() {
1531
+ if (typeof navigator === "undefined") return false;
1532
+ return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
1533
+ }
1534
+ function getDefaultAppId() {
1535
+ if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
1517
1536
  var ua = navigator.userAgent;
1518
- var platform = navigator.platform;
1519
- var vendor = navigator.vendor || "";
1520
- var maxTouchPoints = navigator.maxTouchPoints || 0;
1521
- var memory = navigator.deviceMemory || null;
1522
- var hardwareConcurrency = navigator.hardwareConcurrency || 1;
1523
- var screenInfo = {
1524
- width: (_screen = screen) === null || _screen === void 0 ? void 0 : _screen.width,
1525
- height: (_screen1 = screen) === null || _screen1 === void 0 ? void 0 : _screen1.height,
1526
- availWidth: (_screen2 = screen) === null || _screen2 === void 0 ? void 0 : _screen2.availWidth,
1527
- availHeight: (_screen3 = screen) === null || _screen3 === void 0 ? void 0 : _screen3.availHeight,
1528
- orientation: ((_screen4 = screen) === null || _screen4 === void 0 ? void 0 : (_screen_orientation = _screen4.orientation) === null || _screen_orientation === void 0 ? void 0 : _screen_orientation.type) || "",
1529
- pixelDepth: (_screen5 = screen) === null || _screen5 === void 0 ? void 0 : _screen5.pixelDepth
1530
- };
1531
- var deviceType = "desktop";
1532
- var brand = "Unknown";
1533
- var os = "Unknown";
1534
- var model = "";
1535
- var isSmartTV = false;
1536
- var isAndroid = false;
1537
- var isWebView = false;
1538
- var isWebApp = false;
1539
- if (ua.includes("Web0S")) {
1540
- brand = "LG";
1541
- os = "webOS";
1542
- isSmartTV = true;
1543
- deviceType = "tv";
1544
- var webosMatch = ua.match(/Web0S\/([^\s]+)/);
1545
- model = webosMatch ? "webOS ".concat(webosMatch[1]) : "webOS TV";
1546
- } else if (ua.includes("Tizen")) {
1547
- brand = "Samsung";
1548
- os = "Tizen";
1549
- isSmartTV = true;
1550
- deviceType = "tv";
1551
- var tizenMatch = ua.match(/Tizen\/([^\s]+)/);
1552
- var tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? "Smart TV" : "";
1553
- model = tizenMatch ? "Tizen ".concat(tizenMatch[1], " ").concat(tvMatch).trim() : "Tizen TV";
1554
- } else if (ua.includes("Philips")) {
1555
- brand = "Philips";
1556
- os = "Saphi";
1557
- isSmartTV = true;
1558
- deviceType = "tv";
1559
- } else if (ua.includes("Sharp") || ua.includes("AQUOS")) {
1560
- brand = "Sharp";
1561
- os = "Android TV";
1562
- isSmartTV = true;
1563
- deviceType = "tv";
1564
- } else if (ua.includes("Android") && (ua.includes("Sony") || vendor.includes("Sony"))) {
1565
- brand = "Sony";
1566
- os = "Android TV";
1567
- isSmartTV = true;
1568
- deviceType = "tv";
1569
- } else if (ua.includes("Android") && (ua.includes("NetCast") || ua.includes("LG"))) {
1570
- brand = "LG";
1571
- os = "Android TV";
1572
- isSmartTV = true;
1573
- deviceType = "tv";
1574
- } else if (ua.includes(" Roku") || ua.includes("Roku/")) {
1575
- brand = "Roku";
1576
- os = "Roku OS";
1577
- isSmartTV = true;
1578
- deviceType = "tv";
1579
- } else if (ua.includes("AppleTV")) {
1580
- brand = "Apple";
1581
- os = "tvOS";
1582
- isSmartTV = true;
1583
- deviceType = "tv";
1537
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
1538
+ if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
1539
+ if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
1540
+ return AIRY_ANDROID_APP_ID;
1541
+ }
1542
+ var DEVICE_ID_STORAGE_KEYS = [
1543
+ "rdid",
1544
+ "ifa",
1545
+ "advertisingId",
1546
+ "advertising_id",
1547
+ "deviceAdvertisingId",
1548
+ "aaid",
1549
+ "adid",
1550
+ "rida",
1551
+ "tifa",
1552
+ "lgudid"
1553
+ ];
1554
+ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
1555
+ "aaid",
1556
+ "adid"
1557
+ ]);
1558
+ function resolveVastEnvironmentSignals(isCtv) {
1559
+ var _ref;
1560
+ var bridgeSignals = readNativeBridgeSignals();
1561
+ var platformDevice = readPlatformNativeDeviceId();
1562
+ var lg = isCtv && isLgWebOS();
1563
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
1564
+ var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
1565
+ var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
1566
+ var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
1567
+ if (isCtv) {
1568
+ return _object_spread_props(_object_spread({
1569
+ isCtv: true,
1570
+ contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
1571
+ appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
1572
+ appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
1573
+ sessionId: getOrCreateCtvSessionId()
1574
+ }, deviceId ? {
1575
+ deviceId: deviceId
1576
+ } : {}, deviceIdType ? {
1577
+ deviceIdType: deviceIdType
1578
+ } : {}, limitAdTracking != null ? {
1579
+ limitAdTracking: limitAdTracking
1580
+ } : {}), {
1581
+ deviceTypeHint: 5
1582
+ });
1584
1583
  }
1585
- if (ua.includes("Android")) {
1586
- isAndroid = true;
1587
- os = "Android";
1588
- deviceType = /Mobile/.test(ua) ? "mobile" : "tablet";
1589
- if (ua.includes("Android") && (maxTouchPoints === 0 || ua.includes("Google TV") || ua.includes("XiaoMi"))) {
1590
- deviceType = "tv";
1591
- isSmartTV = true;
1592
- brand = brand === "Unknown" ? "Android TV" : brand;
1593
- }
1594
- var androidModelMatch = ua.match(/\(([^)]*Android[^)]*)\)/);
1595
- if (androidModelMatch && androidModelMatch[1]) {
1596
- model = androidModelMatch[1];
1597
- }
1584
+ return _object_spread({
1585
+ isCtv: false
1586
+ }, deviceId ? {
1587
+ deviceId: deviceId
1588
+ } : {}, deviceIdType ? {
1589
+ deviceIdType: deviceIdType
1590
+ } : {}, limitAdTracking != null ? {
1591
+ limitAdTracking: limitAdTracking
1592
+ } : {});
1593
+ }
1594
+ function inferDeviceIdType() {
1595
+ if (typeof navigator === "undefined") {
1596
+ return void 0;
1598
1597
  }
1599
- if (/iPad|iPhone|iPod/.test(ua)) {
1600
- os = "iOS";
1601
- deviceType = "mobile";
1602
- brand = "Apple";
1603
- if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {
1604
- deviceType = "tablet";
1605
- }
1598
+ var ua = navigator.userAgent;
1599
+ if (/Roku/i.test(ua)) return "rida";
1600
+ if (/Tizen|Samsung/i.test(ua)) return "tifa";
1601
+ if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
1602
+ if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
1603
+ if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
1604
+ if (/Android|Google TV/i.test(ua)) return "aaid";
1605
+ if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
1606
+ return void 0;
1607
+ }
1608
+ function isEquivalentDeviceIdType(tagType, runtimeType) {
1609
+ if (!tagType || !runtimeType) return false;
1610
+ var tag = tagType.toLowerCase();
1611
+ var runtime = runtimeType.toLowerCase();
1612
+ if (tag === runtime) return true;
1613
+ return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
1614
+ }
1615
+ function resolveNativeDeviceId() {
1616
+ var bridgeSignals = readNativeBridgeSignals();
1617
+ var platformDevice = readPlatformNativeDeviceId();
1618
+ var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId;
1619
+ if (!deviceId || isMacroPlaceholder(deviceId) || isZeroedAdId(deviceId)) {
1620
+ return void 0;
1606
1621
  }
1607
- if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {
1608
- if (ua.includes("Windows")) {
1609
- os = "Windows";
1610
- deviceType = "desktop";
1611
- } else if (ua.includes("Mac") && !/iPhone/.test(ua)) {
1612
- os = "macOS";
1613
- deviceType = "desktop";
1614
- if (maxTouchPoints > 1) deviceType = "tablet";
1615
- } else if (ua.includes("Linux")) {
1616
- os = "Linux";
1617
- deviceType = "desktop";
1618
- }
1622
+ return deviceId;
1623
+ }
1624
+ function getOrCreateStoredUuid(storageKey) {
1625
+ if (typeof window === "undefined") {
1626
+ return void 0;
1619
1627
  }
1620
- if (brand === "Unknown") {
1621
- if (vendor.includes("Google") || ua.includes("Chrome")) brand = "Google";
1622
- if (vendor.includes("Apple")) brand = "Apple";
1623
- if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
1628
+ var existing = readStoredString(storageKey);
1629
+ if (existing) {
1630
+ return existing;
1624
1631
  }
1625
- isWebView = /wv|WebView|Linux; U;/.test(ua);
1626
- if (((_window = window) === null || _window === void 0 ? void 0 : _window.outerHeight) === 0 && ((_window1 = window) === null || _window1 === void 0 ? void 0 : _window1.outerWidth) === 0) {
1627
- isWebView = true;
1632
+ var id = createUuid();
1633
+ try {
1634
+ var _window_localStorage;
1635
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(storageKey, id);
1636
+ } catch (unused) {}
1637
+ return id;
1638
+ }
1639
+ function getOrCreateCtvSessionId() {
1640
+ var existing = readStoredString(CTV_SESSION_STORAGE_KEY);
1641
+ if (existing) {
1642
+ return existing;
1628
1643
  }
1629
- isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_window_screen = window.screen) === null || _window_screen === void 0 ? void 0 : (_window_screen_orientation = _window_screen.orientation) === null || _window_screen_orientation === void 0 ? void 0 : _window_screen_orientation.angle) !== void 0;
1630
- return {
1631
- brand: brand,
1632
- os: os,
1633
- model: model || ua.substring(0, 50) + "...",
1634
- deviceType: deviceType,
1635
- isSmartTV: isSmartTV,
1636
- isAndroid: isAndroid,
1637
- isWebView: isWebView,
1638
- isWebApp: isWebApp,
1639
- domain: window.location.hostname,
1640
- origin: window.location.origin,
1641
- path: window.location.pathname,
1642
- userAgent: ua,
1643
- vendor: vendor,
1644
- platform: platform,
1645
- screen: screenInfo,
1646
- hardwareConcurrency: hardwareConcurrency,
1647
- deviceMemory: memory,
1648
- maxTouchPoints: maxTouchPoints,
1649
- language: navigator.language,
1650
- languages: ((_navigator_languages = navigator.languages) === null || _navigator_languages === void 0 ? void 0 : _navigator_languages.join(",")) || "",
1651
- cookieEnabled: navigator.cookieEnabled,
1652
- doNotTrack: navigator.doNotTrack || "",
1653
- referrer: document.referrer,
1654
- visibilityState: document.visibilityState
1655
- };
1644
+ var sessionId = createUuid();
1645
+ try {
1646
+ var _window_localStorage;
1647
+ (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(CTV_SESSION_STORAGE_KEY, sessionId);
1648
+ } catch (unused) {}
1649
+ return sessionId;
1656
1650
  }
1657
- function getBrowserID(clientInfo) {
1658
- return _async_to_generator(function() {
1659
- var _crypto_subtle, fingerprintString, encodedData, utf8, buffer, i, hashBuffer, hashHex, unused, hash, i1, char, fallbackHash, timestamp, random;
1660
- return _ts_generator(this, function(_state) {
1661
- switch(_state.label){
1662
- case 0:
1663
- if (cachedBrowserId) {
1664
- return [
1665
- 2,
1666
- cachedBrowserId
1667
- ];
1668
- }
1669
- fingerprintString = JSON.stringify(clientInfo);
1670
- if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
1671
- 3,
1672
- 5
1673
- ];
1674
- _state.label = 1;
1675
- case 1:
1676
- _state.trys.push([
1677
- 1,
1678
- 4,
1679
- ,
1680
- 5
1681
- ]);
1682
- return [
1683
- 4,
1684
- crypto.subtle.digest("SHA-256", new Uint8Array([
1685
- 1,
1686
- 2,
1687
- 3
1688
- ]))
1689
- ];
1690
- case 2:
1691
- _state.sent();
1692
- if (typeof TextEncoder !== "undefined") {
1693
- encodedData = new TextEncoder().encode(fingerprintString);
1694
- } else {
1695
- utf8 = unescape(encodeURIComponent(fingerprintString));
1696
- buffer = new Uint8Array(utf8.length);
1697
- for(i = 0; i < utf8.length; i++){
1698
- buffer[i] = utf8.charCodeAt(i);
1699
- }
1700
- encodedData = buffer;
1701
- }
1702
- return [
1703
- 4,
1704
- crypto.subtle.digest("SHA-256", encodedData)
1705
- ];
1706
- case 3:
1707
- hashBuffer = _state.sent();
1708
- hashHex = Array.from(new Uint8Array(hashBuffer)).map(function(b) {
1709
- return b.toString(16).padStart(2, "0");
1710
- }).join("");
1711
- cachedBrowserId = hashHex;
1712
- return [
1713
- 2,
1714
- hashHex
1715
- ];
1716
- case 4:
1717
- unused = _state.sent();
1718
- console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
1719
- return [
1720
- 3,
1721
- 5
1722
- ];
1723
- case 5:
1724
- hash = 0;
1725
- for(i1 = 0; i1 < fingerprintString.length; i1++){
1726
- char = fingerprintString.charCodeAt(i1);
1727
- hash = (hash << 5) - hash + char;
1728
- hash = hash & hash;
1729
- }
1730
- fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
1731
- timestamp = Date.now().toString(16).padStart(12, "0");
1732
- random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
1733
- cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, "0");
1734
- return [
1735
- 2,
1736
- cachedBrowserId
1737
- ];
1738
- }
1739
- });
1740
- })();
1741
- }
1742
- function canPublish(licenseKey) {
1743
- return Boolean(isMQTTEnabled() && licenseKey);
1651
+ function createUuid() {
1652
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1653
+ return crypto.randomUUID();
1654
+ }
1655
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
1656
+ var value = Math.floor(Math.random() * 16);
1657
+ var nibble = char === "x" ? value : value & 3 | 8;
1658
+ return nibble.toString(16);
1659
+ });
1744
1660
  }
1745
- function buildPlayerMetricEvent() {
1746
- return _async_to_generator(function() {
1747
- var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
1748
- var _arguments = arguments;
1749
- return _ts_generator(this, function(_state) {
1750
- switch(_state.label){
1751
- case 0:
1752
- context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
1753
- clientInfo = getClientInfo();
1754
- return [
1755
- 4,
1756
- getBrowserID(clientInfo)
1757
- ];
1758
- case 1:
1759
- playerId = _state.sent();
1760
- captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
1761
- return [
1762
- 2,
1763
- _object_spread({
1764
- player_id: playerId,
1765
- device_type: clientInfo.deviceType,
1766
- os: clientInfo.os.toLowerCase(),
1767
- ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
1768
- ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
1769
- capture_at: captureAt
1770
- }, context.inputStreamType ? {
1771
- input_stream_type: context.inputStreamType
1772
- } : {})
1773
- ];
1661
+ function readPlatformNativeDeviceId() {
1662
+ if (typeof window === "undefined") return {};
1663
+ try {
1664
+ var _window_webapis;
1665
+ var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
1666
+ if (adinfo) {
1667
+ var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
1668
+ if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
1669
+ var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
1670
+ return _object_spread({
1671
+ deviceId: tifa,
1672
+ deviceIdType: "tifa"
1673
+ }, typeof lat === "boolean" ? {
1674
+ limitAdTracking: lat
1675
+ } : {});
1774
1676
  }
1775
- });
1776
- }).apply(this, arguments);
1677
+ }
1678
+ } catch (unused) {}
1679
+ try {
1680
+ var webOSDev = window.webOSDev;
1681
+ if (webOSDev) {
1682
+ var _webOSDev_lgudid;
1683
+ var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
1684
+ if (typeof lgudid === "string" && lgudid) {
1685
+ if (isZeroedAdId(lgudid)) {
1686
+ return {
1687
+ deviceIdType: "lgudid",
1688
+ limitAdTracking: true
1689
+ };
1690
+ }
1691
+ if (!isMacroPlaceholder(lgudid)) {
1692
+ return {
1693
+ deviceId: lgudid,
1694
+ deviceIdType: "lgudid",
1695
+ limitAdTracking: false
1696
+ };
1697
+ }
1698
+ }
1699
+ }
1700
+ } catch (unused) {}
1701
+ try {
1702
+ var roku = window.Roku;
1703
+ if (roku) {
1704
+ var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
1705
+ if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
1706
+ return {
1707
+ deviceId: rida,
1708
+ deviceIdType: "rida",
1709
+ limitAdTracking: false
1710
+ };
1711
+ }
1712
+ }
1713
+ } catch (unused) {}
1714
+ return {};
1777
1715
  }
1778
- function publishTracking(licenseKey, channel, body) {
1779
- ensureMQTTClient();
1780
- publishMQTT(buildPlayerTopic(licenseKey, channel), body);
1716
+ var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
1717
+ "38400000-8cf0-11bd-b23e-10b96e40000d",
1718
+ "00000000-0000-0000-0000-000000000000"
1719
+ ]);
1720
+ function isMacroPlaceholder(value) {
1721
+ var t = value.trim();
1722
+ return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
1781
1723
  }
1782
- function sendInitialTracking(_0) {
1783
- return _async_to_generator(function(licenseKey) {
1784
- var context, metricEvent, error;
1785
- var _arguments = arguments;
1786
- return _ts_generator(this, function(_state) {
1787
- switch(_state.label){
1788
- case 0:
1789
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
1790
- if (!canPublish(licenseKey)) return [
1791
- 2
1792
- ];
1793
- _state.label = 1;
1794
- case 1:
1795
- _state.trys.push([
1796
- 1,
1797
- 3,
1798
- ,
1799
- 4
1800
- ]);
1801
- return [
1802
- 4,
1803
- buildPlayerMetricEvent(context, {
1804
- adLoaded: false,
1805
- adDetect: false
1806
- })
1807
- ];
1808
- case 2:
1809
- metricEvent = _state.sent();
1810
- publishTracking(licenseKey, "metrics", {
1811
- events: [
1812
- metricEvent
1813
- ]
1814
- });
1815
- return [
1816
- 3,
1817
- 4
1818
- ];
1819
- case 3:
1820
- error = _state.sent();
1821
- console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
1822
- return [
1823
- 3,
1824
- 4
1825
- ];
1826
- case 4:
1827
- return [
1828
- 2
1829
- ];
1830
- }
1831
- });
1832
- }).apply(this, arguments);
1724
+ function isZeroedAdId(value) {
1725
+ return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
1833
1726
  }
1834
- function sendAdDetectTracking(_0, _1) {
1835
- return _async_to_generator(function(licenseKey, adDetectInfo) {
1836
- var context, error;
1837
- var _arguments = arguments;
1838
- return _ts_generator(this, function(_state) {
1839
- switch(_state.label){
1840
- case 0:
1841
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1842
- _state.label = 1;
1843
- case 1:
1844
- _state.trys.push([
1845
- 1,
1846
- 3,
1847
- ,
1848
- 4
1849
- ]);
1850
- return [
1851
- 4,
1852
- sendHeartbeat(licenseKey, context, {
1853
- adDetect: true,
1854
- captureAt: adDetectInfo.timestamp
1855
- })
1856
- ];
1857
- case 2:
1858
- _state.sent();
1859
- return [
1860
- 3,
1861
- 4
1862
- ];
1863
- case 3:
1864
- error = _state.sent();
1865
- console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
1866
- return [
1867
- 3,
1868
- 4
1869
- ];
1870
- case 4:
1871
- return [
1872
- 2
1873
- ];
1727
+ function readNativeBridgeSignals() {
1728
+ if (typeof window === "undefined") {
1729
+ return {};
1730
+ }
1731
+ var candidates = [
1732
+ window.__STORMCLOUD_CTV_AD_INFO__,
1733
+ window.__STORMCLOUD_CTV__,
1734
+ window.stormcloudCtv,
1735
+ window.AiryTV,
1736
+ window.Android,
1737
+ window.webOS,
1738
+ window.tizen,
1739
+ window.amazon
1740
+ ].filter(Boolean);
1741
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1742
+ try {
1743
+ for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1744
+ var source = _step.value;
1745
+ var contentUrl = readBridgeValue(source, [
1746
+ "contentUrl",
1747
+ "url",
1748
+ "videoUrl",
1749
+ "canonicalUrl"
1750
+ ]) || void 0;
1751
+ var appId = readBridgeValue(source, [
1752
+ "appId",
1753
+ "msid",
1754
+ "applicationId",
1755
+ "packageName"
1756
+ ]) || void 0;
1757
+ var appName = readBridgeValue(source, [
1758
+ "appName",
1759
+ "an",
1760
+ "applicationName"
1761
+ ]) || void 0;
1762
+ var deviceId = readBridgeValue(source, [
1763
+ "rdid",
1764
+ "ifa",
1765
+ "advertisingId",
1766
+ "adId",
1767
+ "deviceId",
1768
+ "lgudid",
1769
+ "LGUDID",
1770
+ "tifa",
1771
+ "rida",
1772
+ "afai",
1773
+ "aaid"
1774
+ ]) || void 0;
1775
+ if (!contentUrl && !deviceId && !appId && !appName) continue;
1776
+ var deviceIdType = readBridgeValue(source, [
1777
+ "idtype",
1778
+ "deviceIdType",
1779
+ "advertisingIdType",
1780
+ "idType"
1781
+ ]) || inferDeviceIdType();
1782
+ var limitAdTracking = readBridgeBoolean(source, [
1783
+ "is_lat",
1784
+ "limitAdTracking",
1785
+ "limitedAdTracking",
1786
+ "lat"
1787
+ ]);
1788
+ return _object_spread({}, contentUrl ? {
1789
+ contentUrl: contentUrl
1790
+ } : {}, appId ? {
1791
+ appId: appId
1792
+ } : {}, appName ? {
1793
+ appName: appName
1794
+ } : {}, deviceId ? {
1795
+ deviceId: deviceId
1796
+ } : {}, deviceId && deviceIdType ? {
1797
+ deviceIdType: deviceIdType
1798
+ } : {}, deviceId && limitAdTracking != null ? {
1799
+ limitAdTracking: limitAdTracking
1800
+ } : {});
1801
+ }
1802
+ } catch (err) {
1803
+ _didIteratorError = true;
1804
+ _iteratorError = err;
1805
+ } finally{
1806
+ try {
1807
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1808
+ _iterator.return();
1874
1809
  }
1875
- });
1876
- }).apply(this, arguments);
1810
+ } finally{
1811
+ if (_didIteratorError) {
1812
+ throw _iteratorError;
1813
+ }
1814
+ }
1815
+ }
1816
+ return {};
1877
1817
  }
1878
- function sendAdLoadedTracking(_0, _1) {
1879
- return _async_to_generator(function(licenseKey, adLoadedInfo) {
1880
- var context, error;
1881
- var _arguments = arguments;
1882
- return _ts_generator(this, function(_state) {
1883
- switch(_state.label){
1884
- case 0:
1885
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1886
- _state.label = 1;
1887
- case 1:
1888
- _state.trys.push([
1889
- 1,
1890
- 3,
1891
- ,
1892
- 4
1893
- ]);
1894
- return [
1895
- 4,
1896
- sendHeartbeat(licenseKey, context, {
1897
- adLoaded: true,
1898
- captureAt: adLoadedInfo.timestamp
1899
- })
1900
- ];
1901
- case 2:
1902
- _state.sent();
1903
- return [
1904
- 3,
1905
- 4
1906
- ];
1907
- case 3:
1908
- error = _state.sent();
1909
- console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
1910
- return [
1911
- 3,
1912
- 4
1913
- ];
1914
- case 4:
1915
- return [
1916
- 2
1917
- ];
1818
+ function readBridgeValue(source, keys) {
1819
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1820
+ try {
1821
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1822
+ var key = _step.value;
1823
+ var value = source === null || source === void 0 ? void 0 : source[key];
1824
+ if (typeof value === "string" && value) {
1825
+ return value;
1918
1826
  }
1919
- });
1920
- }).apply(this, arguments);
1827
+ if (typeof value === "function") {
1828
+ try {
1829
+ var result = value.call(source);
1830
+ if (typeof result === "string" && result) {
1831
+ return result;
1832
+ }
1833
+ } catch (unused) {}
1834
+ }
1835
+ }
1836
+ } catch (err) {
1837
+ _didIteratorError = true;
1838
+ _iteratorError = err;
1839
+ } finally{
1840
+ try {
1841
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1842
+ _iterator.return();
1843
+ }
1844
+ } finally{
1845
+ if (_didIteratorError) {
1846
+ throw _iteratorError;
1847
+ }
1848
+ }
1849
+ }
1850
+ return void 0;
1851
+ }
1852
+ function readBridgeBoolean(source, keys) {
1853
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1854
+ try {
1855
+ for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1856
+ var key = _step.value;
1857
+ var value = source === null || source === void 0 ? void 0 : source[key];
1858
+ var normalized = normalizeBoolean(value);
1859
+ if (normalized != null) {
1860
+ return normalized;
1861
+ }
1862
+ if (typeof value === "function") {
1863
+ try {
1864
+ var result = normalizeBoolean(value.call(source));
1865
+ if (result != null) {
1866
+ return result;
1867
+ }
1868
+ } catch (unused) {}
1869
+ }
1870
+ }
1871
+ } catch (err) {
1872
+ _didIteratorError = true;
1873
+ _iteratorError = err;
1874
+ } finally{
1875
+ try {
1876
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1877
+ _iterator.return();
1878
+ }
1879
+ } finally{
1880
+ if (_didIteratorError) {
1881
+ throw _iteratorError;
1882
+ }
1883
+ }
1884
+ }
1885
+ return void 0;
1886
+ }
1887
+ function readStoredDeviceId() {
1888
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1889
+ try {
1890
+ for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1891
+ var key = _step.value;
1892
+ var value = readStoredString(key);
1893
+ if (value) {
1894
+ return value;
1895
+ }
1896
+ }
1897
+ } catch (err) {
1898
+ _didIteratorError = true;
1899
+ _iteratorError = err;
1900
+ } finally{
1901
+ try {
1902
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
1903
+ _iterator.return();
1904
+ }
1905
+ } finally{
1906
+ if (_didIteratorError) {
1907
+ throw _iteratorError;
1908
+ }
1909
+ }
1910
+ }
1911
+ return void 0;
1912
+ }
1913
+ function readStoredString(key) {
1914
+ if (typeof window === "undefined") {
1915
+ return void 0;
1916
+ }
1917
+ try {
1918
+ var _window_localStorage;
1919
+ var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
1920
+ return value || void 0;
1921
+ } catch (unused) {
1922
+ return void 0;
1923
+ }
1924
+ }
1925
+ function readStoredLimitAdTracking() {
1926
+ return normalizeBoolean(readStoredString("limitAdTracking") || readStoredString("limitedAdTracking") || readStoredString("is_lat"));
1927
+ }
1928
+ function normalizeBoolean(value) {
1929
+ if (typeof value === "boolean") {
1930
+ return value;
1931
+ }
1932
+ if (typeof value === "number") {
1933
+ return value === 1;
1934
+ }
1935
+ if (typeof value === "string") {
1936
+ var normalized = value.toLowerCase();
1937
+ if (normalized === "1" || normalized === "true" || normalized === "yes") {
1938
+ return true;
1939
+ }
1940
+ if (normalized === "0" || normalized === "false" || normalized === "no") {
1941
+ return false;
1942
+ }
1943
+ }
1944
+ return void 0;
1945
+ }
1946
+ // src/utils/tracking.ts
1947
+ var cachedBrowserId = null;
1948
+ function getClientInfo() {
1949
+ var _screen, _screen1, _screen2, _screen3, _screen_orientation, _screen4, _screen5, _window, _window1, _window_screen_orientation, _window_screen, _navigator_languages;
1950
+ var ua = navigator.userAgent;
1951
+ var platform = navigator.platform;
1952
+ var vendor = navigator.vendor || "";
1953
+ var maxTouchPoints = navigator.maxTouchPoints || 0;
1954
+ var memory = navigator.deviceMemory || null;
1955
+ var hardwareConcurrency = navigator.hardwareConcurrency || 1;
1956
+ var screenInfo = {
1957
+ width: (_screen = screen) === null || _screen === void 0 ? void 0 : _screen.width,
1958
+ height: (_screen1 = screen) === null || _screen1 === void 0 ? void 0 : _screen1.height,
1959
+ availWidth: (_screen2 = screen) === null || _screen2 === void 0 ? void 0 : _screen2.availWidth,
1960
+ availHeight: (_screen3 = screen) === null || _screen3 === void 0 ? void 0 : _screen3.availHeight,
1961
+ orientation: ((_screen4 = screen) === null || _screen4 === void 0 ? void 0 : (_screen_orientation = _screen4.orientation) === null || _screen_orientation === void 0 ? void 0 : _screen_orientation.type) || "",
1962
+ pixelDepth: (_screen5 = screen) === null || _screen5 === void 0 ? void 0 : _screen5.pixelDepth
1963
+ };
1964
+ var deviceType = "desktop";
1965
+ var brand = "Unknown";
1966
+ var os = "Unknown";
1967
+ var model = "";
1968
+ var isSmartTV = false;
1969
+ var isAndroid = false;
1970
+ var isWebView = false;
1971
+ var isWebApp = false;
1972
+ if (ua.includes("Web0S")) {
1973
+ brand = "LG";
1974
+ os = "webOS";
1975
+ isSmartTV = true;
1976
+ deviceType = "tv";
1977
+ var webosMatch = ua.match(/Web0S\/([^\s]+)/);
1978
+ model = webosMatch ? "webOS ".concat(webosMatch[1]) : "webOS TV";
1979
+ } else if (ua.includes("Tizen")) {
1980
+ brand = "Samsung";
1981
+ os = "Tizen";
1982
+ isSmartTV = true;
1983
+ deviceType = "tv";
1984
+ var tizenMatch = ua.match(/Tizen\/([^\s]+)/);
1985
+ var tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? "Smart TV" : "";
1986
+ model = tizenMatch ? "Tizen ".concat(tizenMatch[1], " ").concat(tvMatch).trim() : "Tizen TV";
1987
+ } else if (ua.includes("Philips")) {
1988
+ brand = "Philips";
1989
+ os = "Saphi";
1990
+ isSmartTV = true;
1991
+ deviceType = "tv";
1992
+ } else if (ua.includes("Sharp") || ua.includes("AQUOS")) {
1993
+ brand = "Sharp";
1994
+ os = "Android TV";
1995
+ isSmartTV = true;
1996
+ deviceType = "tv";
1997
+ } else if (ua.includes("Android") && (ua.includes("Sony") || vendor.includes("Sony"))) {
1998
+ brand = "Sony";
1999
+ os = "Android TV";
2000
+ isSmartTV = true;
2001
+ deviceType = "tv";
2002
+ } else if (ua.includes("Android") && (ua.includes("NetCast") || ua.includes("LG"))) {
2003
+ brand = "LG";
2004
+ os = "Android TV";
2005
+ isSmartTV = true;
2006
+ deviceType = "tv";
2007
+ } else if (ua.includes(" Roku") || ua.includes("Roku/")) {
2008
+ brand = "Roku";
2009
+ os = "Roku OS";
2010
+ isSmartTV = true;
2011
+ deviceType = "tv";
2012
+ } else if (ua.includes("AppleTV")) {
2013
+ brand = "Apple";
2014
+ os = "tvOS";
2015
+ isSmartTV = true;
2016
+ deviceType = "tv";
2017
+ }
2018
+ if (ua.includes("Android")) {
2019
+ isAndroid = true;
2020
+ os = "Android";
2021
+ deviceType = /Mobile/.test(ua) ? "mobile" : "tablet";
2022
+ if (ua.includes("Android") && (maxTouchPoints === 0 || ua.includes("Google TV") || ua.includes("XiaoMi"))) {
2023
+ deviceType = "tv";
2024
+ isSmartTV = true;
2025
+ brand = brand === "Unknown" ? "Android TV" : brand;
2026
+ }
2027
+ var androidModelMatch = ua.match(/\(([^)]*Android[^)]*)\)/);
2028
+ if (androidModelMatch && androidModelMatch[1]) {
2029
+ model = androidModelMatch[1];
2030
+ }
2031
+ }
2032
+ if (/iPad|iPhone|iPod/.test(ua)) {
2033
+ os = "iOS";
2034
+ deviceType = "mobile";
2035
+ brand = "Apple";
2036
+ if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {
2037
+ deviceType = "tablet";
2038
+ }
2039
+ }
2040
+ if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {
2041
+ if (ua.includes("Windows")) {
2042
+ os = "Windows";
2043
+ deviceType = "desktop";
2044
+ } else if (ua.includes("Mac") && !/iPhone/.test(ua)) {
2045
+ os = "macOS";
2046
+ deviceType = "desktop";
2047
+ if (maxTouchPoints > 1) deviceType = "tablet";
2048
+ } else if (ua.includes("Linux")) {
2049
+ os = "Linux";
2050
+ deviceType = "desktop";
2051
+ }
2052
+ }
2053
+ if (brand === "Unknown") {
2054
+ if (vendor.includes("Google") || ua.includes("Chrome")) brand = "Google";
2055
+ if (vendor.includes("Apple")) brand = "Apple";
2056
+ if (vendor.includes("Samsung") || ua.includes("SM-")) brand = "Samsung";
2057
+ }
2058
+ isWebView = /wv|WebView|Linux; U;/.test(ua);
2059
+ if (((_window = window) === null || _window === void 0 ? void 0 : _window.outerHeight) === 0 && ((_window1 = window) === null || _window1 === void 0 ? void 0 : _window1.outerWidth) === 0) {
2060
+ isWebView = true;
2061
+ }
2062
+ isWebApp = window.matchMedia("(display-mode: standalone)").matches || window.navigator.standalone === true || ((_window_screen = window.screen) === null || _window_screen === void 0 ? void 0 : (_window_screen_orientation = _window_screen.orientation) === null || _window_screen_orientation === void 0 ? void 0 : _window_screen_orientation.angle) !== void 0;
2063
+ return {
2064
+ brand: brand,
2065
+ os: os,
2066
+ model: model || ua.substring(0, 50) + "...",
2067
+ deviceType: deviceType,
2068
+ isSmartTV: isSmartTV,
2069
+ isAndroid: isAndroid,
2070
+ isWebView: isWebView,
2071
+ isWebApp: isWebApp,
2072
+ domain: window.location.hostname,
2073
+ origin: window.location.origin,
2074
+ path: window.location.pathname,
2075
+ userAgent: ua,
2076
+ vendor: vendor,
2077
+ platform: platform,
2078
+ screen: screenInfo,
2079
+ hardwareConcurrency: hardwareConcurrency,
2080
+ deviceMemory: memory,
2081
+ maxTouchPoints: maxTouchPoints,
2082
+ language: navigator.language,
2083
+ languages: ((_navigator_languages = navigator.languages) === null || _navigator_languages === void 0 ? void 0 : _navigator_languages.join(",")) || "",
2084
+ cookieEnabled: navigator.cookieEnabled,
2085
+ doNotTrack: navigator.doNotTrack || "",
2086
+ referrer: document.referrer,
2087
+ visibilityState: document.visibilityState
2088
+ };
1921
2089
  }
1922
- function sendAdImpressionTracking(_0, _1) {
1923
- return _async_to_generator(function(licenseKey, adImpressionInfo) {
1924
- var context, metricEvent, error;
1925
- var _arguments = arguments;
2090
+ function sha256Hex(input) {
2091
+ return _async_to_generator(function() {
2092
+ var _crypto_subtle, encodedData, utf8, buffer, i, hashBuffer, unused, hash, i1, char, fallbackHash, timestamp, random;
1926
2093
  return _ts_generator(this, function(_state) {
1927
2094
  switch(_state.label){
1928
2095
  case 0:
1929
- context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1930
- if (!canPublish(licenseKey)) return [
1931
- 2
1932
- ];
1933
- _state.label = 1;
1934
- case 1:
1935
- _state.trys.push([
1936
- 1,
1937
- 3,
1938
- ,
1939
- 4
1940
- ]);
1941
- return [
1942
- 4,
1943
- buildPlayerMetricEvent(context, {
1944
- captureAt: adImpressionInfo.timestamp
1945
- })
1946
- ];
1947
- case 2:
1948
- metricEvent = _state.sent();
1949
- publishTracking(licenseKey, "heartbeat", metricEvent);
1950
- publishTracking(licenseKey, "impressions", {
1951
- events: [
1952
- {
1953
- player_id: metricEvent.player_id,
1954
- ad_played_count: 1,
1955
- ad_url: adImpressionInfo.adUrl,
1956
- capture_at: adImpressionInfo.timestamp
1957
- }
1958
- ]
1959
- });
1960
- return [
1961
- 3,
1962
- 4
1963
- ];
1964
- case 3:
1965
- error = _state.sent();
1966
- console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
1967
- return [
2096
+ if (!(typeof crypto !== "undefined" && ((_crypto_subtle = crypto.subtle) === null || _crypto_subtle === void 0 ? void 0 : _crypto_subtle.digest))) return [
1968
2097
  3,
1969
- 4
1970
- ];
1971
- case 4:
1972
- return [
1973
- 2
1974
- ];
1975
- }
1976
- });
1977
- }).apply(this, arguments);
1978
- }
1979
- function sendHeartbeat(_0) {
1980
- return _async_to_generator(function(licenseKey) {
1981
- var context, flags, heartbeatData, error;
1982
- var _arguments = arguments;
1983
- return _ts_generator(this, function(_state) {
1984
- switch(_state.label){
1985
- case 0:
1986
- context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
1987
- if (!canPublish(licenseKey)) return [
1988
- 2
2098
+ 5
1989
2099
  ];
1990
2100
  _state.label = 1;
1991
2101
  case 1:
1992
2102
  _state.trys.push([
1993
2103
  1,
1994
- 3,
2104
+ 4,
1995
2105
  ,
1996
- 4
2106
+ 5
1997
2107
  ]);
1998
2108
  return [
1999
2109
  4,
2000
- buildPlayerMetricEvent(context, flags)
2110
+ crypto.subtle.digest("SHA-256", new Uint8Array([
2111
+ 1,
2112
+ 2,
2113
+ 3
2114
+ ]))
2001
2115
  ];
2002
2116
  case 2:
2003
- heartbeatData = _state.sent();
2004
- publishTracking(licenseKey, "heartbeat", heartbeatData);
2005
- return [
2006
- 3,
2007
- 4
2008
- ];
2009
- case 3:
2010
- error = _state.sent();
2011
- console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2012
- return [
2013
- 3,
2014
- 4
2015
- ];
2016
- case 4:
2017
- return [
2018
- 2
2019
- ];
2020
- }
2021
- });
2022
- }).apply(this, arguments);
2023
- }
2024
- // src/utils/polyfills.ts
2025
- function polyfillURLSearchParams() {
2026
- if (typeof URLSearchParams !== "undefined") {
2027
- return;
2028
- }
2029
- var URLSearchParamsPolyfill = /*#__PURE__*/ function() {
2030
- function URLSearchParamsPolyfill(init) {
2031
- var _this = this;
2032
- _class_call_check(this, URLSearchParamsPolyfill);
2033
- this.params = /* @__PURE__ */ new Map();
2034
- if (typeof init === "string") {
2035
- this.parseQueryString(init);
2036
- } else if (_instanceof(init, URLSearchParamsPolyfill)) {
2037
- init.forEach(function(value, key) {
2038
- _this.append(key, value);
2039
- });
2040
- }
2041
- }
2042
- _create_class(URLSearchParamsPolyfill, [
2043
- {
2044
- key: "parseQueryString",
2045
- value: function parseQueryString(query) {
2046
- var _this = this;
2047
- var cleanQuery = query.startsWith("?") ? query.slice(1) : query;
2048
- if (!cleanQuery) return;
2049
- cleanQuery.split("&").forEach(function(param) {
2050
- var _param_split = _sliced_to_array(param.split("="), 2), key = _param_split[0], value = _param_split[1];
2051
- if (key) {
2052
- var decodedKey = _this.safeDecodeURIComponent(key);
2053
- var decodedValue = value ? _this.safeDecodeURIComponent(value) : "";
2054
- _this.append(decodedKey, decodedValue);
2055
- }
2056
- });
2057
- }
2058
- },
2059
- {
2060
- key: "safeDecodeURIComponent",
2061
- value: function safeDecodeURIComponent(str) {
2062
- try {
2063
- return decodeURIComponent(str.replace(/\+/g, " "));
2064
- } catch (e) {
2065
- return str;
2066
- }
2067
- }
2068
- },
2069
- {
2070
- key: "append",
2071
- value: function append(name, value) {
2072
- var values = this.params.get(name) || [];
2073
- values.push(String(value));
2074
- this.params.set(name, values);
2075
- }
2076
- },
2077
- {
2078
- key: "delete",
2079
- value: function _delete(name) {
2080
- this.params.delete(name);
2081
- }
2082
- },
2083
- {
2084
- key: "get",
2085
- value: function get(name) {
2086
- var values = this.params.get(name);
2087
- return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;
2088
- }
2089
- },
2090
- {
2091
- key: "getAll",
2092
- value: function getAll(name) {
2093
- return this.params.get(name) || [];
2094
- }
2095
- },
2096
- {
2097
- key: "has",
2098
- value: function has(name) {
2099
- return this.params.has(name);
2100
- }
2101
- },
2102
- {
2103
- key: "set",
2104
- value: function set(name, value) {
2105
- this.params.set(name, [
2106
- String(value)
2107
- ]);
2108
- }
2109
- },
2110
- {
2111
- key: "forEach",
2112
- value: function forEach(callback) {
2113
- var _this = this;
2114
- this.params.forEach(function(values, key) {
2115
- values.forEach(function(value) {
2116
- callback(value, key, _this);
2117
- });
2118
- });
2119
- }
2120
- },
2121
- {
2122
- key: "toString",
2123
- value: function toString() {
2124
- var parts = [];
2125
- this.params.forEach(function(values, key) {
2126
- values.forEach(function(value) {
2127
- parts.push("".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value)));
2128
- });
2129
- });
2130
- return parts.join("&");
2131
- }
2132
- }
2133
- ]);
2134
- return URLSearchParamsPolyfill;
2135
- }();
2136
- window.URLSearchParams = URLSearchParamsPolyfill;
2137
- }
2138
- function polyfillTextEncoder() {
2139
- if (typeof TextEncoder !== "undefined") {
2140
- return;
2141
- }
2142
- var TextEncoderPolyfill = /*#__PURE__*/ function() {
2143
- function TextEncoderPolyfill() {
2144
- _class_call_check(this, TextEncoderPolyfill);
2145
- this.encoding = "utf-8";
2146
- }
2147
- _create_class(TextEncoderPolyfill, [
2148
- {
2149
- key: "encode",
2150
- value: function encode(str) {
2151
- var utf8 = [];
2152
- for(var i = 0; i < str.length; i++){
2153
- var charcode = str.charCodeAt(i);
2154
- if (charcode < 128) {
2155
- utf8.push(charcode);
2156
- } else if (charcode < 2048) {
2157
- utf8.push(192 | charcode >> 6, 128 | charcode & 63);
2158
- } else if (charcode < 55296 || charcode >= 57344) {
2159
- utf8.push(224 | charcode >> 12, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2160
- } else {
2161
- i++;
2162
- charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);
2163
- utf8.push(240 | charcode >> 18, 128 | charcode >> 12 & 63, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2117
+ _state.sent();
2118
+ if (typeof TextEncoder !== "undefined") {
2119
+ encodedData = new TextEncoder().encode(input);
2120
+ } else {
2121
+ utf8 = unescape(encodeURIComponent(input));
2122
+ buffer = new Uint8Array(utf8.length);
2123
+ for(i = 0; i < utf8.length; i++){
2124
+ buffer[i] = utf8.charCodeAt(i);
2164
2125
  }
2126
+ encodedData = buffer;
2165
2127
  }
2166
- return new Uint8Array(utf8);
2167
- }
2168
- }
2169
- ]);
2170
- return TextEncoderPolyfill;
2171
- }();
2172
- window.TextEncoder = TextEncoderPolyfill;
2173
- }
2174
- function polyfillPromiseFinally() {
2175
- if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
2176
- Promise.prototype.finally = function(callback) {
2177
- var constructor = this.constructor;
2178
- return this.then(function(value) {
2179
- return constructor.resolve(callback()).then(function() {
2180
- return value;
2181
- });
2182
- }, function(reason) {
2183
- return constructor.resolve(callback()).then(function() {
2184
- throw reason;
2185
- });
2186
- });
2187
- };
2188
- }
2189
- }
2190
- function polyfillObjectAssign() {
2191
- if (typeof Object.assign !== "function") {
2192
- Object.assign = function(target) {
2193
- for(var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
2194
- sources[_key - 1] = arguments[_key];
2195
- }
2196
- if (target == null) {
2197
- throw new TypeError("Cannot convert undefined or null to object");
2198
- }
2199
- var to = Object(target);
2200
- for(var i = 0; i < sources.length; i++){
2201
- var nextSource = sources[i];
2202
- if (nextSource != null) {
2203
- for(var nextKey in nextSource){
2204
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2205
- to[nextKey] = nextSource[nextKey];
2206
- }
2128
+ return [
2129
+ 4,
2130
+ crypto.subtle.digest("SHA-256", encodedData)
2131
+ ];
2132
+ case 3:
2133
+ hashBuffer = _state.sent();
2134
+ return [
2135
+ 2,
2136
+ Array.from(new Uint8Array(hashBuffer)).map(function(b) {
2137
+ return b.toString(16).padStart(2, "0");
2138
+ }).join("")
2139
+ ];
2140
+ case 4:
2141
+ unused = _state.sent();
2142
+ console.warn("[StormcloudVideoPlayer] crypto.subtle not supported, using fallback hash");
2143
+ return [
2144
+ 3,
2145
+ 5
2146
+ ];
2147
+ case 5:
2148
+ hash = 0;
2149
+ for(i1 = 0; i1 < input.length; i1++){
2150
+ char = input.charCodeAt(i1);
2151
+ hash = (hash << 5) - hash + char;
2152
+ hash = hash & hash;
2207
2153
  }
2208
- }
2209
- }
2210
- return to;
2211
- };
2212
- }
2213
- }
2214
- function polyfillArrayFrom() {
2215
- if (!Array.from) {
2216
- Array.from = function(arrayLike, mapFn, thisArg) {
2217
- var items = Object(arrayLike);
2218
- if (arrayLike == null) {
2219
- throw new TypeError("Array.from requires an array-like object");
2220
- }
2221
- var len = items.length >>> 0;
2222
- var result = new Array(len);
2223
- for(var i = 0; i < len; i++){
2224
- if (mapFn) {
2225
- result[i] = mapFn.call(thisArg, items[i], i);
2226
- } else {
2227
- result[i] = items[i];
2228
- }
2154
+ fallbackHash = Math.abs(hash).toString(16).padStart(8, "0");
2155
+ timestamp = Date.now().toString(16).padStart(12, "0");
2156
+ random = Math.random().toString(16).substring(2, 14).padStart(12, "0");
2157
+ return [
2158
+ 2,
2159
+ (fallbackHash + timestamp + random).padEnd(64, "0")
2160
+ ];
2229
2161
  }
2230
- return result;
2231
- };
2232
- }
2162
+ });
2163
+ })();
2233
2164
  }
2234
- function polyfillStringStartsWith() {
2235
- if (!String.prototype.startsWith) {
2236
- String.prototype.startsWith = function(search, pos) {
2237
- pos = !pos || pos < 0 ? 0 : +pos;
2238
- return this.substring(pos, pos + search.length) === search;
2239
- };
2165
+ function resolvePlayerIdentitySeed(clientInfo) {
2166
+ var nativeDeviceId = resolveNativeDeviceId();
2167
+ if (nativeDeviceId) {
2168
+ return "device:".concat(nativeDeviceId);
2240
2169
  }
2241
- }
2242
- function polyfillStringEndsWith() {
2243
- if (!String.prototype.endsWith) {
2244
- String.prototype.endsWith = function(search, length) {
2245
- if (length === void 0 || length > this.length) {
2246
- length = this.length;
2247
- }
2248
- return this.substring(length - search.length, length) === search;
2249
- };
2170
+ var persistedId = getOrCreateStoredUuid(PLAYER_ID_STORAGE_KEY);
2171
+ if (persistedId) {
2172
+ return "persisted:".concat(persistedId);
2250
2173
  }
2174
+ return "fingerprint:".concat(JSON.stringify(clientInfo));
2251
2175
  }
2252
- function polyfillStringIncludes() {
2253
- if (!String.prototype.includes) {
2254
- String.prototype.includes = function(search, start) {
2255
- if (typeof start !== "number") {
2256
- start = 0;
2257
- }
2258
- if (start + search.length > this.length) {
2259
- return false;
2176
+ function getBrowserID(clientInfo) {
2177
+ return _async_to_generator(function() {
2178
+ return _ts_generator(this, function(_state) {
2179
+ switch(_state.label){
2180
+ case 0:
2181
+ if (cachedBrowserId) {
2182
+ return [
2183
+ 2,
2184
+ cachedBrowserId
2185
+ ];
2186
+ }
2187
+ return [
2188
+ 4,
2189
+ sha256Hex(resolvePlayerIdentitySeed(clientInfo))
2190
+ ];
2191
+ case 1:
2192
+ cachedBrowserId = _state.sent();
2193
+ return [
2194
+ 2,
2195
+ cachedBrowserId
2196
+ ];
2260
2197
  }
2261
- return this.indexOf(search, start) !== -1;
2262
- };
2263
- }
2198
+ });
2199
+ })();
2264
2200
  }
2265
- function initializePolyfills() {
2266
- polyfillObjectAssign();
2267
- polyfillArrayFrom();
2268
- polyfillStringStartsWith();
2269
- polyfillStringEndsWith();
2270
- polyfillStringIncludes();
2271
- polyfillURLSearchParams();
2272
- polyfillTextEncoder();
2273
- polyfillPromiseFinally();
2201
+ function canPublish(licenseKey) {
2202
+ return Boolean(isMQTTEnabled() && licenseKey);
2274
2203
  }
2275
- // src/utils/vastEnvironmentSignals.ts
2276
- var AIRY_ANDROID_APP_ID = "com.freeairytv.android";
2277
- var AIRY_WEBOS_APP_ID = "com.freeairytv.webos";
2278
- var AIRY_TIZEN_APP_ID = "com.freeairytv.samsung";
2279
- var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
2280
- var AIRY_APP_NAME = "AiryTV Movies & TV";
2281
- var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
2282
- var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
2283
- var LG_TEST_APP_ID = "com.hulu.plus";
2284
- var LG_TEST_APP_NAME = "Hulu";
2285
- var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
2286
- var _lgTestDeviceId;
2287
- function getLgTestDeviceId() {
2288
- if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
2289
- return _lgTestDeviceId;
2204
+ function buildPlayerMetricEvent() {
2205
+ return _async_to_generator(function() {
2206
+ var context, flags, _flags_captureAt, _flags_adLoaded, _flags_adDetect, clientInfo, playerId, captureAt;
2207
+ var _arguments = arguments;
2208
+ return _ts_generator(this, function(_state) {
2209
+ switch(_state.label){
2210
+ case 0:
2211
+ context = _arguments.length > 0 && _arguments[0] !== void 0 ? _arguments[0] : {}, flags = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2212
+ clientInfo = getClientInfo();
2213
+ return [
2214
+ 4,
2215
+ getBrowserID(clientInfo)
2216
+ ];
2217
+ case 1:
2218
+ playerId = _state.sent();
2219
+ captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
2220
+ return [
2221
+ 2,
2222
+ _object_spread({
2223
+ player_id: playerId,
2224
+ device_type: clientInfo.deviceType,
2225
+ os: clientInfo.os.toLowerCase(),
2226
+ ad_loaded: (_flags_adLoaded = flags.adLoaded) !== null && _flags_adLoaded !== void 0 ? _flags_adLoaded : false,
2227
+ ad_detect: (_flags_adDetect = flags.adDetect) !== null && _flags_adDetect !== void 0 ? _flags_adDetect : false,
2228
+ capture_at: captureAt
2229
+ }, context.inputStreamType ? {
2230
+ input_stream_type: context.inputStreamType
2231
+ } : {})
2232
+ ];
2233
+ }
2234
+ });
2235
+ }).apply(this, arguments);
2290
2236
  }
2291
- function isLgWebOS() {
2292
- if (typeof navigator === "undefined") return false;
2293
- return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
2237
+ function publishTracking(licenseKey, channel, body) {
2238
+ ensureMQTTClient();
2239
+ publishMQTT(buildPlayerTopic(licenseKey, channel), body);
2294
2240
  }
2295
- function getDefaultAppId() {
2296
- if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
2297
- var ua = navigator.userAgent;
2298
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return AIRY_WEBOS_APP_ID;
2299
- if (/Tizen|Samsung/i.test(ua)) return AIRY_TIZEN_APP_ID;
2300
- if (/Roku/i.test(ua)) return AIRY_ROKU_APP_ID;
2301
- return AIRY_ANDROID_APP_ID;
2241
+ function sendInitialTracking(_0) {
2242
+ return _async_to_generator(function(licenseKey) {
2243
+ var context, metricEvent, error;
2244
+ var _arguments = arguments;
2245
+ return _ts_generator(this, function(_state) {
2246
+ switch(_state.label){
2247
+ case 0:
2248
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
2249
+ if (!canPublish(licenseKey)) return [
2250
+ 2
2251
+ ];
2252
+ _state.label = 1;
2253
+ case 1:
2254
+ _state.trys.push([
2255
+ 1,
2256
+ 3,
2257
+ ,
2258
+ 4
2259
+ ]);
2260
+ return [
2261
+ 4,
2262
+ buildPlayerMetricEvent(context, {
2263
+ adLoaded: false,
2264
+ adDetect: false
2265
+ })
2266
+ ];
2267
+ case 2:
2268
+ metricEvent = _state.sent();
2269
+ publishTracking(licenseKey, "metrics", {
2270
+ events: [
2271
+ metricEvent
2272
+ ]
2273
+ });
2274
+ return [
2275
+ 3,
2276
+ 4
2277
+ ];
2278
+ case 3:
2279
+ error = _state.sent();
2280
+ console.error("[StormcloudVideoPlayer] Error sending initial tracking data:", error);
2281
+ return [
2282
+ 3,
2283
+ 4
2284
+ ];
2285
+ case 4:
2286
+ return [
2287
+ 2
2288
+ ];
2289
+ }
2290
+ });
2291
+ }).apply(this, arguments);
2302
2292
  }
2303
- var DEVICE_ID_STORAGE_KEYS = [
2304
- "rdid",
2305
- "ifa",
2306
- "advertisingId",
2307
- "advertising_id",
2308
- "deviceAdvertisingId",
2309
- "aaid",
2310
- "adid",
2311
- "rida",
2312
- "tifa",
2313
- "lgudid"
2314
- ];
2315
- var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
2316
- "aaid",
2317
- "adid"
2318
- ]);
2319
- function resolveVastEnvironmentSignals(isCtv) {
2320
- var _ref;
2321
- var bridgeSignals = readNativeBridgeSignals();
2322
- var platformDevice = readPlatformNativeDeviceId();
2323
- var lg = isCtv && isLgWebOS();
2324
- var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
2325
- var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
2326
- var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
2327
- var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
2328
- if (isCtv) {
2329
- return _object_spread_props(_object_spread({
2330
- isCtv: true,
2331
- contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
2332
- appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
2333
- appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
2334
- sessionId: getOrCreateCtvSessionId()
2335
- }, deviceId ? {
2336
- deviceId: deviceId
2337
- } : {}, deviceIdType ? {
2338
- deviceIdType: deviceIdType
2339
- } : {}, limitAdTracking != null ? {
2340
- limitAdTracking: limitAdTracking
2341
- } : {}), {
2342
- deviceTypeHint: 5
2293
+ function sendAdDetectTracking(_0, _1) {
2294
+ return _async_to_generator(function(licenseKey, adDetectInfo) {
2295
+ var context, error;
2296
+ var _arguments = arguments;
2297
+ return _ts_generator(this, function(_state) {
2298
+ switch(_state.label){
2299
+ case 0:
2300
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2301
+ _state.label = 1;
2302
+ case 1:
2303
+ _state.trys.push([
2304
+ 1,
2305
+ 3,
2306
+ ,
2307
+ 4
2308
+ ]);
2309
+ return [
2310
+ 4,
2311
+ sendHeartbeat(licenseKey, context, {
2312
+ adDetect: true,
2313
+ captureAt: adDetectInfo.timestamp
2314
+ })
2315
+ ];
2316
+ case 2:
2317
+ _state.sent();
2318
+ return [
2319
+ 3,
2320
+ 4
2321
+ ];
2322
+ case 3:
2323
+ error = _state.sent();
2324
+ console.error("[StormcloudVideoPlayer] Error sending ad detect tracking:", error);
2325
+ return [
2326
+ 3,
2327
+ 4
2328
+ ];
2329
+ case 4:
2330
+ return [
2331
+ 2
2332
+ ];
2333
+ }
2343
2334
  });
2344
- }
2345
- return _object_spread({
2346
- isCtv: false
2347
- }, deviceId ? {
2348
- deviceId: deviceId
2349
- } : {}, deviceIdType ? {
2350
- deviceIdType: deviceIdType
2351
- } : {}, limitAdTracking != null ? {
2352
- limitAdTracking: limitAdTracking
2353
- } : {});
2335
+ }).apply(this, arguments);
2354
2336
  }
2355
- function inferDeviceIdType() {
2356
- if (typeof navigator === "undefined") {
2357
- return void 0;
2358
- }
2359
- var ua = navigator.userAgent;
2360
- if (/Roku/i.test(ua)) return "rida";
2361
- if (/Tizen|Samsung/i.test(ua)) return "tifa";
2362
- if (/AppleTV|Apple TV/i.test(ua)) return "tvOS";
2363
- if (/AFT|Fire TV|Amazon/i.test(ua)) return "afai";
2364
- if (/Web0S|webOS|LG Browser|LGSTB|LGE/i.test(ua)) return "lgudid";
2365
- if (/Android|Google TV/i.test(ua)) return "aaid";
2366
- if (/iPhone|iPad|iPod/i.test(ua)) return "idfa";
2367
- return void 0;
2337
+ function sendAdLoadedTracking(_0, _1) {
2338
+ return _async_to_generator(function(licenseKey, adLoadedInfo) {
2339
+ var context, error;
2340
+ var _arguments = arguments;
2341
+ return _ts_generator(this, function(_state) {
2342
+ switch(_state.label){
2343
+ case 0:
2344
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2345
+ _state.label = 1;
2346
+ case 1:
2347
+ _state.trys.push([
2348
+ 1,
2349
+ 3,
2350
+ ,
2351
+ 4
2352
+ ]);
2353
+ return [
2354
+ 4,
2355
+ sendHeartbeat(licenseKey, context, {
2356
+ adLoaded: true,
2357
+ captureAt: adLoadedInfo.timestamp
2358
+ })
2359
+ ];
2360
+ case 2:
2361
+ _state.sent();
2362
+ return [
2363
+ 3,
2364
+ 4
2365
+ ];
2366
+ case 3:
2367
+ error = _state.sent();
2368
+ console.error("[StormcloudVideoPlayer] Error sending ad loaded tracking:", error);
2369
+ return [
2370
+ 3,
2371
+ 4
2372
+ ];
2373
+ case 4:
2374
+ return [
2375
+ 2
2376
+ ];
2377
+ }
2378
+ });
2379
+ }).apply(this, arguments);
2368
2380
  }
2369
- function isEquivalentDeviceIdType(tagType, runtimeType) {
2370
- if (!tagType || !runtimeType) return false;
2371
- var tag = tagType.toLowerCase();
2372
- var runtime = runtimeType.toLowerCase();
2373
- if (tag === runtime) return true;
2374
- return ANDROID_ID_TYPES.has(tag) && ANDROID_ID_TYPES.has(runtime);
2381
+ function sendAdImpressionTracking(_0, _1) {
2382
+ return _async_to_generator(function(licenseKey, adImpressionInfo) {
2383
+ var context, metricEvent, error;
2384
+ var _arguments = arguments;
2385
+ return _ts_generator(this, function(_state) {
2386
+ switch(_state.label){
2387
+ case 0:
2388
+ context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2389
+ if (!canPublish(licenseKey)) return [
2390
+ 2
2391
+ ];
2392
+ _state.label = 1;
2393
+ case 1:
2394
+ _state.trys.push([
2395
+ 1,
2396
+ 3,
2397
+ ,
2398
+ 4
2399
+ ]);
2400
+ return [
2401
+ 4,
2402
+ buildPlayerMetricEvent(context, {
2403
+ captureAt: adImpressionInfo.timestamp
2404
+ })
2405
+ ];
2406
+ case 2:
2407
+ metricEvent = _state.sent();
2408
+ publishTracking(licenseKey, "heartbeat", metricEvent);
2409
+ publishTracking(licenseKey, "impressions", {
2410
+ events: [
2411
+ {
2412
+ player_id: metricEvent.player_id,
2413
+ ad_played_count: 1,
2414
+ ad_url: adImpressionInfo.adUrl,
2415
+ capture_at: adImpressionInfo.timestamp
2416
+ }
2417
+ ]
2418
+ });
2419
+ return [
2420
+ 3,
2421
+ 4
2422
+ ];
2423
+ case 3:
2424
+ error = _state.sent();
2425
+ console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
2426
+ return [
2427
+ 3,
2428
+ 4
2429
+ ];
2430
+ case 4:
2431
+ return [
2432
+ 2
2433
+ ];
2434
+ }
2435
+ });
2436
+ }).apply(this, arguments);
2375
2437
  }
2376
- function getOrCreateCtvSessionId() {
2377
- var existing = readStoredString(CTV_SESSION_STORAGE_KEY);
2378
- if (existing) {
2379
- return existing;
2380
- }
2381
- var sessionId = createUuid();
2382
- try {
2383
- var _window_localStorage;
2384
- (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.setItem(CTV_SESSION_STORAGE_KEY, sessionId);
2385
- } catch (unused) {}
2386
- return sessionId;
2438
+ function sendHeartbeat(_0) {
2439
+ return _async_to_generator(function(licenseKey) {
2440
+ var context, flags, heartbeatData, error;
2441
+ var _arguments = arguments;
2442
+ return _ts_generator(this, function(_state) {
2443
+ switch(_state.label){
2444
+ case 0:
2445
+ context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
2446
+ if (!canPublish(licenseKey)) return [
2447
+ 2
2448
+ ];
2449
+ _state.label = 1;
2450
+ case 1:
2451
+ _state.trys.push([
2452
+ 1,
2453
+ 3,
2454
+ ,
2455
+ 4
2456
+ ]);
2457
+ return [
2458
+ 4,
2459
+ buildPlayerMetricEvent(context, flags)
2460
+ ];
2461
+ case 2:
2462
+ heartbeatData = _state.sent();
2463
+ publishTracking(licenseKey, "heartbeat", heartbeatData);
2464
+ return [
2465
+ 3,
2466
+ 4
2467
+ ];
2468
+ case 3:
2469
+ error = _state.sent();
2470
+ console.error("[StormcloudVideoPlayer] Error sending heartbeat:", error);
2471
+ return [
2472
+ 3,
2473
+ 4
2474
+ ];
2475
+ case 4:
2476
+ return [
2477
+ 2
2478
+ ];
2479
+ }
2480
+ });
2481
+ }).apply(this, arguments);
2387
2482
  }
2388
- function createUuid() {
2389
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
2390
- return crypto.randomUUID();
2483
+ // src/utils/polyfills.ts
2484
+ function polyfillURLSearchParams() {
2485
+ if (typeof URLSearchParams !== "undefined") {
2486
+ return;
2391
2487
  }
2392
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(char) {
2393
- var value = Math.floor(Math.random() * 16);
2394
- var nibble = char === "x" ? value : value & 3 | 8;
2395
- return nibble.toString(16);
2396
- });
2397
- }
2398
- function readPlatformNativeDeviceId() {
2399
- if (typeof window === "undefined") return {};
2400
- try {
2401
- var _window_webapis;
2402
- var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
2403
- if (adinfo) {
2404
- var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
2405
- if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
2406
- var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
2407
- return _object_spread({
2408
- deviceId: tifa,
2409
- deviceIdType: "tifa"
2410
- }, typeof lat === "boolean" ? {
2411
- limitAdTracking: lat
2412
- } : {});
2488
+ var URLSearchParamsPolyfill = /*#__PURE__*/ function() {
2489
+ function URLSearchParamsPolyfill(init) {
2490
+ var _this = this;
2491
+ _class_call_check(this, URLSearchParamsPolyfill);
2492
+ this.params = /* @__PURE__ */ new Map();
2493
+ if (typeof init === "string") {
2494
+ this.parseQueryString(init);
2495
+ } else if (_instanceof(init, URLSearchParamsPolyfill)) {
2496
+ init.forEach(function(value, key) {
2497
+ _this.append(key, value);
2498
+ });
2413
2499
  }
2414
2500
  }
2415
- } catch (unused) {}
2416
- try {
2417
- var webOSDev = window.webOSDev;
2418
- if (webOSDev) {
2419
- var _webOSDev_lgudid;
2420
- var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
2421
- if (typeof lgudid === "string" && lgudid) {
2422
- if (isZeroedAdId(lgudid)) {
2423
- return {
2424
- deviceIdType: "lgudid",
2425
- limitAdTracking: true
2426
- };
2501
+ _create_class(URLSearchParamsPolyfill, [
2502
+ {
2503
+ key: "parseQueryString",
2504
+ value: function parseQueryString(query) {
2505
+ var _this = this;
2506
+ var cleanQuery = query.startsWith("?") ? query.slice(1) : query;
2507
+ if (!cleanQuery) return;
2508
+ cleanQuery.split("&").forEach(function(param) {
2509
+ var _param_split = _sliced_to_array(param.split("="), 2), key = _param_split[0], value = _param_split[1];
2510
+ if (key) {
2511
+ var decodedKey = _this.safeDecodeURIComponent(key);
2512
+ var decodedValue = value ? _this.safeDecodeURIComponent(value) : "";
2513
+ _this.append(decodedKey, decodedValue);
2514
+ }
2515
+ });
2427
2516
  }
2428
- if (!isMacroPlaceholder(lgudid)) {
2429
- return {
2430
- deviceId: lgudid,
2431
- deviceIdType: "lgudid",
2432
- limitAdTracking: false
2433
- };
2517
+ },
2518
+ {
2519
+ key: "safeDecodeURIComponent",
2520
+ value: function safeDecodeURIComponent(str) {
2521
+ try {
2522
+ return decodeURIComponent(str.replace(/\+/g, " "));
2523
+ } catch (e) {
2524
+ return str;
2525
+ }
2526
+ }
2527
+ },
2528
+ {
2529
+ key: "append",
2530
+ value: function append(name, value) {
2531
+ var values = this.params.get(name) || [];
2532
+ values.push(String(value));
2533
+ this.params.set(name, values);
2534
+ }
2535
+ },
2536
+ {
2537
+ key: "delete",
2538
+ value: function _delete(name) {
2539
+ this.params.delete(name);
2540
+ }
2541
+ },
2542
+ {
2543
+ key: "get",
2544
+ value: function get(name) {
2545
+ var values = this.params.get(name);
2546
+ return values && values.length > 0 && values[0] !== void 0 ? values[0] : null;
2547
+ }
2548
+ },
2549
+ {
2550
+ key: "getAll",
2551
+ value: function getAll(name) {
2552
+ return this.params.get(name) || [];
2553
+ }
2554
+ },
2555
+ {
2556
+ key: "has",
2557
+ value: function has(name) {
2558
+ return this.params.has(name);
2559
+ }
2560
+ },
2561
+ {
2562
+ key: "set",
2563
+ value: function set(name, value) {
2564
+ this.params.set(name, [
2565
+ String(value)
2566
+ ]);
2567
+ }
2568
+ },
2569
+ {
2570
+ key: "forEach",
2571
+ value: function forEach(callback) {
2572
+ var _this = this;
2573
+ this.params.forEach(function(values, key) {
2574
+ values.forEach(function(value) {
2575
+ callback(value, key, _this);
2576
+ });
2577
+ });
2578
+ }
2579
+ },
2580
+ {
2581
+ key: "toString",
2582
+ value: function toString() {
2583
+ var parts = [];
2584
+ this.params.forEach(function(values, key) {
2585
+ values.forEach(function(value) {
2586
+ parts.push("".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(value)));
2587
+ });
2588
+ });
2589
+ return parts.join("&");
2434
2590
  }
2435
2591
  }
2436
- }
2437
- } catch (unused) {}
2438
- try {
2439
- var roku = window.Roku;
2440
- if (roku) {
2441
- var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
2442
- if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
2443
- return {
2444
- deviceId: rida,
2445
- deviceIdType: "rida",
2446
- limitAdTracking: false
2447
- };
2448
- }
2449
- }
2450
- } catch (unused) {}
2451
- return {};
2452
- }
2453
- var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
2454
- "38400000-8cf0-11bd-b23e-10b96e40000d",
2455
- "00000000-0000-0000-0000-000000000000"
2456
- ]);
2457
- function isMacroPlaceholder(value) {
2458
- var t = value.trim();
2459
- return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
2460
- }
2461
- function isZeroedAdId(value) {
2462
- return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
2463
- }
2464
- function readNativeBridgeSignals() {
2465
- if (typeof window === "undefined") {
2466
- return {};
2467
- }
2468
- var candidates = [
2469
- window.__STORMCLOUD_CTV_AD_INFO__,
2470
- window.__STORMCLOUD_CTV__,
2471
- window.stormcloudCtv,
2472
- window.AiryTV,
2473
- window.Android,
2474
- window.webOS,
2475
- window.tizen,
2476
- window.amazon
2477
- ].filter(Boolean);
2478
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2479
- try {
2480
- for(var _iterator = candidates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2481
- var source = _step.value;
2482
- var contentUrl = readBridgeValue(source, [
2483
- "contentUrl",
2484
- "url",
2485
- "videoUrl",
2486
- "canonicalUrl"
2487
- ]) || void 0;
2488
- var appId = readBridgeValue(source, [
2489
- "appId",
2490
- "msid",
2491
- "applicationId",
2492
- "packageName"
2493
- ]) || void 0;
2494
- var appName = readBridgeValue(source, [
2495
- "appName",
2496
- "an",
2497
- "applicationName"
2498
- ]) || void 0;
2499
- var deviceId = readBridgeValue(source, [
2500
- "rdid",
2501
- "ifa",
2502
- "advertisingId",
2503
- "adId",
2504
- "deviceId",
2505
- "lgudid",
2506
- "LGUDID",
2507
- "tifa",
2508
- "rida",
2509
- "afai",
2510
- "aaid"
2511
- ]) || void 0;
2512
- if (!contentUrl && !deviceId && !appId && !appName) continue;
2513
- var deviceIdType = readBridgeValue(source, [
2514
- "idtype",
2515
- "deviceIdType",
2516
- "advertisingIdType",
2517
- "idType"
2518
- ]) || inferDeviceIdType();
2519
- var limitAdTracking = readBridgeBoolean(source, [
2520
- "is_lat",
2521
- "limitAdTracking",
2522
- "limitedAdTracking",
2523
- "lat"
2524
- ]);
2525
- return _object_spread({}, contentUrl ? {
2526
- contentUrl: contentUrl
2527
- } : {}, appId ? {
2528
- appId: appId
2529
- } : {}, appName ? {
2530
- appName: appName
2531
- } : {}, deviceId ? {
2532
- deviceId: deviceId
2533
- } : {}, deviceId && deviceIdType ? {
2534
- deviceIdType: deviceIdType
2535
- } : {}, deviceId && limitAdTracking != null ? {
2536
- limitAdTracking: limitAdTracking
2537
- } : {});
2538
- }
2539
- } catch (err) {
2540
- _didIteratorError = true;
2541
- _iteratorError = err;
2542
- } finally{
2543
- try {
2544
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2545
- _iterator.return();
2546
- }
2547
- } finally{
2548
- if (_didIteratorError) {
2549
- throw _iteratorError;
2550
- }
2551
- }
2552
- }
2553
- return {};
2592
+ ]);
2593
+ return URLSearchParamsPolyfill;
2594
+ }();
2595
+ window.URLSearchParams = URLSearchParamsPolyfill;
2554
2596
  }
2555
- function readBridgeValue(source, keys) {
2556
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2557
- try {
2558
- for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2559
- var key = _step.value;
2560
- var value = source === null || source === void 0 ? void 0 : source[key];
2561
- if (typeof value === "string" && value) {
2562
- return value;
2563
- }
2564
- if (typeof value === "function") {
2565
- try {
2566
- var result = value.call(source);
2567
- if (typeof result === "string" && result) {
2568
- return result;
2569
- }
2570
- } catch (unused) {}
2571
- }
2597
+ function polyfillTextEncoder() {
2598
+ if (typeof TextEncoder !== "undefined") {
2599
+ return;
2600
+ }
2601
+ var TextEncoderPolyfill = /*#__PURE__*/ function() {
2602
+ function TextEncoderPolyfill() {
2603
+ _class_call_check(this, TextEncoderPolyfill);
2604
+ this.encoding = "utf-8";
2572
2605
  }
2573
- } catch (err) {
2574
- _didIteratorError = true;
2575
- _iteratorError = err;
2576
- } finally{
2577
- try {
2578
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2579
- _iterator.return();
2580
- }
2581
- } finally{
2582
- if (_didIteratorError) {
2583
- throw _iteratorError;
2606
+ _create_class(TextEncoderPolyfill, [
2607
+ {
2608
+ key: "encode",
2609
+ value: function encode(str) {
2610
+ var utf8 = [];
2611
+ for(var i = 0; i < str.length; i++){
2612
+ var charcode = str.charCodeAt(i);
2613
+ if (charcode < 128) {
2614
+ utf8.push(charcode);
2615
+ } else if (charcode < 2048) {
2616
+ utf8.push(192 | charcode >> 6, 128 | charcode & 63);
2617
+ } else if (charcode < 55296 || charcode >= 57344) {
2618
+ utf8.push(224 | charcode >> 12, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2619
+ } else {
2620
+ i++;
2621
+ charcode = 65536 + ((charcode & 1023) << 10 | str.charCodeAt(i) & 1023);
2622
+ utf8.push(240 | charcode >> 18, 128 | charcode >> 12 & 63, 128 | charcode >> 6 & 63, 128 | charcode & 63);
2623
+ }
2624
+ }
2625
+ return new Uint8Array(utf8);
2626
+ }
2584
2627
  }
2585
- }
2628
+ ]);
2629
+ return TextEncoderPolyfill;
2630
+ }();
2631
+ window.TextEncoder = TextEncoderPolyfill;
2632
+ }
2633
+ function polyfillPromiseFinally() {
2634
+ if (typeof Promise !== "undefined" && !Promise.prototype.finally) {
2635
+ Promise.prototype.finally = function(callback) {
2636
+ var constructor = this.constructor;
2637
+ return this.then(function(value) {
2638
+ return constructor.resolve(callback()).then(function() {
2639
+ return value;
2640
+ });
2641
+ }, function(reason) {
2642
+ return constructor.resolve(callback()).then(function() {
2643
+ throw reason;
2644
+ });
2645
+ });
2646
+ };
2586
2647
  }
2587
- return void 0;
2588
2648
  }
2589
- function readBridgeBoolean(source, keys) {
2590
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2591
- try {
2592
- for(var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2593
- var key = _step.value;
2594
- var value = source === null || source === void 0 ? void 0 : source[key];
2595
- var normalized = normalizeBoolean(value);
2596
- if (normalized != null) {
2597
- return normalized;
2598
- }
2599
- if (typeof value === "function") {
2600
- try {
2601
- var result = normalizeBoolean(value.call(source));
2602
- if (result != null) {
2603
- return result;
2604
- }
2605
- } catch (unused) {}
2649
+ function polyfillObjectAssign() {
2650
+ if (typeof Object.assign !== "function") {
2651
+ Object.assign = function(target) {
2652
+ for(var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
2653
+ sources[_key - 1] = arguments[_key];
2606
2654
  }
2607
- }
2608
- } catch (err) {
2609
- _didIteratorError = true;
2610
- _iteratorError = err;
2611
- } finally{
2612
- try {
2613
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2614
- _iterator.return();
2655
+ if (target == null) {
2656
+ throw new TypeError("Cannot convert undefined or null to object");
2615
2657
  }
2616
- } finally{
2617
- if (_didIteratorError) {
2618
- throw _iteratorError;
2658
+ var to = Object(target);
2659
+ for(var i = 0; i < sources.length; i++){
2660
+ var nextSource = sources[i];
2661
+ if (nextSource != null) {
2662
+ for(var nextKey in nextSource){
2663
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
2664
+ to[nextKey] = nextSource[nextKey];
2665
+ }
2666
+ }
2667
+ }
2619
2668
  }
2620
- }
2669
+ return to;
2670
+ };
2621
2671
  }
2622
- return void 0;
2623
2672
  }
2624
- function readStoredDeviceId() {
2625
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
2626
- try {
2627
- for(var _iterator = DEVICE_ID_STORAGE_KEYS[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
2628
- var key = _step.value;
2629
- var value = readStoredString(key);
2630
- if (value) {
2631
- return value;
2632
- }
2633
- }
2634
- } catch (err) {
2635
- _didIteratorError = true;
2636
- _iteratorError = err;
2637
- } finally{
2638
- try {
2639
- if (!_iteratorNormalCompletion && _iterator.return != null) {
2640
- _iterator.return();
2673
+ function polyfillArrayFrom() {
2674
+ if (!Array.from) {
2675
+ Array.from = function(arrayLike, mapFn, thisArg) {
2676
+ var items = Object(arrayLike);
2677
+ if (arrayLike == null) {
2678
+ throw new TypeError("Array.from requires an array-like object");
2641
2679
  }
2642
- } finally{
2643
- if (_didIteratorError) {
2644
- throw _iteratorError;
2680
+ var len = items.length >>> 0;
2681
+ var result = new Array(len);
2682
+ for(var i = 0; i < len; i++){
2683
+ if (mapFn) {
2684
+ result[i] = mapFn.call(thisArg, items[i], i);
2685
+ } else {
2686
+ result[i] = items[i];
2687
+ }
2645
2688
  }
2646
- }
2689
+ return result;
2690
+ };
2647
2691
  }
2648
- return void 0;
2649
2692
  }
2650
- function readStoredString(key) {
2651
- if (typeof window === "undefined") {
2652
- return void 0;
2653
- }
2654
- try {
2655
- var _window_localStorage;
2656
- var value = (_window_localStorage = window.localStorage) === null || _window_localStorage === void 0 ? void 0 : _window_localStorage.getItem(key);
2657
- return value || void 0;
2658
- } catch (unused) {
2659
- return void 0;
2693
+ function polyfillStringStartsWith() {
2694
+ if (!String.prototype.startsWith) {
2695
+ String.prototype.startsWith = function(search, pos) {
2696
+ pos = !pos || pos < 0 ? 0 : +pos;
2697
+ return this.substring(pos, pos + search.length) === search;
2698
+ };
2660
2699
  }
2661
2700
  }
2662
- function readStoredLimitAdTracking() {
2663
- return normalizeBoolean(readStoredString("limitAdTracking") || readStoredString("limitedAdTracking") || readStoredString("is_lat"));
2664
- }
2665
- function normalizeBoolean(value) {
2666
- if (typeof value === "boolean") {
2667
- return value;
2668
- }
2669
- if (typeof value === "number") {
2670
- return value === 1;
2701
+ function polyfillStringEndsWith() {
2702
+ if (!String.prototype.endsWith) {
2703
+ String.prototype.endsWith = function(search, length) {
2704
+ if (length === void 0 || length > this.length) {
2705
+ length = this.length;
2706
+ }
2707
+ return this.substring(length - search.length, length) === search;
2708
+ };
2671
2709
  }
2672
- if (typeof value === "string") {
2673
- var normalized = value.toLowerCase();
2674
- if (normalized === "1" || normalized === "true" || normalized === "yes") {
2675
- return true;
2676
- }
2677
- if (normalized === "0" || normalized === "false" || normalized === "no") {
2678
- return false;
2679
- }
2710
+ }
2711
+ function polyfillStringIncludes() {
2712
+ if (!String.prototype.includes) {
2713
+ String.prototype.includes = function(search, start) {
2714
+ if (typeof start !== "number") {
2715
+ start = 0;
2716
+ }
2717
+ if (start + search.length > this.length) {
2718
+ return false;
2719
+ }
2720
+ return this.indexOf(search, start) !== -1;
2721
+ };
2680
2722
  }
2681
- return void 0;
2723
+ }
2724
+ function initializePolyfills() {
2725
+ polyfillObjectAssign();
2726
+ polyfillArrayFrom();
2727
+ polyfillStringStartsWith();
2728
+ polyfillStringEndsWith();
2729
+ polyfillStringIncludes();
2730
+ polyfillURLSearchParams();
2731
+ polyfillTextEncoder();
2732
+ polyfillPromiseFinally();
2682
2733
  }
2683
2734
  // src/utils/vastMacros.ts
2684
2735
  var UNEXPANDED_MACRO_PATTERN = /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/;