unified-video-framework 1.4.196 → 1.4.198
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.
|
@@ -238,6 +238,10 @@ export class WebPlayer extends BasePlayer {
|
|
|
238
238
|
this.video.playsInline = this.config.playsInline ?? true;
|
|
239
239
|
this.video.preload = this.config.preload ?? 'metadata';
|
|
240
240
|
|
|
241
|
+
// Enable AirPlay for iOS devices
|
|
242
|
+
(this.video as any).webkitAllowsAirPlay = true;
|
|
243
|
+
this.video.setAttribute('x-webkit-airplay', 'allow');
|
|
244
|
+
|
|
241
245
|
if (this.config.crossOrigin) {
|
|
242
246
|
this.video.crossOrigin = this.config.crossOrigin;
|
|
243
247
|
}
|
|
@@ -938,6 +942,8 @@ export class WebPlayer extends BasePlayer {
|
|
|
938
942
|
try {
|
|
939
943
|
await this.play();
|
|
940
944
|
this.debugLog('✅ Muted autoplay successful');
|
|
945
|
+
// Show YouTube-style unmute button instead of blocking overlay
|
|
946
|
+
this.showUnmuteButton();
|
|
941
947
|
return true;
|
|
942
948
|
} catch (error) {
|
|
943
949
|
this.debugLog('❌ Muted autoplay failed');
|
|
@@ -1133,6 +1139,129 @@ export class WebPlayer extends BasePlayer {
|
|
|
1133
1139
|
}
|
|
1134
1140
|
}
|
|
1135
1141
|
|
|
1142
|
+
/**
|
|
1143
|
+
* Show YouTube-style unmute button when video autoplays muted
|
|
1144
|
+
*/
|
|
1145
|
+
private showUnmuteButton(): void {
|
|
1146
|
+
// Remove existing unmute button
|
|
1147
|
+
this.hideUnmuteButton();
|
|
1148
|
+
|
|
1149
|
+
this.debugLog('🔇 Showing unmute button - video autoplaying muted');
|
|
1150
|
+
|
|
1151
|
+
const unmuteBtn = document.createElement('button');
|
|
1152
|
+
unmuteBtn.id = 'uvf-unmute-btn';
|
|
1153
|
+
unmuteBtn.className = 'uvf-unmute-btn';
|
|
1154
|
+
unmuteBtn.setAttribute('aria-label', 'Tap to unmute');
|
|
1155
|
+
unmuteBtn.innerHTML = `
|
|
1156
|
+
<svg viewBox="0 0 24 24" class="uvf-unmute-icon">
|
|
1157
|
+
<path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/>
|
|
1158
|
+
</svg>
|
|
1159
|
+
<span class="uvf-unmute-text">Tap to unmute</span>
|
|
1160
|
+
`;
|
|
1161
|
+
|
|
1162
|
+
// Click handler to unmute
|
|
1163
|
+
unmuteBtn.addEventListener('click', (e) => {
|
|
1164
|
+
e.stopPropagation();
|
|
1165
|
+
if (this.video) {
|
|
1166
|
+
this.video.muted = false;
|
|
1167
|
+
this.debugLog('🔊 Video unmuted by user');
|
|
1168
|
+
this.hideUnmuteButton();
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
|
|
1172
|
+
// Add enhanced styles
|
|
1173
|
+
const style = document.createElement('style');
|
|
1174
|
+
style.textContent = `
|
|
1175
|
+
.uvf-unmute-btn {
|
|
1176
|
+
position: absolute !important;
|
|
1177
|
+
bottom: 80px !important;
|
|
1178
|
+
left: 20px !important;
|
|
1179
|
+
z-index: 1000 !important;
|
|
1180
|
+
display: flex !important;
|
|
1181
|
+
align-items: center !important;
|
|
1182
|
+
gap: 8px !important;
|
|
1183
|
+
padding: 12px 16px !important;
|
|
1184
|
+
background: rgba(0, 0, 0, 0.8) !important;
|
|
1185
|
+
border: none !important;
|
|
1186
|
+
border-radius: 4px !important;
|
|
1187
|
+
color: white !important;
|
|
1188
|
+
font-size: 14px !important;
|
|
1189
|
+
font-weight: 500 !important;
|
|
1190
|
+
cursor: pointer !important;
|
|
1191
|
+
transition: all 0.2s ease !important;
|
|
1192
|
+
backdrop-filter: blur(10px) !important;
|
|
1193
|
+
-webkit-backdrop-filter: blur(10px) !important;
|
|
1194
|
+
animation: uvf-unmute-pulse 2s ease-in-out infinite !important;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
.uvf-unmute-btn:hover {
|
|
1198
|
+
background: rgba(0, 0, 0, 0.9) !important;
|
|
1199
|
+
transform: scale(1.05) !important;
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
.uvf-unmute-btn:active {
|
|
1203
|
+
transform: scale(0.95) !important;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
.uvf-unmute-icon {
|
|
1207
|
+
width: 20px !important;
|
|
1208
|
+
height: 20px !important;
|
|
1209
|
+
fill: white !important;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
.uvf-unmute-text {
|
|
1213
|
+
white-space: nowrap !important;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
@keyframes uvf-unmute-pulse {
|
|
1217
|
+
0%, 100% {
|
|
1218
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3) !important;
|
|
1219
|
+
}
|
|
1220
|
+
50% {
|
|
1221
|
+
box-shadow: 0 2px 16px rgba(255, 255, 255, 0.2) !important;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
/* Mobile responsive */
|
|
1226
|
+
@media (max-width: 767px) {
|
|
1227
|
+
.uvf-unmute-btn {
|
|
1228
|
+
bottom: 70px !important;
|
|
1229
|
+
left: 50% !important;
|
|
1230
|
+
transform: translateX(-50%) !important;
|
|
1231
|
+
padding: 10px 14px !important;
|
|
1232
|
+
font-size: 13px !important;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
.uvf-unmute-btn:hover {
|
|
1236
|
+
transform: translateX(-50%) scale(1.05) !important;
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
`;
|
|
1240
|
+
|
|
1241
|
+
// Add to page if not already added
|
|
1242
|
+
if (!document.getElementById('uvf-unmute-styles')) {
|
|
1243
|
+
style.id = 'uvf-unmute-styles';
|
|
1244
|
+
document.head.appendChild(style);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
// Add to player
|
|
1248
|
+
if (this.playerWrapper) {
|
|
1249
|
+
this.playerWrapper.appendChild(unmuteBtn);
|
|
1250
|
+
this.debugLog('✅ Unmute button added to player');
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* Hide unmute button
|
|
1256
|
+
*/
|
|
1257
|
+
private hideUnmuteButton(): void {
|
|
1258
|
+
const unmuteBtn = document.getElementById('uvf-unmute-btn');
|
|
1259
|
+
if (unmuteBtn) {
|
|
1260
|
+
unmuteBtn.remove();
|
|
1261
|
+
this.debugLog('Unmute button removed');
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1136
1265
|
private updateTimeTooltip(e: MouseEvent): void {
|
|
1137
1266
|
const progressBar = document.getElementById('uvf-progress-bar');
|
|
1138
1267
|
const tooltip = document.getElementById('uvf-time-tooltip');
|
|
@@ -3845,9 +3974,19 @@ export class WebPlayer extends BasePlayer {
|
|
|
3845
3974
|
}
|
|
3846
3975
|
|
|
3847
3976
|
.uvf-top-btn:hover {
|
|
3977
|
+
width: 40px;
|
|
3978
|
+
height: 40px;
|
|
3979
|
+
backdrop-filter: blur(10px);
|
|
3980
|
+
border: 1px solid rgba(255,255,255,0.2);
|
|
3981
|
+
border-radius: 50%;
|
|
3848
3982
|
background: rgba(255,255,255,0.2);
|
|
3849
3983
|
transform: scale(1.1);
|
|
3850
3984
|
box-shadow: 0 0 20px rgba(255,255,255,0.3);
|
|
3985
|
+
cursor: pointer;
|
|
3986
|
+
display: flex;
|
|
3987
|
+
align-items: center;
|
|
3988
|
+
justify-content: center;
|
|
3989
|
+
transition: all 0.3s ease;
|
|
3851
3990
|
}
|
|
3852
3991
|
|
|
3853
3992
|
.uvf-top-btn.cast-grey {
|
|
@@ -4112,18 +4251,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4112
4251
|
height: 24px;
|
|
4113
4252
|
}
|
|
4114
4253
|
|
|
4115
|
-
.uvf-player-wrapper.uvf-fullscreen .uvf-top-btn {
|
|
4116
|
-
width: 40px;
|
|
4117
|
-
height: 40px;
|
|
4118
|
-
min-width: 40px;
|
|
4119
|
-
min-height: 40px;
|
|
4120
|
-
}
|
|
4121
|
-
|
|
4122
|
-
.uvf-player-wrapper.uvf-fullscreen .uvf-top-btn svg {
|
|
4123
|
-
width: 20px;
|
|
4124
|
-
height: 20px;
|
|
4125
|
-
}
|
|
4126
|
-
|
|
4127
4254
|
.uvf-player-wrapper.uvf-fullscreen .uvf-time-display {
|
|
4128
4255
|
font-size: 14px;
|
|
4129
4256
|
padding: 0 10px;
|
|
@@ -4240,11 +4367,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4240
4367
|
display: flex !important;
|
|
4241
4368
|
}
|
|
4242
4369
|
|
|
4243
|
-
.uvf-top-btn {
|
|
4244
|
-
display: flex !important;
|
|
4245
|
-
border-radius: 50% !important;
|
|
4246
|
-
}
|
|
4247
|
-
|
|
4248
4370
|
/* Show top bar when controls are visible or on hover */
|
|
4249
4371
|
.uvf-player-wrapper:hover .uvf-top-bar,
|
|
4250
4372
|
.uvf-player-wrapper.controls-visible .uvf-top-bar {
|
|
@@ -4348,18 +4470,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4348
4470
|
gap: 6px !important;
|
|
4349
4471
|
}
|
|
4350
4472
|
|
|
4351
|
-
.uvf-top-btn {
|
|
4352
|
-
width: 40px;
|
|
4353
|
-
height: 40px;
|
|
4354
|
-
min-width: 40px;
|
|
4355
|
-
min-height: 40px;
|
|
4356
|
-
}
|
|
4357
|
-
|
|
4358
|
-
.uvf-top-btn svg {
|
|
4359
|
-
width: 18px;
|
|
4360
|
-
height: 18px;
|
|
4361
|
-
}
|
|
4362
|
-
|
|
4363
4473
|
/* Title bar within top bar - landscape */
|
|
4364
4474
|
.uvf-top-bar .uvf-title-bar {
|
|
4365
4475
|
padding: 0;
|
|
@@ -4445,19 +4555,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4445
4555
|
height: 23px;
|
|
4446
4556
|
}
|
|
4447
4557
|
|
|
4448
|
-
/* Tablet top controls */
|
|
4449
|
-
.uvf-top-btn {
|
|
4450
|
-
width: 42px;
|
|
4451
|
-
height: 42px;
|
|
4452
|
-
min-width: 42px;
|
|
4453
|
-
min-height: 42px;
|
|
4454
|
-
}
|
|
4455
|
-
|
|
4456
|
-
.uvf-top-btn svg {
|
|
4457
|
-
width: 19px;
|
|
4458
|
-
height: 19px;
|
|
4459
|
-
}
|
|
4460
|
-
|
|
4461
4558
|
/* Top bar for tablet */
|
|
4462
4559
|
.uvf-top-bar {
|
|
4463
4560
|
padding: 16px;
|
|
@@ -4596,23 +4693,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4596
4693
|
height: 24px;
|
|
4597
4694
|
}
|
|
4598
4695
|
|
|
4599
|
-
/* Enhanced top controls */
|
|
4600
|
-
.uvf-top-btn {
|
|
4601
|
-
width: 40px;
|
|
4602
|
-
height: 40px;
|
|
4603
|
-
transition: all 0.2s cubic-bezier(0.4, 0.0, 0.2, 1);
|
|
4604
|
-
}
|
|
4605
|
-
|
|
4606
|
-
.uvf-top-btn:hover {
|
|
4607
|
-
transform: scale(1.1);
|
|
4608
|
-
background: var(--uvf-overlay-medium);
|
|
4609
|
-
}
|
|
4610
|
-
|
|
4611
|
-
.uvf-top-btn svg {
|
|
4612
|
-
width: 20px;
|
|
4613
|
-
height: 20px;
|
|
4614
|
-
}
|
|
4615
|
-
|
|
4616
4696
|
/* Top bar for desktop 1024px+ */
|
|
4617
4697
|
.uvf-top-bar {
|
|
4618
4698
|
padding: 20px;
|
|
@@ -4732,16 +4812,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4732
4812
|
height: 28px;
|
|
4733
4813
|
}
|
|
4734
4814
|
|
|
4735
|
-
.uvf-top-btn {
|
|
4736
|
-
width: 44px;
|
|
4737
|
-
height: 44px;
|
|
4738
|
-
}
|
|
4739
|
-
|
|
4740
|
-
.uvf-top-btn svg {
|
|
4741
|
-
width: 22px;
|
|
4742
|
-
height: 22px;
|
|
4743
|
-
}
|
|
4744
|
-
|
|
4745
4815
|
.uvf-center-play-btn {
|
|
4746
4816
|
width: clamp(64px, 10vw, 76px);
|
|
4747
4817
|
height: clamp(64px, 10vw, 76px);
|
|
@@ -4782,8 +4852,7 @@ export class WebPlayer extends BasePlayer {
|
|
|
4782
4852
|
/* High-DPI display optimizations */
|
|
4783
4853
|
@media screen and (-webkit-min-device-pixel-ratio: 2),
|
|
4784
4854
|
screen and (min-resolution: 192dpi) {
|
|
4785
|
-
.uvf-control-btn
|
|
4786
|
-
.uvf-top-btn {
|
|
4855
|
+
.uvf-control-btn {
|
|
4787
4856
|
image-rendering: -webkit-optimize-contrast;
|
|
4788
4857
|
image-rendering: crisp-edges;
|
|
4789
4858
|
}
|
|
@@ -4800,7 +4869,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4800
4869
|
/* Reduced motion accessibility */
|
|
4801
4870
|
@media (prefers-reduced-motion: reduce) {
|
|
4802
4871
|
.uvf-control-btn,
|
|
4803
|
-
.uvf-top-btn,
|
|
4804
4872
|
.uvf-center-play-btn,
|
|
4805
4873
|
.uvf-progress-handle,
|
|
4806
4874
|
.uvf-volume-slider,
|
|
@@ -4809,7 +4877,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4809
4877
|
}
|
|
4810
4878
|
|
|
4811
4879
|
.uvf-control-btn:hover,
|
|
4812
|
-
.uvf-top-btn:hover,
|
|
4813
4880
|
.uvf-center-play-btn:hover {
|
|
4814
4881
|
transform: none !important;
|
|
4815
4882
|
}
|
|
@@ -4835,11 +4902,6 @@ export class WebPlayer extends BasePlayer {
|
|
|
4835
4902
|
border-radius: 50%
|
|
4836
4903
|
}
|
|
4837
4904
|
|
|
4838
|
-
.uvf-top-btn {
|
|
4839
|
-
min-width: 44px;
|
|
4840
|
-
min-height: 44px;
|
|
4841
|
-
}
|
|
4842
|
-
|
|
4843
4905
|
.uvf-progress-bar {
|
|
4844
4906
|
height: 3px;
|
|
4845
4907
|
}
|
|
@@ -4858,22 +4920,21 @@ export class WebPlayer extends BasePlayer {
|
|
|
4858
4920
|
background: var(--uvf-overlay-medium);
|
|
4859
4921
|
transform: scale(0.95);
|
|
4860
4922
|
}
|
|
4861
|
-
|
|
4862
|
-
.uvf-top-btn:active {
|
|
4863
|
-
background: var(--uvf-overlay-medium);
|
|
4864
|
-
transform: scale(0.95);
|
|
4865
|
-
}
|
|
4866
4923
|
}
|
|
4867
4924
|
|
|
4868
4925
|
/* Keyboard navigation and accessibility */
|
|
4869
4926
|
.uvf-control-btn:focus-visible,
|
|
4870
|
-
.uvf-top-btn:focus-visible,
|
|
4871
4927
|
.uvf-center-play-btn:focus-visible {
|
|
4872
4928
|
outline: 2px solid var(--uvf-primary-color, #007bff);
|
|
4873
4929
|
outline-offset: 2px;
|
|
4874
4930
|
background: var(--uvf-overlay-medium);
|
|
4875
4931
|
}
|
|
4876
4932
|
|
|
4933
|
+
.uvf-top-btn:focus-visible {
|
|
4934
|
+
outline: 2px solid var(--uvf-primary-color, #007bff);
|
|
4935
|
+
outline-offset: 2px;
|
|
4936
|
+
}
|
|
4937
|
+
|
|
4877
4938
|
.uvf-progress-bar-wrapper:focus-visible {
|
|
4878
4939
|
outline: 2px solid var(--uvf-primary-color, #007bff);
|
|
4879
4940
|
outline-offset: 2px;
|
|
@@ -4905,7 +4966,10 @@ export class WebPlayer extends BasePlayer {
|
|
|
4905
4966
|
|
|
4906
4967
|
/* High contrast mode support */
|
|
4907
4968
|
@media (prefers-contrast: high) {
|
|
4908
|
-
.uvf-control-btn
|
|
4969
|
+
.uvf-control-btn {
|
|
4970
|
+
border: 1px solid;
|
|
4971
|
+
}
|
|
4972
|
+
|
|
4909
4973
|
.uvf-top-btn {
|
|
4910
4974
|
border: 1px solid;
|
|
4911
4975
|
}
|
|
@@ -5692,6 +5756,8 @@ export class WebPlayer extends BasePlayer {
|
|
|
5692
5756
|
} else {
|
|
5693
5757
|
volumeIcon.style.display = 'block';
|
|
5694
5758
|
muteIcon.style.display = 'none';
|
|
5759
|
+
// Hide unmute button when video is unmuted
|
|
5760
|
+
this.hideUnmuteButton();
|
|
5695
5761
|
}
|
|
5696
5762
|
}
|
|
5697
5763
|
});
|
|
@@ -5868,6 +5934,17 @@ export class WebPlayer extends BasePlayer {
|
|
|
5868
5934
|
const stopCastBtn = document.getElementById('uvf-stop-cast-btn');
|
|
5869
5935
|
const shareBtn = document.getElementById('uvf-share-btn');
|
|
5870
5936
|
|
|
5937
|
+
// Update cast button icon and functionality for iOS (AirPlay)
|
|
5938
|
+
if (this.isIOSDevice() && castBtn) {
|
|
5939
|
+
castBtn.innerHTML = `
|
|
5940
|
+
<svg viewBox="0 0 24 24">
|
|
5941
|
+
<path d="M1 18h6v-2H1v2zm0-4h12v-2H1v2zm16.5 4.5c-1.25 0-2.45-.5-3.35-1.41L12 18.5l2.09 2.09c1.8 1.8 4.72 1.8 6.52 0 1.8-1.8 1.8-4.72 0-6.52L12 5.5 3.39 14.11c-1.8 1.8-1.8 4.72 0 6.52.9.9 2.1 1.41 3.35 1.41l6.76-6.76M12 7.91l6.89 6.89c.78.78.78 2.05 0 2.83-.78.78-2.05.78-2.83 0L12 13.57 7.94 17.63c-.78.78-2.05.78-2.83 0-.78-.78-.78-2.05 0-2.83L12 7.91z"/>
|
|
5942
|
+
</svg>
|
|
5943
|
+
`;
|
|
5944
|
+
castBtn.setAttribute('title', 'AirPlay');
|
|
5945
|
+
castBtn.setAttribute('aria-label', 'AirPlay');
|
|
5946
|
+
}
|
|
5947
|
+
|
|
5871
5948
|
castBtn?.addEventListener('click', () => this.onCastButtonClick());
|
|
5872
5949
|
stopCastBtn?.addEventListener('click', () => this.stopCasting());
|
|
5873
5950
|
shareBtn?.addEventListener('click', () => this.shareVideo());
|
|
@@ -8211,6 +8288,13 @@ export class WebPlayer extends BasePlayer {
|
|
|
8211
8288
|
}
|
|
8212
8289
|
|
|
8213
8290
|
private onCastButtonClick(): void {
|
|
8291
|
+
// On iOS, use AirPlay instead of Google Cast
|
|
8292
|
+
if (this.isIOSDevice()) {
|
|
8293
|
+
this.showAirPlayPicker();
|
|
8294
|
+
return;
|
|
8295
|
+
}
|
|
8296
|
+
|
|
8297
|
+
// Google Cast for non-iOS devices
|
|
8214
8298
|
try {
|
|
8215
8299
|
const castNs = (window as any).cast;
|
|
8216
8300
|
if (this.isCasting && castNs && castNs.framework) {
|
|
@@ -8222,6 +8306,31 @@ export class WebPlayer extends BasePlayer {
|
|
|
8222
8306
|
// Not casting yet
|
|
8223
8307
|
this.initCast();
|
|
8224
8308
|
}
|
|
8309
|
+
|
|
8310
|
+
/**
|
|
8311
|
+
* Show AirPlay picker for iOS devices
|
|
8312
|
+
*/
|
|
8313
|
+
private showAirPlayPicker(): void {
|
|
8314
|
+
if (!this.video) {
|
|
8315
|
+
this.showNotification('Video not ready');
|
|
8316
|
+
return;
|
|
8317
|
+
}
|
|
8318
|
+
|
|
8319
|
+
// Check if AirPlay is supported
|
|
8320
|
+
const videoElement = this.video as any;
|
|
8321
|
+
if (typeof videoElement.webkitShowPlaybackTargetPicker === 'function') {
|
|
8322
|
+
try {
|
|
8323
|
+
videoElement.webkitShowPlaybackTargetPicker();
|
|
8324
|
+
this.debugLog('AirPlay picker shown');
|
|
8325
|
+
} catch (error) {
|
|
8326
|
+
this.debugWarn('Failed to show AirPlay picker:', (error as Error).message);
|
|
8327
|
+
this.showNotification('AirPlay not available');
|
|
8328
|
+
}
|
|
8329
|
+
} else {
|
|
8330
|
+
this.debugWarn('AirPlay not supported on this device');
|
|
8331
|
+
this.showNotification('AirPlay not supported');
|
|
8332
|
+
}
|
|
8333
|
+
}
|
|
8225
8334
|
|
|
8226
8335
|
private stopCasting(): void {
|
|
8227
8336
|
try {
|