stormcloud-video-player 0.6.7 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +239 -182
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +23 -2
- package/lib/index.d.ts +23 -2
- package/lib/index.js +239 -182
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +239 -182
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +6 -1
- package/lib/players/HlsPlayer.cjs +239 -182
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +239 -182
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/vastAdLayer.cjs +1 -26
- package/lib/sdk/vastAdLayer.cjs.map +1 -1
- package/lib/sdk/vastAdLayer.d.cts +1 -1
- package/lib/sdk/vastManager.d.cts +1 -1
- package/lib/{types-BYwfSJb5.d.cts → types-DSKC4ySr.d.cts} +5 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +239 -182
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/tracking.cjs +179 -150
- package/lib/utils/tracking.cjs.map +1 -1
- package/lib/utils/tracking.d.cts +11 -6
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { StormcloudVideoPlayer } from '../player/StormcloudVideoPlayer.cjs';
|
|
3
|
-
import { S as StormcloudVideoPlayerConfig } from '../types-
|
|
3
|
+
import { S as StormcloudVideoPlayerConfig } from '../types-DSKC4ySr.cjs';
|
|
4
4
|
|
|
5
5
|
type StormcloudVideoPlayerProps = Omit<StormcloudVideoPlayerConfig, "videoElement"> & React.VideoHTMLAttributes<HTMLVideoElement> & {
|
|
6
6
|
onReady?: (player: StormcloudVideoPlayer) => void;
|
package/lib/utils/tracking.cjs
CHANGED
|
@@ -56,30 +56,6 @@ function _object_spread(target) {
|
|
|
56
56
|
}
|
|
57
57
|
return target;
|
|
58
58
|
}
|
|
59
|
-
function ownKeys(object, enumerableOnly) {
|
|
60
|
-
var keys = Object.keys(object);
|
|
61
|
-
if (Object.getOwnPropertySymbols) {
|
|
62
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
63
|
-
if (enumerableOnly) {
|
|
64
|
-
symbols = symbols.filter(function(sym) {
|
|
65
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
keys.push.apply(keys, symbols);
|
|
69
|
-
}
|
|
70
|
-
return keys;
|
|
71
|
-
}
|
|
72
|
-
function _object_spread_props(target, source) {
|
|
73
|
-
source = source != null ? source : {};
|
|
74
|
-
if (Object.getOwnPropertyDescriptors) {
|
|
75
|
-
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
76
|
-
} else {
|
|
77
|
-
ownKeys(Object(source)).forEach(function(key) {
|
|
78
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
return target;
|
|
82
|
-
}
|
|
83
59
|
function _type_of(obj) {
|
|
84
60
|
"@swc/helpers - typeof";
|
|
85
61
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
@@ -484,24 +460,30 @@ function getBrowserID(clientInfo) {
|
|
|
484
460
|
});
|
|
485
461
|
})();
|
|
486
462
|
}
|
|
487
|
-
var
|
|
463
|
+
var PLAYER_TRACKING_BASE_URL = "https://adstorm.co/api-adstorm-dev/adstorm/player-tracking";
|
|
464
|
+
var TRACK_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/metrics/ingest");
|
|
465
|
+
var HEARTBEAT_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/heartbeat");
|
|
466
|
+
var IMPRESSIONS_URL = "".concat(PLAYER_TRACKING_BASE_URL, "/impressions/ingest");
|
|
467
|
+
function buildHeaders(licenseKey) {
|
|
468
|
+
var headers = {
|
|
469
|
+
"Content-Type": "application/json"
|
|
470
|
+
};
|
|
471
|
+
if (licenseKey) {
|
|
472
|
+
headers["Authorization"] = "Bearer ".concat(licenseKey);
|
|
473
|
+
}
|
|
474
|
+
return headers;
|
|
475
|
+
}
|
|
488
476
|
function sendTrackRequest(licenseKey, body) {
|
|
489
477
|
return _async_to_generator(function() {
|
|
490
|
-
var
|
|
478
|
+
var response;
|
|
491
479
|
return _ts_generator(this, function(_state) {
|
|
492
480
|
switch(_state.label){
|
|
493
481
|
case 0:
|
|
494
|
-
headers = {
|
|
495
|
-
"Content-Type": "application/json"
|
|
496
|
-
};
|
|
497
|
-
if (licenseKey) {
|
|
498
|
-
headers["Authorization"] = "Bearer ".concat(licenseKey);
|
|
499
|
-
}
|
|
500
482
|
return [
|
|
501
483
|
4,
|
|
502
484
|
fetch(TRACK_URL, {
|
|
503
485
|
method: "POST",
|
|
504
|
-
headers:
|
|
486
|
+
headers: buildHeaders(licenseKey),
|
|
505
487
|
body: JSON.stringify(body)
|
|
506
488
|
})
|
|
507
489
|
];
|
|
@@ -523,14 +505,86 @@ function sendTrackRequest(licenseKey, body) {
|
|
|
523
505
|
});
|
|
524
506
|
})();
|
|
525
507
|
}
|
|
526
|
-
function
|
|
508
|
+
function postJson(url, licenseKey, body) {
|
|
527
509
|
return _async_to_generator(function() {
|
|
528
|
-
var
|
|
510
|
+
var response;
|
|
511
|
+
return _ts_generator(this, function(_state) {
|
|
512
|
+
switch(_state.label){
|
|
513
|
+
case 0:
|
|
514
|
+
return [
|
|
515
|
+
4,
|
|
516
|
+
fetch(url, {
|
|
517
|
+
method: "POST",
|
|
518
|
+
headers: buildHeaders(licenseKey),
|
|
519
|
+
body: JSON.stringify(body)
|
|
520
|
+
})
|
|
521
|
+
];
|
|
522
|
+
case 1:
|
|
523
|
+
response = _state.sent();
|
|
524
|
+
if (!response.ok) {
|
|
525
|
+
throw new Error("HTTP error! status: ".concat(response.status));
|
|
526
|
+
}
|
|
527
|
+
return [
|
|
528
|
+
4,
|
|
529
|
+
response.json()
|
|
530
|
+
];
|
|
531
|
+
case 2:
|
|
532
|
+
_state.sent();
|
|
533
|
+
return [
|
|
534
|
+
2
|
|
535
|
+
];
|
|
536
|
+
}
|
|
537
|
+
});
|
|
538
|
+
})();
|
|
539
|
+
}
|
|
540
|
+
function buildPlayerMetricEvent(_0) {
|
|
541
|
+
return _async_to_generator(function(licenseKey) {
|
|
542
|
+
var context, flags, _flags_captureAt, clientInfo, browserId, captureAt;
|
|
543
|
+
var _arguments = arguments;
|
|
529
544
|
return _ts_generator(this, function(_state) {
|
|
530
545
|
switch(_state.label){
|
|
531
546
|
case 0:
|
|
547
|
+
context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
|
|
548
|
+
clientInfo = getClientInfo();
|
|
549
|
+
return [
|
|
550
|
+
4,
|
|
551
|
+
getBrowserID(clientInfo)
|
|
552
|
+
];
|
|
553
|
+
case 1:
|
|
554
|
+
browserId = _state.sent();
|
|
555
|
+
captureAt = (_flags_captureAt = flags.captureAt) !== null && _flags_captureAt !== void 0 ? _flags_captureAt : /* @__PURE__ */ new Date().toISOString();
|
|
556
|
+
return [
|
|
557
|
+
2,
|
|
558
|
+
{
|
|
559
|
+
player_id: browserId,
|
|
560
|
+
browserId: browserId,
|
|
561
|
+
device_type: clientInfo.deviceType,
|
|
562
|
+
deviceType: clientInfo.deviceType,
|
|
563
|
+
input_stream_type: context.inputStreamType,
|
|
564
|
+
os: clientInfo.os,
|
|
565
|
+
ad_loaded: flags.adLoaded,
|
|
566
|
+
ad_detect: flags.adDetect,
|
|
567
|
+
license_key: licenseKey,
|
|
568
|
+
capture_at: captureAt,
|
|
569
|
+
timestamp: captureAt
|
|
570
|
+
}
|
|
571
|
+
];
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
}).apply(this, arguments);
|
|
575
|
+
}
|
|
576
|
+
function sendInitialTracking(_0) {
|
|
577
|
+
return _async_to_generator(function(licenseKey) {
|
|
578
|
+
var context, clientInfo, browserId, trackingData, error;
|
|
579
|
+
var _arguments = arguments;
|
|
580
|
+
return _ts_generator(this, function(_state) {
|
|
581
|
+
switch(_state.label){
|
|
582
|
+
case 0:
|
|
583
|
+
context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {};
|
|
584
|
+
_state.label = 1;
|
|
585
|
+
case 1:
|
|
532
586
|
_state.trys.push([
|
|
533
|
-
|
|
587
|
+
1,
|
|
534
588
|
4,
|
|
535
589
|
,
|
|
536
590
|
5
|
|
@@ -540,34 +594,29 @@ function sendInitialTracking(licenseKey) {
|
|
|
540
594
|
4,
|
|
541
595
|
getBrowserID(clientInfo)
|
|
542
596
|
];
|
|
543
|
-
case
|
|
597
|
+
case 2:
|
|
544
598
|
browserId = _state.sent();
|
|
545
599
|
trackingData = _object_spread({
|
|
546
600
|
browserId: browserId
|
|
547
601
|
}, clientInfo);
|
|
548
|
-
headers = {
|
|
549
|
-
"Content-Type": "application/json"
|
|
550
|
-
};
|
|
551
|
-
if (licenseKey) {
|
|
552
|
-
headers["Authorization"] = "Bearer ".concat(licenseKey);
|
|
553
|
-
}
|
|
554
602
|
return [
|
|
555
603
|
4,
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
604
|
+
sendTrackRequest(licenseKey, {
|
|
605
|
+
events: [
|
|
606
|
+
{
|
|
607
|
+
player_id: browserId,
|
|
608
|
+
device_type: clientInfo.deviceType,
|
|
609
|
+
input_stream_type: context.inputStreamType,
|
|
610
|
+
os: clientInfo.os,
|
|
611
|
+
ad_loaded: false,
|
|
612
|
+
ad_detect: false,
|
|
613
|
+
license_key: licenseKey,
|
|
614
|
+
capture_at: /* @__PURE__ */ new Date().toISOString()
|
|
615
|
+
}
|
|
616
|
+
],
|
|
617
|
+
trackingData: trackingData
|
|
560
618
|
})
|
|
561
619
|
];
|
|
562
|
-
case 2:
|
|
563
|
-
response = _state.sent();
|
|
564
|
-
if (!response.ok) {
|
|
565
|
-
throw new Error("HTTP error! status: ".concat(response.status));
|
|
566
|
-
}
|
|
567
|
-
return [
|
|
568
|
-
4,
|
|
569
|
-
response.json()
|
|
570
|
-
];
|
|
571
620
|
case 3:
|
|
572
621
|
_state.sent();
|
|
573
622
|
return [
|
|
@@ -587,36 +636,30 @@ function sendInitialTracking(licenseKey) {
|
|
|
587
636
|
];
|
|
588
637
|
}
|
|
589
638
|
});
|
|
590
|
-
})();
|
|
639
|
+
}).apply(this, arguments);
|
|
591
640
|
}
|
|
592
|
-
function sendAdDetectTracking(
|
|
593
|
-
return _async_to_generator(function() {
|
|
594
|
-
var
|
|
641
|
+
function sendAdDetectTracking(_0, _1) {
|
|
642
|
+
return _async_to_generator(function(licenseKey, adDetectInfo) {
|
|
643
|
+
var context, error;
|
|
644
|
+
var _arguments = arguments;
|
|
595
645
|
return _ts_generator(this, function(_state) {
|
|
596
646
|
switch(_state.label){
|
|
597
647
|
case 0:
|
|
648
|
+
context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
|
|
649
|
+
_state.label = 1;
|
|
650
|
+
case 1:
|
|
598
651
|
_state.trys.push([
|
|
599
|
-
|
|
652
|
+
1,
|
|
600
653
|
3,
|
|
601
654
|
,
|
|
602
655
|
4
|
|
603
656
|
]);
|
|
604
|
-
clientInfo = getClientInfo();
|
|
605
|
-
return [
|
|
606
|
-
4,
|
|
607
|
-
getBrowserID(clientInfo)
|
|
608
|
-
];
|
|
609
|
-
case 1:
|
|
610
|
-
browserId = _state.sent();
|
|
611
|
-
trackingData = _object_spread({
|
|
612
|
-
browserId: browserId
|
|
613
|
-
}, clientInfo);
|
|
614
657
|
return [
|
|
615
658
|
4,
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
})
|
|
659
|
+
sendHeartbeat(licenseKey, context, {
|
|
660
|
+
adDetect: true,
|
|
661
|
+
captureAt: adDetectInfo.timestamp
|
|
662
|
+
})
|
|
620
663
|
];
|
|
621
664
|
case 2:
|
|
622
665
|
_state.sent();
|
|
@@ -637,36 +680,30 @@ function sendAdDetectTracking(licenseKey, adDetectInfo) {
|
|
|
637
680
|
];
|
|
638
681
|
}
|
|
639
682
|
});
|
|
640
|
-
})();
|
|
683
|
+
}).apply(this, arguments);
|
|
641
684
|
}
|
|
642
|
-
function sendAdLoadedTracking(
|
|
643
|
-
return _async_to_generator(function() {
|
|
644
|
-
var
|
|
685
|
+
function sendAdLoadedTracking(_0, _1) {
|
|
686
|
+
return _async_to_generator(function(licenseKey, adLoadedInfo) {
|
|
687
|
+
var context, error;
|
|
688
|
+
var _arguments = arguments;
|
|
645
689
|
return _ts_generator(this, function(_state) {
|
|
646
690
|
switch(_state.label){
|
|
647
691
|
case 0:
|
|
692
|
+
context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
|
|
693
|
+
_state.label = 1;
|
|
694
|
+
case 1:
|
|
648
695
|
_state.trys.push([
|
|
649
|
-
|
|
696
|
+
1,
|
|
650
697
|
3,
|
|
651
698
|
,
|
|
652
699
|
4
|
|
653
700
|
]);
|
|
654
|
-
clientInfo = getClientInfo();
|
|
655
|
-
return [
|
|
656
|
-
4,
|
|
657
|
-
getBrowserID(clientInfo)
|
|
658
|
-
];
|
|
659
|
-
case 1:
|
|
660
|
-
browserId = _state.sent();
|
|
661
|
-
trackingData = _object_spread({
|
|
662
|
-
browserId: browserId
|
|
663
|
-
}, clientInfo);
|
|
664
701
|
return [
|
|
665
702
|
4,
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
})
|
|
703
|
+
sendHeartbeat(licenseKey, context, {
|
|
704
|
+
adLoaded: true,
|
|
705
|
+
captureAt: adLoadedInfo.timestamp
|
|
706
|
+
})
|
|
670
707
|
];
|
|
671
708
|
case 2:
|
|
672
709
|
_state.sent();
|
|
@@ -687,103 +724,95 @@ function sendAdLoadedTracking(licenseKey, adLoadedInfo) {
|
|
|
687
724
|
];
|
|
688
725
|
}
|
|
689
726
|
});
|
|
690
|
-
})();
|
|
727
|
+
}).apply(this, arguments);
|
|
691
728
|
}
|
|
692
|
-
function sendAdImpressionTracking(
|
|
693
|
-
return _async_to_generator(function() {
|
|
694
|
-
var
|
|
729
|
+
function sendAdImpressionTracking(_0, _1) {
|
|
730
|
+
return _async_to_generator(function(licenseKey, adImpressionInfo) {
|
|
731
|
+
var context, metricEvent, error;
|
|
732
|
+
var _arguments = arguments;
|
|
695
733
|
return _ts_generator(this, function(_state) {
|
|
696
734
|
switch(_state.label){
|
|
697
735
|
case 0:
|
|
736
|
+
context = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
|
|
737
|
+
_state.label = 1;
|
|
738
|
+
case 1:
|
|
698
739
|
_state.trys.push([
|
|
699
|
-
|
|
700
|
-
|
|
740
|
+
1,
|
|
741
|
+
4,
|
|
701
742
|
,
|
|
702
|
-
|
|
743
|
+
5
|
|
703
744
|
]);
|
|
704
|
-
clientInfo = getClientInfo();
|
|
705
745
|
return [
|
|
706
746
|
4,
|
|
707
|
-
|
|
747
|
+
buildPlayerMetricEvent(licenseKey, context, {
|
|
748
|
+
captureAt: adImpressionInfo.timestamp
|
|
749
|
+
})
|
|
708
750
|
];
|
|
709
|
-
case
|
|
710
|
-
|
|
711
|
-
trackingData = _object_spread({
|
|
712
|
-
browserId: browserId
|
|
713
|
-
}, clientInfo);
|
|
751
|
+
case 2:
|
|
752
|
+
metricEvent = _state.sent();
|
|
714
753
|
return [
|
|
715
754
|
4,
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
755
|
+
Promise.all([
|
|
756
|
+
postJson(HEARTBEAT_URL, licenseKey, metricEvent),
|
|
757
|
+
postJson(IMPRESSIONS_URL, licenseKey, {
|
|
758
|
+
events: [
|
|
759
|
+
{
|
|
760
|
+
player_id: metricEvent.player_id,
|
|
761
|
+
ad_played_count: 1,
|
|
762
|
+
ad_url: adImpressionInfo.adUrl,
|
|
763
|
+
license_key: licenseKey,
|
|
764
|
+
capture_at: adImpressionInfo.timestamp
|
|
765
|
+
}
|
|
766
|
+
]
|
|
767
|
+
})
|
|
768
|
+
])
|
|
720
769
|
];
|
|
721
|
-
case
|
|
770
|
+
case 3:
|
|
722
771
|
_state.sent();
|
|
723
772
|
return [
|
|
724
773
|
3,
|
|
725
|
-
|
|
774
|
+
5
|
|
726
775
|
];
|
|
727
|
-
case
|
|
776
|
+
case 4:
|
|
728
777
|
error = _state.sent();
|
|
729
778
|
console.error("[StormcloudVideoPlayer] Error sending ad impression tracking:", error);
|
|
730
779
|
return [
|
|
731
780
|
3,
|
|
732
|
-
|
|
781
|
+
5
|
|
733
782
|
];
|
|
734
|
-
case
|
|
783
|
+
case 5:
|
|
735
784
|
return [
|
|
736
785
|
2
|
|
737
786
|
];
|
|
738
787
|
}
|
|
739
788
|
});
|
|
740
|
-
})();
|
|
789
|
+
}).apply(this, arguments);
|
|
741
790
|
}
|
|
742
|
-
function sendHeartbeat(
|
|
743
|
-
return _async_to_generator(function() {
|
|
744
|
-
var
|
|
791
|
+
function sendHeartbeat(_0) {
|
|
792
|
+
return _async_to_generator(function(licenseKey) {
|
|
793
|
+
var context, flags, heartbeatData, error;
|
|
794
|
+
var _arguments = arguments;
|
|
745
795
|
return _ts_generator(this, function(_state) {
|
|
746
796
|
switch(_state.label){
|
|
747
797
|
case 0:
|
|
798
|
+
context = _arguments.length > 1 && _arguments[1] !== void 0 ? _arguments[1] : {}, flags = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
|
|
799
|
+
_state.label = 1;
|
|
800
|
+
case 1:
|
|
748
801
|
_state.trys.push([
|
|
749
|
-
|
|
802
|
+
1,
|
|
750
803
|
4,
|
|
751
804
|
,
|
|
752
805
|
5
|
|
753
806
|
]);
|
|
754
|
-
clientInfo = getClientInfo();
|
|
755
807
|
return [
|
|
756
808
|
4,
|
|
757
|
-
|
|
758
|
-
];
|
|
759
|
-
case 1:
|
|
760
|
-
browserId = _state.sent();
|
|
761
|
-
heartbeatData = {
|
|
762
|
-
browserId: browserId,
|
|
763
|
-
timestamp: /* @__PURE__ */ new Date().toISOString()
|
|
764
|
-
};
|
|
765
|
-
headers = {
|
|
766
|
-
"Content-Type": "application/json"
|
|
767
|
-
};
|
|
768
|
-
if (licenseKey) {
|
|
769
|
-
headers["Authorization"] = "Bearer ".concat(licenseKey);
|
|
770
|
-
}
|
|
771
|
-
return [
|
|
772
|
-
4,
|
|
773
|
-
fetch("https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat", {
|
|
774
|
-
method: "POST",
|
|
775
|
-
headers: headers,
|
|
776
|
-
body: JSON.stringify(heartbeatData)
|
|
777
|
-
})
|
|
809
|
+
buildPlayerMetricEvent(licenseKey, context, flags)
|
|
778
810
|
];
|
|
779
811
|
case 2:
|
|
780
|
-
|
|
781
|
-
if (!response.ok) {
|
|
782
|
-
throw new Error("HTTP error! status: ".concat(response.status));
|
|
783
|
-
}
|
|
812
|
+
heartbeatData = _state.sent();
|
|
784
813
|
return [
|
|
785
814
|
4,
|
|
786
|
-
|
|
815
|
+
postJson(HEARTBEAT_URL, licenseKey, heartbeatData)
|
|
787
816
|
];
|
|
788
817
|
case 3:
|
|
789
818
|
_state.sent();
|
|
@@ -804,7 +833,7 @@ function sendHeartbeat(licenseKey) {
|
|
|
804
833
|
];
|
|
805
834
|
}
|
|
806
835
|
});
|
|
807
|
-
})();
|
|
836
|
+
}).apply(this, arguments);
|
|
808
837
|
}
|
|
809
838
|
// Annotate the CommonJS export names for ESM import in node:
|
|
810
839
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/utils/tracking.cjs","../../src/utils/tracking.ts"],"names":["__defProp","Object","__getOwnPropDesc","__getOwnPropNames","enumerable","defineProperty","getOwnPropertyDescriptor","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","all","name","get","__copyProps","to","from","except","desc","key","__toCommonJS","mod","value","tracking_exports","getClientInfo","exports","getBrowserID","sendAdDetectTracking","sendAdImpressionTracking","sendAdLoadedTracking","sendHeartbeat","sendInitialTracking","cachedBrowserId","screen","window","navigator","vendor","maxTouchPoints","hardwareConcurrency","screenInfo","width","height","availWidth","availHeight","orientation","type","deviceType","brand","os","isAndroid","isWebView","ua","includes","isSmartTV","webosMatch","match","model","tizenMatch","tvMatch","trim","test","androidModelMatch"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/utils/tracking.ts\nvar tracking_exports = {};\n__export(tracking_exports, {\n getBrowserID: () => getBrowserID,\n getClientInfo: () => getClientInfo,\n sendAdDetectTracking: () => sendAdDetectTracking,\n sendAdImpressionTracking: () => sendAdImpressionTracking,\n sendAdLoadedTracking: () => sendAdLoadedTracking,\n sendHeartbeat: () => sendHeartbeat,\n sendInitialTracking: () => sendInitialTracking\n});\nmodule.exports = __toCommonJS(tracking_exports);\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nvar TRACK_URL = \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\nasync function sendTrackRequest(licenseKey, body) {\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function sendInitialTracking(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const heartbeatData = {\n browserId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n };\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData)\n }\n );\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n getBrowserID,\n getClientInfo,\n sendAdDetectTracking,\n sendAdImpressionTracking,\n sendAdLoadedTracking,\n sendHeartbeat,\n sendInitialTracking\n});\n","import type {\n ClientInfo,\n TrackingData,\n HeartbeatData,\n AdDetectInfo,\n AdLoadedInfo,\n AdImpressionInfo,\n} from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nconst TRACK_URL =\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/track\";\n\nasync function sendTrackRequest(\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nexport async function sendInitialTracking(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers,\n body: JSON.stringify(trackingData),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendAdDetectTracking(\n licenseKey: string | undefined,\n adDetectInfo: AdDetectInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adDetectInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdLoadedTracking(\n licenseKey: string | undefined,\n adLoadedInfo: AdLoadedInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adLoadedInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdImpressionTracking(\n licenseKey: string | undefined,\n adImpressionInfo: AdImpressionInfo\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData: TrackingData = { browserId, ...clientInfo };\n await sendTrackRequest(licenseKey, {\n ...trackingData,\n licenseKey,\n adImpressionInfo,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(licenseKey?: string): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const heartbeatData: HeartbeatData = {\n browserId,\n timestamp: new Date().toISOString(),\n };\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n\n const response = await fetch(\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking/heartbeat\",\n {\n method: \"POST\",\n headers,\n body: JSON.stringify(heartbeatData),\n }\n );\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n await response.json();\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/ubuntu24-new/Dev/stormcloud-vp/lib/utils/tracking.cjs","../../src/utils/tracking.ts"],"names":["name","all","__defProp","Object","defineProperty","__getOwnPropDesc","getOwnPropertyDescriptor","__getOwnPropNames","getOwnPropertyNames","__hasOwnProp","prototype","hasOwnProperty","__export","target","get","enumerable","__copyProps","to","from","except","desc","key","value","mod","tracking_exports","getBrowserID","call","getClientInfo","sendAdDetectTracking","sendAdImpressionTracking","sendAdLoadedTracking","sendHeartbeat","sendInitialTracking","module","exports","__toCommonJS","cachedBrowserId","screen","window","navigator","ua","userAgent","platform","vendor","maxTouchPoints","deviceMemory","hardwareConcurrency","screenInfo","width","height","memory","availWidth","availHeight","orientation","type","pixelDepth","deviceType","brand","os","model","isSmartTV","isAndroid","isWebView","isWebApp","includes","webosMatch","match","tvMatch","tizenMatch","trim","test","androidModelMatch","outerHeight","outerWidth","domain","substring","location","hostname","origin","language","languages","join","cookieEnabled","doNotTrack"],"mappings":"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","sourcesContent":["\"use strict\";\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __export = (target, all) => {\n for (var name in all)\n __defProp(target, name, { get: all[name], enumerable: true });\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === \"object\" || typeof from === \"function\") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toCommonJS = (mod) => __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n// src/utils/tracking.ts\nvar tracking_exports = {};\n__export(tracking_exports, {\n getBrowserID: () => getBrowserID,\n getClientInfo: () => getClientInfo,\n sendAdDetectTracking: () => sendAdDetectTracking,\n sendAdImpressionTracking: () => sendAdImpressionTracking,\n sendAdLoadedTracking: () => sendAdLoadedTracking,\n sendHeartbeat: () => sendHeartbeat,\n sendInitialTracking: () => sendInitialTracking\n});\nmodule.exports = __toCommonJS(tracking_exports);\nvar cachedBrowserId = null;\nfunction getClientInfo() {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = navigator.deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: screen?.orientation?.type || \"\",\n pixelDepth: screen?.pixelDepth\n };\n let deviceType = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim() : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Android\") && (ua.includes(\"NetCast\") || ua.includes(\"LG\"))) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n if (ua.includes(\"Android\") && (maxTouchPoints === 0 || ua.includes(\"Google TV\") || ua.includes(\"XiaoMi\"))) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n isWebApp = window.matchMedia(\"(display-mode: standalone)\").matches || window.navigator.standalone === true || window.screen?.orientation?.angle !== void 0;\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState\n };\n}\nasync function getBrowserID(clientInfo) {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n const fingerprintString = JSON.stringify(clientInfo);\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n let encodedData;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray.map((b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\nvar PLAYER_TRACKING_BASE_URL = \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking\";\nvar TRACK_URL = `${PLAYER_TRACKING_BASE_URL}/metrics/ingest`;\nvar HEARTBEAT_URL = `${PLAYER_TRACKING_BASE_URL}/heartbeat`;\nvar IMPRESSIONS_URL = `${PLAYER_TRACKING_BASE_URL}/impressions/ingest`;\nfunction buildHeaders(licenseKey) {\n const headers = {\n \"Content-Type\": \"application/json\"\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n return headers;\n}\nasync function sendTrackRequest(licenseKey, body) {\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function postJson(url, licenseKey, body) {\n const response = await fetch(url, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body)\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\nasync function buildPlayerMetricEvent(licenseKey, context = {}, flags = {}) {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const captureAt = flags.captureAt ?? (/* @__PURE__ */ new Date()).toISOString();\n return {\n player_id: browserId,\n browserId,\n device_type: clientInfo.deviceType,\n deviceType: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: flags.adLoaded,\n ad_detect: flags.adDetect,\n license_key: licenseKey,\n capture_at: captureAt,\n timestamp: captureAt\n };\n}\nasync function sendInitialTracking(licenseKey, context = {}) {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const trackingData = {\n browserId,\n ...clientInfo\n };\n await sendTrackRequest(licenseKey, {\n events: [\n {\n player_id: browserId,\n device_type: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: false,\n ad_detect: false,\n license_key: licenseKey,\n capture_at: (/* @__PURE__ */ new Date()).toISOString()\n }\n ],\n trackingData\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\nasync function sendAdDetectTracking(licenseKey, adDetectInfo, context = {}) {\n try {\n await sendHeartbeat(licenseKey, context, {\n adDetect: true,\n captureAt: adDetectInfo.timestamp\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\nasync function sendAdLoadedTracking(licenseKey, adLoadedInfo, context = {}) {\n try {\n await sendHeartbeat(licenseKey, context, {\n adLoaded: true,\n captureAt: adLoadedInfo.timestamp\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\nasync function sendAdImpressionTracking(licenseKey, adImpressionInfo, context = {}) {\n try {\n const metricEvent = await buildPlayerMetricEvent(licenseKey, context, {\n captureAt: adImpressionInfo.timestamp\n });\n await Promise.all([\n postJson(HEARTBEAT_URL, licenseKey, metricEvent),\n postJson(IMPRESSIONS_URL, licenseKey, {\n events: [\n {\n player_id: metricEvent.player_id,\n ad_played_count: 1,\n ad_url: adImpressionInfo.adUrl,\n license_key: licenseKey,\n capture_at: adImpressionInfo.timestamp\n }\n ]\n })\n ]);\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\nasync function sendHeartbeat(licenseKey, context = {}, flags = {}) {\n try {\n const heartbeatData = await buildPlayerMetricEvent(\n licenseKey,\n context,\n flags\n );\n await postJson(HEARTBEAT_URL, licenseKey, heartbeatData);\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {\n getBrowserID,\n getClientInfo,\n sendAdDetectTracking,\n sendAdImpressionTracking,\n sendAdLoadedTracking,\n sendHeartbeat,\n sendInitialTracking\n});\n","import type {\n ClientInfo,\n TrackingData,\n AdDetectInfo,\n AdLoadedInfo,\n AdImpressionInfo,\n PlayerAnalyticsContext,\n} from \"../types\";\n\nlet cachedBrowserId: string | null = null;\n\nexport function getClientInfo(): ClientInfo {\n const ua = navigator.userAgent;\n const platform = navigator.platform;\n const vendor = navigator.vendor || \"\";\n const maxTouchPoints = navigator.maxTouchPoints || 0;\n const memory = (navigator as any).deviceMemory || null;\n const hardwareConcurrency = navigator.hardwareConcurrency || 1;\n\n const screenInfo = {\n width: screen?.width,\n height: screen?.height,\n availWidth: screen?.availWidth,\n availHeight: screen?.availHeight,\n orientation: (screen?.orientation as any)?.type || \"\",\n pixelDepth: screen?.pixelDepth,\n };\n\n let deviceType: \"tv\" | \"mobile\" | \"tablet\" | \"desktop\" = \"desktop\";\n let brand = \"Unknown\";\n let os = \"Unknown\";\n let model = \"\";\n let isSmartTV = false;\n let isAndroid = false;\n let isWebView = false;\n let isWebApp = false;\n\n if (ua.includes(\"Web0S\")) {\n brand = \"LG\";\n os = \"webOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n const webosMatch = ua.match(/Web0S\\/([^\\s]+)/);\n model = webosMatch ? `webOS ${webosMatch[1]}` : \"webOS TV\";\n } else if (ua.includes(\"Tizen\")) {\n brand = \"Samsung\";\n os = \"Tizen\";\n isSmartTV = true;\n deviceType = \"tv\";\n const tizenMatch = ua.match(/Tizen\\/([^\\s]+)/);\n const tvMatch = ua.match(/(?:Smart-TV|SMART-TV|TV)/i) ? \"Smart TV\" : \"\";\n model = tizenMatch\n ? `Tizen ${tizenMatch[1]} ${tvMatch}`.trim()\n : \"Tizen TV\";\n } else if (ua.includes(\"Philips\")) {\n brand = \"Philips\";\n os = \"Saphi\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"Sharp\") || ua.includes(\"AQUOS\")) {\n brand = \"Sharp\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"Sony\") || vendor.includes(\"Sony\"))\n ) {\n brand = \"Sony\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (\n ua.includes(\"Android\") &&\n (ua.includes(\"NetCast\") || ua.includes(\"LG\"))\n ) {\n brand = \"LG\";\n os = \"Android TV\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\" Roku\") || ua.includes(\"Roku/\")) {\n brand = \"Roku\";\n os = \"Roku OS\";\n isSmartTV = true;\n deviceType = \"tv\";\n } else if (ua.includes(\"AppleTV\")) {\n brand = \"Apple\";\n os = \"tvOS\";\n isSmartTV = true;\n deviceType = \"tv\";\n }\n\n if (ua.includes(\"Android\")) {\n isAndroid = true;\n os = \"Android\";\n deviceType = /Mobile/.test(ua) ? \"mobile\" : \"tablet\";\n\n if (\n ua.includes(\"Android\") &&\n (maxTouchPoints === 0 ||\n ua.includes(\"Google TV\") ||\n ua.includes(\"XiaoMi\"))\n ) {\n deviceType = \"tv\";\n isSmartTV = true;\n brand = brand === \"Unknown\" ? \"Android TV\" : brand;\n }\n\n const androidModelMatch = ua.match(/\\(([^)]*Android[^)]*)\\)/);\n if (androidModelMatch && androidModelMatch[1]) {\n model = androidModelMatch[1];\n }\n }\n\n if (/iPad|iPhone|iPod/.test(ua)) {\n os = \"iOS\";\n deviceType = \"mobile\";\n brand = \"Apple\";\n if (navigator.maxTouchPoints > 1 && /iPad/.test(ua)) {\n deviceType = \"tablet\";\n }\n }\n\n if (!isAndroid && !isSmartTV && !/Mobile/.test(ua)) {\n if (ua.includes(\"Windows\")) {\n os = \"Windows\";\n deviceType = \"desktop\";\n } else if (ua.includes(\"Mac\") && !/iPhone/.test(ua)) {\n os = \"macOS\";\n deviceType = \"desktop\";\n if (maxTouchPoints > 1) deviceType = \"tablet\";\n } else if (ua.includes(\"Linux\")) {\n os = \"Linux\";\n deviceType = \"desktop\";\n }\n }\n\n if (brand === \"Unknown\") {\n if (vendor.includes(\"Google\") || ua.includes(\"Chrome\")) brand = \"Google\";\n if (vendor.includes(\"Apple\")) brand = \"Apple\";\n if (vendor.includes(\"Samsung\") || ua.includes(\"SM-\")) brand = \"Samsung\";\n }\n\n isWebView = /wv|WebView|Linux; U;/.test(ua);\n\n if (window?.outerHeight === 0 && window?.outerWidth === 0) {\n isWebView = true;\n }\n\n isWebApp =\n window.matchMedia(\"(display-mode: standalone)\").matches ||\n (window.navigator as any).standalone === true ||\n window.screen?.orientation?.angle !== undefined;\n\n return {\n brand,\n os,\n model: model || ua.substring(0, 50) + \"...\",\n deviceType,\n isSmartTV,\n isAndroid,\n isWebView,\n isWebApp,\n domain: window.location.hostname,\n origin: window.location.origin,\n path: window.location.pathname,\n userAgent: ua,\n vendor,\n platform,\n screen: screenInfo,\n hardwareConcurrency,\n deviceMemory: memory,\n maxTouchPoints,\n language: navigator.language,\n languages: navigator.languages?.join(\",\") || \"\",\n cookieEnabled: navigator.cookieEnabled,\n doNotTrack: navigator.doNotTrack || \"\",\n referrer: document.referrer,\n visibilityState: document.visibilityState,\n };\n}\n\nexport async function getBrowserID(clientInfo: ClientInfo): Promise<string> {\n if (cachedBrowserId) {\n return cachedBrowserId;\n }\n\n const fingerprintString = JSON.stringify(clientInfo);\n\n if (typeof crypto !== \"undefined\" && crypto.subtle && crypto.subtle.digest) {\n try {\n await crypto.subtle.digest(\"SHA-256\", new Uint8Array([1, 2, 3]));\n\n let encodedData: BufferSource;\n if (typeof TextEncoder !== \"undefined\") {\n encodedData = new TextEncoder().encode(fingerprintString);\n } else {\n const utf8 = unescape(encodeURIComponent(fingerprintString));\n const buffer = new Uint8Array(utf8.length);\n for (let i = 0; i < utf8.length; i++) {\n buffer[i] = utf8.charCodeAt(i);\n }\n encodedData = buffer;\n }\n\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encodedData);\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n const hashHex = hashArray\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n cachedBrowserId = hashHex;\n return hashHex;\n } catch (error) {\n console.warn(\n \"[StormcloudVideoPlayer] crypto.subtle.digest not supported, using fallback hash\"\n );\n }\n }\n\n let hash = 0;\n for (let i = 0; i < fingerprintString.length; i++) {\n const char = fingerprintString.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n\n const fallbackHash = Math.abs(hash).toString(16).padStart(8, \"0\");\n const timestamp = Date.now().toString(16).padStart(12, \"0\");\n const random = Math.random().toString(16).substring(2, 14).padStart(12, \"0\");\n\n cachedBrowserId = (fallbackHash + timestamp + random).padEnd(64, \"0\");\n return cachedBrowserId;\n}\n\nconst PLAYER_TRACKING_BASE_URL =\n \"https://adstorm.co/api-adstorm-dev/adstorm/player-tracking\";\nconst TRACK_URL = `${PLAYER_TRACKING_BASE_URL}/metrics/ingest`;\nconst HEARTBEAT_URL = `${PLAYER_TRACKING_BASE_URL}/heartbeat`;\nconst IMPRESSIONS_URL = `${PLAYER_TRACKING_BASE_URL}/impressions/ingest`;\n\ntype PlayerMetricFlags = {\n adLoaded?: boolean;\n adDetect?: boolean;\n captureAt?: string;\n};\n\nfunction buildHeaders(licenseKey: string | undefined): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (licenseKey) {\n headers[\"Authorization\"] = `Bearer ${licenseKey}`;\n }\n return headers;\n}\n\nasync function sendTrackRequest(\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const response = await fetch(TRACK_URL, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nasync function postJson(\n url: string,\n licenseKey: string | undefined,\n body: Record<string, unknown>\n): Promise<void> {\n const response = await fetch(url, {\n method: \"POST\",\n headers: buildHeaders(licenseKey),\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n await response.json();\n}\n\nasync function buildPlayerMetricEvent(\n licenseKey: string | undefined,\n context: PlayerAnalyticsContext = {},\n flags: PlayerMetricFlags = {}\n): Promise<Record<string, unknown>> {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n const captureAt = flags.captureAt ?? new Date().toISOString();\n\n return {\n player_id: browserId,\n browserId,\n device_type: clientInfo.deviceType,\n deviceType: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: flags.adLoaded,\n ad_detect: flags.adDetect,\n license_key: licenseKey,\n capture_at: captureAt,\n timestamp: captureAt,\n };\n}\n\nexport async function sendInitialTracking(\n licenseKey?: string,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n const clientInfo = getClientInfo();\n const browserId = await getBrowserID(clientInfo);\n\n const trackingData: TrackingData = {\n browserId,\n ...clientInfo,\n };\n\n await sendTrackRequest(licenseKey, {\n events: [\n {\n player_id: browserId,\n device_type: clientInfo.deviceType,\n input_stream_type: context.inputStreamType,\n os: clientInfo.os,\n ad_loaded: false,\n ad_detect: false,\n license_key: licenseKey,\n capture_at: new Date().toISOString(),\n },\n ],\n trackingData,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending initial tracking data:\",\n error\n );\n }\n}\n\nexport async function sendAdDetectTracking(\n licenseKey: string | undefined,\n adDetectInfo: AdDetectInfo,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n await sendHeartbeat(licenseKey, context, {\n adDetect: true,\n captureAt: adDetectInfo.timestamp,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad detect tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdLoadedTracking(\n licenseKey: string | undefined,\n adLoadedInfo: AdLoadedInfo,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n await sendHeartbeat(licenseKey, context, {\n adLoaded: true,\n captureAt: adLoadedInfo.timestamp,\n });\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad loaded tracking:\",\n error\n );\n }\n}\n\nexport async function sendAdImpressionTracking(\n licenseKey: string | undefined,\n adImpressionInfo: AdImpressionInfo,\n context: PlayerAnalyticsContext = {}\n): Promise<void> {\n try {\n const metricEvent = await buildPlayerMetricEvent(licenseKey, context, {\n captureAt: adImpressionInfo.timestamp,\n });\n await Promise.all([\n postJson(HEARTBEAT_URL, licenseKey, metricEvent),\n postJson(IMPRESSIONS_URL, licenseKey, {\n events: [\n {\n player_id: metricEvent.player_id,\n ad_played_count: 1,\n ad_url: adImpressionInfo.adUrl,\n license_key: licenseKey,\n capture_at: adImpressionInfo.timestamp,\n },\n ],\n }),\n ]);\n } catch (error) {\n console.error(\n \"[StormcloudVideoPlayer] Error sending ad impression tracking:\",\n error\n );\n }\n}\n\nexport async function sendHeartbeat(\n licenseKey?: string,\n context: PlayerAnalyticsContext = {},\n flags: PlayerMetricFlags = {}\n): Promise<void> {\n try {\n const heartbeatData = await buildPlayerMetricEvent(\n licenseKey,\n context,\n flags\n );\n await postJson(HEARTBEAT_URL, licenseKey, heartbeatData);\n } catch (error) {\n console.error(\"[StormcloudVideoPlayer] Error sending heartbeat:\", error);\n }\n}\n"]}
|