@vkontakte/videoplayer-statistics 1.0.83 → 1.0.84-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es2015.cjs.js +4 -4
- package/es2015.esm.js +4 -4
- package/es2018.cjs.js +4 -4
- package/es2018.esm.js +4 -4
- package/es2024.cjs.js +4 -4
- package/es2024.esm.js +4 -4
- package/esnext.cjs.js +4 -4
- package/esnext.esm.js +4 -4
- package/evergreen.esm.js +4 -4
- package/package.json +3 -3
- package/types/ShareVSID.d.ts +6 -0
- package/types/oneStat/OneStat.d.ts +5 -1
- package/types/oneStat/utils/mappers.d.ts +1 -1
- package/types/oneStat/values.d.ts +3 -1
- package/types/thinOneStat/ThinOneStat.d.ts +100 -6
- package/types/thinOneStat/{uiEvents.d.ts → events.d.ts} +7 -0
- package/types/thinOneStat/index.d.ts +1 -1
- package/types/thinOneStat/utils/mappers.d.ts +4 -3
- package/types/thinOneStat/utils/watchCoverage.d.ts +2 -1
- package/types/thinOneStat/utils/watchedN.d.ts +2 -1
- package/types/thinOneStat/values.d.ts +11 -2
package/evergreen.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vkontakte/videoplayer-statistics v1.0.
|
|
3
|
-
*
|
|
4
|
-
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-
|
|
2
|
+
* @vkontakte/videoplayer-statistics v1.0.84-beta.0
|
|
3
|
+
* Thu, 14 Aug 2025 12:56:02 GMT
|
|
4
|
+
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-84/doc/
|
|
5
5
|
*/
|
|
6
|
-
var Tt=Object.defineProperty;var xt=(s,e)=>{for(var i in e)Tt(s,i,{get:e[i],enumerable:!0})};var R=(a=>(a.PROD="prod",a.VK_ALIAS="vk_alias",a.VIDEOTEST="videotest",a.TEST="test",a.OKCDN="okcdn",a.AUTO="auto",a))(R||{}),re=(c=>(c.Q144P="mobile",c.Q240P="lowest",c.Q360P="low",c.Q480P="medium",c.Q720P="high",c.Q1080P="fullhd",c.Q1440P="quadhd",c.Q2160P="ultrahd",c.UNKNOWN="unknown",c))(re||{}),se=(u=>(u.MP4="mp4",u.DASH="dash",u.DASH_SEP="dash_sep",u.ONDEMAND_DASH="ondemand_dash",u.HLS="hls",u.ONDEMAND_HLS="ondemand_hls",u.WEBM="webm",u.AV1="av1",u.ONDEMAND_DASH_LIVE="ondemand_dash_live",u.ONDEMAND_HLS_LIVE="ondemand_hls_live",u.WEBRTC="webrtc",u.UNKNOWN="unknown",u.RTMP="rtmp",u))(se||{});var ae=(t=>(t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3",t))(ae||{});var ne=(n=>(n.SLIDER="slider",n.DOUBLE_TAP="double_tap",n.TIME_CODE="time_code",n.EPISODE="episode",n.REWIND="rewind",n.LIVE="live",n.UNKNOWN="unknown",n))(ne||{}),xe=(r=>(r.GRAPH_SHOW="iGraphShow",r.GRAPH_HIDE="iGraphHide",r.NEXT_AREA="iNextChapterArea",r.NEXT_BUTTON="iNextChapterBtn",r.WATCH_AGAIN="iWatchAgainBtn",r))(xe||{}),ke={action_play:"ap",action_play_interactive:"api",first_bytes:"fb",player_ready:"pr",first_frame:"ff",seek:"sk",watch_coverage_record:"wr",watch_coverage_live:"wl",empty_buffer:"eb",action_stop:"as",close_at_empty_buffer:"cb",content_error:"er",player_interface_click:"pc",next_movie:"nm",track_switch:"ts",failover:"fo",quality:"qt"},Le={vsid:"si",isid:"is",vid:"vi",place:"pl",quality:"qt",cdn_host:"ch",stat_type:"st",param:"pm",vk_app_id:"va",track_code:"tc",connection_type:"cnt",connection_reused:"cr",cached_data:"cd",live:"lv",muted:"mu",mode:"mo",subtitles:"sb",failover:"fo",download_speed:"ds",manual_quality:"mq",ref_domain:"rd",direct_url:"du"},Ce={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},$e={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"};import{fillWithDefault as kt}from"@vkontakte/videoplayer-shared/evergreen";var De="CIOPGQJGDIHBABABA",de={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var Lt={apiEnv:"vk_alias",apiKey:De,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:["quality"],disabledCustomFields:[],shorten:!0,maxLoops:100,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,clearStorageAtUnload:!0,useVKComIsMobileLogic:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1},useKeepalive:!1},Ne=s=>kt(s,Lt);function ce(){let s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=s[o===19?t&3|8:t]);return e.join("")}import{assertNonNullable as Wt,combine as Qe,fromEvent as je,isNonNullable as D,isNullable as Ge,merge as Kt,now as x,observableFrom as qt,once as zt,safeStorage as Ye,Subject as Qt,Subscription as be,ValueSubject as z,createURL as Xe}from"@vkontakte/videoplayer-shared/evergreen";import{Logger as jt,detectEmbed as Gt}from"@vkontakte/videoplayer-shared/evergreen";var Oe=s=>{let{operation:e,custom:i}=s,t=Object.fromEntries(Object.entries(i).map(([o,r])=>{let a=Le[o]??o,n=r;return r&&(o==="mode"?n=$e[r]??r:o==="quality"&&(n=Ce[r]??r)),[a,n]}));return{...s,operation:ke[e]??e,custom:t}};var P="1.0.83";import{ValueSubject as Ct,getExponentialDelay as $t,ErrorCategory as C}from"@vkontakte/videoplayer-shared/evergreen";var Dt=/Mobile|mini|Fennec|Android|iP(ad|od|hone)|opera (mini|mobi)/i,V=class{constructor(e){this.consequentAuthErrors=0;this.authorized$=new Ct(!1);this.params=e}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;let r=async(a,n=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,o)}catch(l){if(!l||!("error_code"in l)){this.params.error$.next({id:"logRequestUnknown",category:C.NETWORK,message:`Unknown ${i} error`,thrown:l});return}let c=l?.error_code;switch(c){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),n>0?r(a,n-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),n>0?r(a,n-1):void 0;default:{this.params.error$.next({id:`LogRequest#${c}`,category:C.EXTERNAL_API,message:`${i} error`,data:l});return}}}};return r(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){let i="WEB",t=!1,o=`@vkontakte/videoplayer-statistics:${P}`;if(this.params.config.useVKComIsMobileLogic){let{appVersion:r}=window.navigator;t=Dt.test(r)}else this.params.mobile&&(t=!0);return t&&(i="M_WEB"),this.params.vktvVersion&&(i="SMART_TV",o=this.params.vktvVersion),{collector:"ok.mobile.apps.video",data:JSON.stringify({application:o,platform:i,items:this.params.config.shorten?e.map(Oe):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();let e=$t(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(t=>this.params.error$.next({id:"AuthorizeBackoff",category:C.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:P.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:C.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:C.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:C.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{ErrorCategory as B,now as ue}from"@vkontakte/videoplayer-shared/evergreen";var M=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=de[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:B.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),de.vk_alias}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this._prepareQueryParams({method:e,queryParams:i,sessionKey:t}),r=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,r)}catch(a){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:B.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t){let o=ue(),r=n=>{if(n instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(n.message)){this.params.error$.next({id:"Network",category:B.NETWORK,message:"Request failed",thrown:n});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:B.NETWORK,message:"Unhandled request error",thrown:n,data:{method:e,params:i,sessionKey:t,time:ue()-o}})};this.apiBaseUrl=await this.resolveApiBaseUrl();let a={method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:t})};return this.params.config.useKeepalive&&(a.keepalive=!0),fetch(`${this.apiBaseUrl}/fb.do`,a).then(n=>{let l=Number(n.headers.get("content-length"))===0,c=new Date(n.headers.get("date")??"").getTime(),h=ue()-o;if(isFinite(c)&&this.timeSynchronisation?.addServerTime(c,h),!l)return n.json().then(p=>Object.prototype.hasOwnProperty.call(p,"error_msg")?Promise.reject(p):p,r)},r)}_prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as Nt,now as Ot,safeStorage as U,debounceFn as Re}from"@vkontakte/videoplayer-shared/evergreen";var H="onestat_events",le=s=>e=>e.timestamp+s>=Ot(),W=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{operation:i}=e;return["action_play","watch_coverage_record","watch_coverage_live"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=Re(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=U.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Re(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:Nt.WTF,message:e?String(e):"Unknown logger error",thrown:e})}}readFromStorage(){let e=U.get(H);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(le(this.params.config.storageExpiration));U.set(H,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(le(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],U.set(H,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(le(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}U.set(H,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.custom.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};import{HttpConnectionType as he,Surface as $,VideoFormat as v,VideoQuality as _}from"@vkontakte/videoplayer-core/evergreen";import{assertNever as Ve}from"@vkontakte/videoplayer-shared/evergreen";var Me=s=>s&&{[_.INVARIANT]:"unknown",[_.Q_144P]:"mobile",[_.Q_240P]:"lowest",[_.Q_360P]:"low",[_.Q_480P]:"medium",[_.Q_576P]:"unknown",[_.Q_720P]:"high",[_.Q_1080P]:"fullhd",[_.Q_1440P]:"quadhd",[_.Q_2160P]:"ultrahd",[_.Q_4320P]:"unknown"}[s],pe=s=>s&&{[he.HTTP1]:"http1",[he.HTTP2]:"http2",[he.QUIC]:"http3"}[s],Ue=s=>{if(s!==void 0)switch(s){case v.MPEG:return"mp4";case v.DASH:case v.DASH_LIVE:case v.DASH_STREAMS:return"dash";case v.DASH_SEP:return"dash_sep";case v.DASH_ONDEMAND:return"ondemand_dash";case v.DASH_WEBM:case v.DASH_LIVE_WEBM:return"webm";case v.DASH_WEBM_AV1:return"av1";case v.DASH_LIVE_CMAF:return"ondemand_dash_live";case v.HLS:case v.HLS_LIVE:return"hls";case v.HLS_ONDEMAND:return"ondemand_hls";case v.HLS_LIVE_CMAF:return"ondemand_hls_live";case v.WEB_RTC_LIVE:return"webrtc";default:return Ve(s)}},K=s=>{if(s!==void 0)switch(s){case $.NONE:case $.INLINE:return;case $.FULLSCREEN:return"fullscreen";case $.SECOND_SCREEN:return"chromecast";case $.PIP:return"pip";case $.INVISIBLE:return"invisible";default:return Ve(s)}},Fe=s=>{switch(s){case"slow-2g":return"poor";case"2g":return"poor";case"3g":return"good";case"4g":return"excellent"}};var q=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};var Be=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(7,"0"),He=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");import{PlaybackState as We}from"@vkontakte/videoplayer-core/evergreen";import{filter as Ke,filterChanged as Vt,fromEvent as Mt,isNullable as qe,map as Ut,merge as fe,Observable as Ft,Subject as ge,Subscription as Bt,ValueSubject as Ht}from"@vkontakte/videoplayer-shared/evergreen";var ze=(s,e)=>new Ft(i=>{let t=new Bt,o=fe(Mt(window,"beforeunload"),s.events.willDestruct$),r=new Ht(void 0),a;t.add(s.info.isLive$.pipe(Vt()).subscribe(g=>{a&&(a.unsubscribe(),r.next(void 0)),g?a=s.info.liveTime$.pipe(Ut(y=>y&&y/1e3)).subscribe(r):a=s.info.position$.subscribe(r),t.add(a)}));let{playing$:n,paused$:l}=s.events,c=s.events.willSeek$.pipe(Ke(()=>s.info.playbackState$.getValue()===We.PLAYING)),h=s.events.seeked$.pipe(Ke(()=>s.info.playbackState$.getValue()===We.PLAYING)),p=!1,d=new ge;t.add(c.subscribe(()=>{p||d.next(),p=!0})),t.add(h.subscribe(()=>p=!1));let u=new ge,m=new ge,f=fe(n,h,u),I=fe(l,d,o,s.events.looped$,m),S,A=()=>S=r.getValue(),w=()=>{let g=r.getValue();qe(S)||S===g||qe(g)||(i.next({from:S,to:g}),S=void 0)},T=()=>{m.next(),u.next()};if(t.add(f.subscribe(A)),t.add(I.subscribe(w)),e.forceInterval&&isFinite(e.forceInterval)){let g=0;t.add(f.subscribe(()=>g=window.setTimeout(T,e.forceInterval))),t.add(I.subscribe(()=>window.clearTimeout(g)))}return t});var Yt="_one-stat_",Je=`${Yt}deviceId`,me=()=>{let s=new be;return{subscription:s,subscribe:(e,i)=>{e&&s.add(e.subscribe(i))}}},ve=class{constructor(e,i){this.subscription=new be;this.debugLogger=new jt;this.oneStatDebugLog=this.debugLogger.createComponentLog("onestat");this.loopCounter=0;this.disabled=!1;this.vsid$=new z(void 0);this.isid$=new z(void 0);this.zenUid$=new z(void 0);this.seekAction$=new z("unknown");this.statContext=e,this.config=Ne(i.config??{}),D(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new q);let t=new Qt;this.experimental={error$:t};let o=Ye.get(Je);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=ce(),Ye.set(Je,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??He()),this.zenUid$.next(i.zenUid);let r=new M({config:this.config,error$:t,timeSynchronisation:this.timeSynchronisation});this.api=new V({config:this.config,apiTransport:r,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,deviceId:this.deviceId,error$:t,vktvVersion:i.vktvVersion}),this.logger=new W({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:a,topOrigin:n}=Gt();this.isEmbed=a,this.embedParent=n?new URL(n).hostname:void 0,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new be,t=(d,u)=>i.add(d.subscribe(u));t(e.events.willStart$,()=>{let d=e.info.position$.getValue();this.logActionPlay({position:d}),this.statContext.projectId&&this.logActionPlayInteractive()}),t(e.events.looped$,()=>{this.resetViewSession(),++this.loopCounter>this.config.maxLoops&&(this.disabled=!0),this.logActionPlay({position:e.info.position$.getValue()})}),t(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next("unknown")}),t(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),t(e.events.willResume$,()=>{this.logPlay()}),t(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),t(e.events.playing$,()=>{this.logPlaying()}),t(ze(e,{forceInterval:this.config.watchCoverageInterval}),d=>{let u=e.info.isLive$.getValue(),m=e.info.atLiveEdge$.getValue(),f={start:parseFloat(d.from.toFixed(3)),end:parseFloat(d.to.toFixed(3))};if(m){let I=e.info.liveLatency$.getValue()??0,S=e.info.currentBuffer$.getValue()?.end??0,A=e.info.liveBufferTime$.getValue()??0,w=Math.round((I-(S-A))*1e3),T=Math.round(I*1e3);w&&T&&(f.latency=w,f.bufferLatency=T)}u?this.logWatchCoverageLive(f):this.logWatchCoverageRecord(f)});let o;t(e.info.isStalled$,d=>{d?o=x():(D(o)&&this.logEmptyBuffer({duration:x()-o}),o=void 0)});let r=!1;i.add(e.events.fatalError$.pipe(zt()).subscribe(()=>r=!0)),t(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){let u=D(o)?x()-o:void 0;this.logCloseAtEmptyBuffer({duration:u??0}),o=void 0}else r||this.logActionStop()}),t(e.events.managedError$,({id:d})=>{this.logError({fatal:!1,errorType:d})}),t(e.events.fatalError$,({id:d})=>{this.logError({fatal:!0,errorType:d})});let a,n,l=!1;t(e.events.firstBytes$,d=>{a=x(),this.logFirstBytes({time:d})}),t(e.events.willStart$,()=>n=x()),t(e.info.currentBuffer$,d=>{!l&&d&&d.end-d.start>0&&D(a)&&(this.logPlayerReady({duration:x()-a}),l=!0)}),t(e.events.firstFrame$,()=>{D(a)&&!l&&(this.logPlayerReady({duration:x()-a}),l=!0),D(n)&&this.logFirstFrame({time:x()-n})});let c;t(e.info.currentVideoStream$,d=>{d&&(c&&d.id!==c&&this.logTrackSwitch(d),c=d.id)});let h;t(e.info.currentAudioStream$,d=>{d&&(h&&d.id!==h&&this.logTrackSwitch(d),h=d.id)}),t(e.info.atLiveEdge$,d=>this.updateContext({liveEdge:d})),t(Qe({muted:e.info.muted$,volume:e.info.volume$}),({muted:d,volume:u})=>this.updateContext({audible:!d&&u>0})),t(e.info.currentQuality$,d=>{let u=Me(d);this.updateContext({quality:u}),u&&this.logQuality(u)}),t(e.info.isAutoQualityEnabled$,d=>this.updateContext({autoQuality:d})),t(e.info.currentFormat$,d=>this.updateContext({contentType:Ue(d)})),t(e.info.currentPlaybackRate$,d=>this.updateContext({rate:d})),t(e.info.is3DVideo$,d=>this.updateContext({is3d:d}));let p;return t(e.info.hostname$,d=>{let u=p!==void 0&&p!==d;this.updateContext({cdnHostname:d,failover:u}),u&&this.logFailover(d),p=d}),t(e.info.throughputEstimation$,d=>this.updateContext({downloadSpeed:d})),t(e.info.httpConnectionType$,d=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:pe(d)}),this.updateContext({connectionType:pe(d)})}),t(e.info.httpConnectionReused$,d=>{Ge(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:d}),this.updateContext({connectionReused:d})}),t(e.info.surface$,d=>this.updateContext({mode:K(d)})),t(Qe({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:d,available:u})=>{let m=u.find(({id:I})=>I===d),f=m&&(m.isAuto?`${m.language}_auto`:m.language);this.updateContext({subtitles:f?.split(".")[0]})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){this.uiEvents=e;let{subscription:i,subscribe:t}=me();return this.player&&(t(e.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),t(e.actionSeek$,this.seekAction$),t(e.inPiP$,o=>{let r=o?"pip":K(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),t(e.inFullscreen$,o=>{let r=o?"fullscreen":K(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),t(e.actionSetSubtitle$,o=>this.updateContext({subtitles:o.split(".")[0]})),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(e){let{subscription:i,subscribe:t}=me();return t(e.slotRequested$,()=>this.logAdSlotRequest()),t(e.started$,o=>this.logAdStarted(o)),t(e.paused$,()=>this.logAdPaused()),t(e.resumed$,()=>this.logAdResumed()),t(e.ended$,()=>this.logAdEnded()),t(e.skipped$,()=>this.logAdSkipped()),t(e.clicked$,()=>this.logAdClicked()),t(e.error$,o=>this.logError({errorType:o,fatal:!1})),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(e){let{subscription:i,subscribe:t}=me();return t(e.click$,o=>this.logInterfaceClick(o)),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(e){return this.api.authorize(e)}pause(){this.logger.pause(),this.oneStatDebugLog({message:"paused"})}resume(){this.logger.resume(),this.oneStatDebugLog({message:"resumed"})}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.oneStatDebugLog({message:"VSID reset"}),this.vsid$.next(Be())}getDeviceId(){return this.deviceId}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}logPlaying(){this.log({operation:"playing"})}logPause(e){this.log({operation:"pause",param:String(Math.round(e.position))})}logSeek(e){this.log({operation:"seek",param:e.action,time:e.time})}logFirstBytes(e){this.log({operation:"first_bytes",param:String(e.time)})}logFirstFrame(e){this.log({operation:"first_frame",param:String(e.time)})}logError(e){this.log({operation:"content_error",param:`${e.fatal?"fatal":"recoverable"}_${e.errorType}`})}logWatchCoverageRecord(e){this.log({operation:"watch_coverage_record",param:`${e.start}-${e.end}`},{in_history:this.statContext.inHistory?1:void 0})}logWatchCoverageLive(e){let i=this.timeSynchronisation?.getOffset()??0,t=e.start+i,o=e.end+i;this.log({operation:"watch_coverage_live",param:`${t}-${o}`},{in_history:this.statContext.inHistory?1:void 0,latency:e.latency,buffer_latency:e.bufferLatency})}logEmptyBuffer(e){this.log({operation:"empty_buffer",param:String(e.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(e){this.log({operation:"adv",param:e})}logAdPaused(){this.log({operation:"adv",param:"pause"})}logAdResumed(){this.log({operation:"adv",param:"resume"})}logAdEnded(){this.log({operation:"adv",param:"ended"})}logAdSkipped(){this.log({operation:"adv",param:"skip"})}logAdClicked(){this.log({operation:"adv",param:"click"})}logInterfaceClick(e){this.log({operation:"player_interface_click",param:e})}logNextMovie(e){this.log({operation:"next_movie",param:String(e)})}subscribe(){this.resubscribeBeforeunload();let e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(Kt(je(e,"change"),qt(["init"])).subscribe(()=>this.updateContext({network:Fe(e.effectiveType)}))),this.config.debugLog&&this.debugLogger.log$.subscribe(i=>{console.debug("%c stat ","background:#fa6470;",`component: ${i.component}.`,i.message)})}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=je(window,"beforeunload").subscribe(()=>this.logger.flush({wantBeacon:!0,clearStorage:this.config.clearStorageAtUnload})),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(e){this.log({operation:"player_ready",param:String(Math.round(e.duration))})}logActionPlay(e){this.log({operation:"action_play",param:String(Math.round(e.position))})}logActionPlayInteractive(){this.statContext.projectId&&this.log({operation:"action_play_interactive",param:String(this.statContext.movieId)},{vid:this.statContext.projectId})}logFailover(e){this.log({operation:"failover",param:e})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}logTrackSwitch(e){this.log({operation:"track_switch",param:e.id})}logQuality(e){this.log({operation:"quality",param:e})}log(e,i={}){if(this.disabled){this.oneStatDebugLog({message:`operation ${e.operation} but statistics is disabled`});return}if(this.config.disabledOperations.includes(e.operation)){this.oneStatDebugLog({message:`operation ${e.operation} but it is disabled`});return}this.oneStatDebugLog({message:`operation ${e.operation} ${e.param}`});let t=this.createLogItem(e,i);this.logger.log(t)}createLogItem({operation:e,param:i,time:t},o={}){let r=this.timeSynchronisation?.now()??x(),a=this.vsid$.getValue();Wt(a);let n=this.isid$.getValue(),l=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,c=this.statContext.firstConnectionReused,h,p;if(this.isEmbed||this.statContext.place==="embed"){h=this.embedParent;let u=[...new URLSearchParams(location.search).entries()].filter(([m,f])=>this.config.embedUrlParams.includes(m));p=new URLSearchParams(u).toString()}else this.statContext.place==="direct"&&(this.statContext.refDomain?h=Xe(this.statContext.refDomain)?.hostname??this.statContext.refDomain:document.referrer&&(h=Xe(document.referrer)?.hostname??document.referrer),p=location.href.substring(0,1024));let d={vsid:a,isid:n,vid:this.statContext.movieId,uid:this.zenUid$.getValue(),ct:this.statContext.contentType,place:this.isEmbed?"embed":this.statContext.place,quality:this.statContext.quality,cdn_host:this.statContext.cdnHostname,stat_type:this.statContext.autoplay===!0?"auto":this.statContext.autoplay===!1?"":void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:l,connection_reused:c===!0?1:c===!1?0:void 0,cached_data:this.statContext.cached===!0?1:this.statContext.cached===!1?0:void 0,live:this.statContext.liveEdge?1:void 0,muted:this.statContext.audible===!1?1:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:1,ref_domain:h,direct_url:p,rate:this.statContext.rate===1||Ge(this.statContext.rate)?void 0:this.statContext.rate.toFixed(2),view_360:this.statContext.is3d?1:void 0,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId,...o};for(let u of this.config.disabledCustomFields)delete d[u];return{operation:e,type:1,time:t,network:this.statContext.network,timestamp:r,custom:d}}};var Pt={};xt(Pt,{SeekType:()=>Q,ThinOneStat:()=>te,VERSION:()=>P});import{assertNonNullable as li,detectEmbed as hi,fromEvent as pi,Logger as fi,merge as vt,safeStorage as It,Subject as gi,Subscription as we,ValueSubject as ee}from"@vkontakte/videoplayer-shared/evergreen";import{clientChecker as L,PlaybackState as St}from"@vkontakte/videoplayer-core/evergreen";import{fillWithDefault as Xt}from"@vkontakte/videoplayer-shared/evergreen";var Q=(n=>(n.SLIDER="slider",n.DOUBLE_TAP="double_tap",n.TIME_CODE="time_code",n.EPISODE="episode",n.REWIND="rewind",n.LIVE="live",n.UNKNOWN="unknown",n))(Q||{});var et="CIOPGQJGDIHBABABA",Ie={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var Jt={apiKey:et,apiEnv:"vk_alias",requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageHeartbeatInterval:15,synchronizeTime:!0,useBeacon:!1,alwaysSendDesktop:!1},tt=s=>Xt(s,Jt);import{getExponentialDelay as Zt,ErrorCategory as N,ValueSubject as ei}from"@vkontakte/videoplayer-shared/evergreen";var j=class{constructor(e){this.params=e,this.authorized$=new ei(!1),this.consequentAuthErrors=0}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this.authorizeWithBackoff()}logBeacon(e){let i="log.logUvStat",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.logUvStat",t=this.createLogParams(e),o={},r=this.sessionKey??await this.authorizeWithBackoff();if(!r)return;let a=async(n,l=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,r,o)}catch(c){if(!c||!("error_code"in c)){this.params.error$.next({id:"logRequestUnknown",category:N.NETWORK,message:`Unknown ${i} error`,thrown:c});return}let h=c?.error_code;switch(h){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this.authorizeWithBackoff(),l>0?a(n,l-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this.authorizeWithBackoff(),l>0?a(n,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${h}`,category:N.EXTERNAL_API,message:`${i} error`,data:c});return}}}};return a(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){return{collector:"ok.mobile.apps.video",uv_stat_data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${P}`,platform:e[0].platform,product:e[0].product,events:e})}}authorizeWithBackoff(){if(!this.consequentAuthErrors)return this.doAuthorize();let e=Zt(this.consequentAuthErrors);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(async()=>{try{let t=await this.doAuthorize();i(t)}catch(t){this.params.error$.next({id:"AuthorizeBackoff",category:N.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})}finally{this.backoffTimeoutId=0}},e))})}doAuthorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:P.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:N.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this.authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:N.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:N.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{now as Se,ErrorCategory as G}from"@vkontakte/videoplayer-shared/evergreen";var Y=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=Ie[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this.prepareQueryParams({method:e,queryParams:i,sessionKey:t}),r=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,r)}catch(a){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:G.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t,o){let r=Se(),a=n=>{if(n instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(n.message)){this.params.error$.next({id:"Network",category:G.NETWORK,message:"Request failed",thrown:n});return}this.params.error$.next({id:"ThinOneStat:ApiTransport:sendRequest",category:G.NETWORK,message:"Unhandled request error",thrown:n,data:{method:e,params:i,sessionKey:t,time:Se()-r}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded",...o},body:this.prepareQueryParams({method:e,queryParams:i,sessionKey:t})}).then(n=>{let l=Number(n.headers.get("content-length"))===0,c=new Date(n.headers.get("date")??"").getTime(),h=Se()-r;if(isFinite(c)&&this.timeSynchronisation?.addServerTime(c,h),!l)return n.json().then(p=>Object.prototype.hasOwnProperty.call(p,"error_msg")?Promise.reject(p):p,a)},a)}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"ThinOneStat:ApiTransport:resolveApiBaseUrl",category:G.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),Ie.vk_alias}finally{this.isApiBaseUrlFetched=!0}}prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as ti,now as ii,safeStorage as F,debounceFn as it}from"@vkontakte/videoplayer-shared/evergreen";var X="thinonestat_events",ye=s=>e=>e.client_time+s>=ii(),J=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{event_name:i}=e;return["watch_coverage","watch_coverage_live","watched_n","playback_started"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=it(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=F.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=it(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:ti.WTF,message:String(e)||"Unknown logger error",thrown:e})}}readFromStorage(){let e=F.get(X);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(ye(this.params.config.storageExpiration));F.set(X,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(ye(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],F.set(X,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(ye(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}F.set(X,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};function Pe(){let s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=s[o===19?t&3|8:t]);return e.join("")}var Z=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};import{PlaybackState as ot}from"@vkontakte/videoplayer-core/evergreen";import{Observable as oi,Subscription as ri,ValueSubject as si,Subject as _e,fromEvent as ai,isNullable as rt,merge as Ee,filter as st,filterChanged as at}from"@vkontakte/videoplayer-shared/evergreen";var nt=(s,e)=>new oi(i=>{let t=new ri,o=new si(void 0),r;t.add(s.info.isLive$.pipe(at()).subscribe(y=>{r&&(r.unsubscribe(),o.next(void 0)),y?r=s.info.liveTime$.pipe(at()).subscribe(o):r=s.info.position$.subscribe(o),t.add(r)}));let{playing$:a,paused$:n,ended$:l,looped$:c}=s.events,h=s.events.willSeek$.pipe(st(()=>s.info.playbackState$.getValue()===ot.PLAYING)),p=s.events.seeked$.pipe(st(()=>s.info.playbackState$.getValue()===ot.PLAYING)),d=!1,u=new _e;t.add(h.subscribe(()=>{d||u.next(),d=!0})).add(p.subscribe(()=>d=!1));let m=Ee(ai(window,"beforeunload"),s.events.willDestruct$),f,I=()=>f=o.getValue(),S=()=>{let y=o.getValue();rt(f)||rt(y)||f===y||(i.next({from:f,to:y}),f=void 0)},A=new _e,w=new _e,T=Ee(a,u,A),g=Ee(n,p,m,l,c,w);if(t.add(T.subscribe(I)).add(g.subscribe(S)),e.heartbeatInterval&&isFinite(e.heartbeatInterval)){let y=[],At=e.heartbeatInterval*1e3,wt=()=>{w.next(),A.next()};t.add(T.subscribe(()=>{let oe=window.setTimeout(wt,At);y.push(oe)})).add(g.subscribe(()=>{y.forEach(oe=>{window.clearTimeout(oe)}),y=[]}))}return t});import{Subscription as ni}from"@vkontakte/videoplayer-core/evergreen";import{Observable as di}from"@vkontakte/videoplayer-shared/evergreen";var dt=(s,e)=>new di(i=>{let t=new ni,o=1e4,r=0;return t.add(s.info.position$.subscribe(()=>{let a=e.getTotalViewTime()*1e3;a>r&&a%o===0&&(r=a,i.next({target_duration:o,current_tvt:a}))})),t});import{Observable as ci,Subscription as ui,merge as ct}from"@vkontakte/videoplayer-shared/evergreen";var ut=s=>new ci(e=>{let i=new ui,t=0,o=1,r=0,a=!1,n=!1,l=()=>{if(!a)return;let g=Date.now();r+=(g-t)*o,t=g},c=()=>{(!a||n)&&(t=Date.now(),a=!0,n=!1)},h=()=>{a&&(l(),a=!1)},p=()=>{a&&(l(),a=!1,n=!0)},d=g=>{a&&l(),o=g,t=Date.now()},{started$:u,playing$:m,paused$:f,willSeek$:I,ended$:S,willDestruct$:A}=s.events,{currentPlaybackRate$:w}=s.info;i.add(I.subscribe(p)).add(ct(u,m).subscribe(c)).add(ct(f,S,A).subscribe(h)).add(w.subscribe(d));let T=()=>{let g=r;return a&&(g+=(Date.now()-t)*o),Math.floor(g/1e3)};return e.next(T),i});import{assertNever as lt}from"@vkontakte/videoplayer-shared/evergreen";import{Surface as O,VideoFormat as b,VideoQuality as E}from"@vkontakte/videoplayer-core/evergreen";var Ae=s=>{if(s!==void 0)switch(s){case b.MPEG:return"MP4";case b.DASH:case b.DASH_LIVE:return"DASH";case b.DASH_SEP:return"DASH_SEP";case b.DASH_ONDEMAND:return"ONDEMAND_DASH";case b.HLS_ONDEMAND:return"ONDEMAND_HLS";case b.HLS:case b.HLS_LIVE:return"HLS";case b.DASH_WEBM:case b.DASH_LIVE_WEBM:return"WEBM";case b.DASH_LIVE_CMAF:return"ONDEMAND_DASH_LIVE";case b.HLS_LIVE_CMAF:return"ONDEMAND_HLS_LIVE";case b.WEB_RTC_LIVE:return"WEBRTC";case b.DASH_WEBM_AV1:return"AV1";case b.DASH_STREAMS:return"MULTI_DASH";default:return lt(s)}},k=s=>{if(s!==void 0)switch(s){case E.Q_144P:return"144p";case E.Q_240P:return"240p";case E.Q_360P:return"360p";case E.Q_480P:return"480p";case E.Q_720P:return"720p";case E.Q_1080P:return"1080p";case E.Q_1440P:return"1440p";case E.Q_2160P:return"2160p";case E.INVARIANT:case E.Q_576P:case E.Q_4320P:return"UNKNOWN";default:return lt(s)}},ht=s=>{if(s!==void 0)switch(s){case"MP4":case"ONDEMAND_DASH":case"ONDEMAND_DASH_LIVE":case"ONDEMAND_HLS":case"ONDEMAND_HLS_LIVE":case"MULTI_DASH":case"WEBM":case"AV1":return"vod";case"DASH":case"HLS":case"WEBRTC":return"live";default:return}},pt=(s,e,i)=>{if(s&&e)switch(s){case b.MPEG:return i&&e[s]&&e[s][i];default:return e[s]?.url}},ft=s=>{if(s!==void 0)switch(s){case O.NONE:return;case O.INLINE:return"inline";case O.FULLSCREEN:return"fullscreen";case O.SECOND_SCREEN:return"chromecast";case O.PIP:return"pip_external"}},gt=s=>{if(s!==void 0)return s===O.INVISIBLE?"background":"foreground"};var mt=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(13,"0"),bt=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");var mi="_thin-one-stat_",yt=`${mi}deviceId`,bi=()=>{let s=new we;return{subscription:s,subscribe:(e,i)=>{e&&s.add(e.subscribe(i))}}},te=class{constructor(e,i){this.debugLogger=new fi;this.thinOneStatDebugLog=this.debugLogger.createComponentLog("ThinOneStat");this.eventNumber=1;this.seekAction$=new ee("unknown");this.playerSize$=new ee({width:0,height:0});this.vsid$=new ee(void 0);this.isid$=new ee(void 0);this.statContext=e,this.config=tt(i.config??{}),this.subscription=new we,this.config.synchronizeTime&&(this.timeSynchronisation=new Z);let t=new gi,o=It.get(yt);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=Pe(),It.set(yt,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??bt());let r=new Y({error$:t,config:this.config,timeSynchronisation:this.timeSynchronisation});this.api=new j({config:this.config,apiTransport:r,error$:t,deviceId:this.deviceId,refreshAuthToken:i.refreshAuthToken}),this.logger=new J({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:a,topOrigin:n}=hi();this.isEmbed=a,this.embedHostname=n?new URL(n).hostname:void 0}authorize(e){return this.api.authorize(e)}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new we,t=(r,a)=>i.add(r.subscribe(a));t(ut(e),r=>{this.getTotalViewTime=r}),t(e.info.isLive$,r=>this.isLive=r),t(e.info.position$,r=>this.position=r);let o;return t(e.info.hostname$,r=>{o!==void 0&&o!==r&&this.logFailover({cdn_host:r}),this.cdnHostname=o=r}),t(nt(e,{heartbeatInterval:this.config.watchCoverageHeartbeatInterval}),r=>{let a=Math.round(r.from*1e3),n=Math.round(r.to*1e3),l={watch_interval:`${a}-${n}`,in_history:!!this.statContext.inHistory,content_type:Ae(e.info.currentFormat$.getValue()),playback_quality:k(e.info.currentQuality$.getValue()),recom_info:this.statContext.recomInfo};if(!e.info.isLive$.getValue())this.logWatchCoverage(l);else{let h=e.info.atLiveEdge$.getValue();this.logWatchCoverageLive({...l,live:!!h})}}),t(dt(e,{getTotalViewTime:this.getTotalViewTime}),r=>{this.logWatchedN(r)}),t(vt(e.events.willStart$,e.events.looped$),r=>{r&&this.resetViewSession();let a={isid:this.isid$.getValue(),stream_profile:ht(Ae(e.info.currentFormat$.getValue())),dpi:L.display.pixelRatio,web_layout:L.device.isMobile?"mobile":"desktop",iframe_host:this.isEmbed?this.embedHostname??void 0:null,from_downloads:!0,preloaded:this.statContext.preload,navigation:this.statContext.navigation,recom_info:this.statContext.recomInfo};this.logStartSession(a)}),t(e.events.willReady$,()=>{if(this.statContext.preload){let r=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),n=e.info.currentBuffer$.getValue(),l=e.info.currentQuality$.getValue(),c={target_buffer_time:n?n.end-n.start:void 0,playback_url:pt(r,a,l),playback_quality:k(l)};this.logPreloadStarted(c)}}),t(e.events.ready$,()=>{if(this.statContext.preload){let r=e.info.currentBuffer$.getValue(),a={buffer_time:r?r.end-r.start:void 0};this.logPreloadEnded(a)}}),t(e.events.playing$,()=>{this.logPlay()}),t(e.info.playbackState$,r=>{if(r===St.PLAYING){let a=e.info.currentBuffer$.getValue(),n={buffer_time:a?a.end-a.start:void 0};if(this.logPlaying(n),this.isStarted)this.logResume();else{this.isStarted=!0;let l=e.info.currentQuality$.getValue(),c=e.info.isAutoQualityEnabled$.getValue(),h=e.info.muted$.getValue(),p=e.info.volume$.getValue(),d=e.info.surface$.getValue(),u=e.info.availableTextTracks$.getValue(),m=e.info.currentTextTrack$.getValue(),f=e.info.currentAudioStream$.getValue(),I=e.info.currentPlaybackRate$.getValue(),S={playback_quality:k(l),user_quality:c?"auto":k(l),player_width:this.playerSize$.getValue().width,player_height:this.playerSize$.getValue().height,muted:h,sound_volume:p,buffer_time:a?Math.round(a.end-a.start):void 0,mode:ft(d),visibility:gt(d),subtitles_enabled:!!m,auto_subtitles:!!u.find(({id:A})=>A===m)?.isAuto,audio_track_lang:f?.language,playback_rate:I,recom_info:this.statContext.recomInfo};this.logPlaybackStarted(S)}}else r===St.PAUSED&&this.logPause()}),t(e.events.willSeek$,({to:r})=>{let a={target_position:r,seek_type:this.seekAction$.getValue()};this.logSeeking(a)}),t(e.events.seeked$,()=>{let a={target_position:e.info.position$.getValue(),seek_type:this.seekAction$.getValue()};this.logSeeked(a),this.seekAction$.next("unknown")}),t(vt(e.info.isBuffering$,e.info.isStalled$),r=>{r&&this.logShowLoader()}),t(e.info.currentQuality$,r=>{if(r){let a=e.info.isAutoQualityEnabled$.getValue(),n=e.info.currentVideoStream$.getValue()?.codec,l=e.info.currentAudioStream$.getValue()?.codec,c={user_quality:a?"auto":k(r),playback_quality:k(r),download_quality:k(r),codec_info:n&&l?`${n},${l}`:void 0,manual_switch:!a};this.logQualityChanged(c)}}),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){let{subscribe:i,subscription:t}=bi();return i(e.actionSeek$,this.seekAction$),i(e.playerSize$,this.playerSize$),this.subscription.add(t),t}getDeviceId(){return this.deviceId}resetViewSession(){this.thinOneStatDebugLog({message:"VSID reset"}),this.vsid$.next(mt()),this.eventNumber=0}destroy(){this.api.destroy()}createRequiredParams(e){let i=this.vsid$.getValue();li(i);let t=this.eventNumber++;return{vsid:i,uv_movie_id:this.statContext.movieId,event_name:e,client_time:Date.now(),application:`@vkontakte/videoplayer-statistics:${P}`,platform:`web:${L.device.isMobile?"mobile":"desktop"}`,product:this.statContext.product,event_number:t,playback_position:this.isLive?void 0:Math.round(this.position),current_tvt:this.getTotalViewTime(),cdn_host:this.cdnHostname}}createRequiredFatParams(){return{stats_version:P,browser:L.browser.current,browser_version:String(L.browser.currentVersion),os:L.device.current,os_version:"",device_type:L.device.isMobile?"mobile":"desktop",navigation:this.statContext.navigation}}log(e,i,t=!1){let o=this.createRequiredParams(e),r={};t&&(r=this.createRequiredFatParams()),this.logger.log({...o,...r,...i})}logWatchCoverage(e){this.log("watch_coverage",e,!0)}logWatchCoverageLive(e){this.log("watch_coverage_live",e,!0)}logWatchedN(e){this.log("watched_n",e,!0)}logStartSession(e){this.log("start_session",e,!0)}logPreloadStarted(e){this.log("preload_started",e)}logPreloadEnded(e){this.log("preload_ended",e)}logPlaybackStarted(e){this.log("playback_started",e,!0)}logPlay(){this.log("play")}logPlaying(e){this.log("playing",e)}logPause(){this.log("pause")}logResume(){this.log("resume")}logSeeking(e){this.log("seeking",e)}logSeeked(e){this.log("seeked",e)}logShowLoader(){this.log("show_loader")}logQualityChanged(e){this.log("quality_changed",e)}logFailover(e){this.log("failover",e)}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=pi(window,"beforeunload").subscribe(()=>{}),this.subscription.add(this.beforeunloadSubscription)}};var vi={};import{PlaybackState as Et,Subscription as Ii}from"@vkontakte/videoplayer-core/evergreen";import{Logger as Si}from"@vkontakte/videoplayer-shared/evergreen";var ie=class{constructor(){this.startTime=null;this.stopTime=null;this.accumulatedTime=0}get time(){return Math.floor(this.timeMs/1e3)}get timeMs(){return this.startTime===null?0:(this.stopTime??this.now())-this.startTime-this.accumulatedTime}get isRunning(){return this.startTime!==null&&this.stopTime===null}start(){this.isRunning||(this.stopTime!==null?(this.accumulatedTime+=this.now()-this.stopTime,this.stopTime=null):this.startTime=this.now())}stop(){this.isRunning&&(this.stopTime=this.now())}reset(){this.startTime=null,this.stopTime=null,this.accumulatedTime=0}now(){return Date.now()}};var _t=()=>window.Image?new Image:document.createElement("img");var Te=class{constructor(e){this.position=0;this.started=!1;this.heartbeatPixels=[];this.heartbeatLastTimeSent={};this.idleCallbackIds=[];this.stopwatch=new ie;this.subscription=new Ii;this.params=e;let i=new Si;this.log=i.createComponentLog("MediascopePixel")}attachTo(e){this.subscription.add(e.info.playbackState$.subscribe(i=>this.onPlaybackState(i))).add(e.info.position$.subscribe(i=>this.onPosition(i))).add(e.info.atLiveEdge$.subscribe(i=>this.isActiveLive=i)),this.subscription.add(e.events.willSeek$.subscribe(()=>this.onWillSeek())).add(e.events.seeked$.subscribe(()=>this.onSeeked())).add(e.events.ended$.subscribe(()=>this.onEnded()))}destroy(){this.stopwatch.reset(),this.subscription.unsubscribe(),window.clearTimeout(this.heartbeatFirstTimeoutId),this.idleCallbackIds.forEach(e=>window.cancelIdleCallback(e)),this.send("stop")}onPlaybackState(e){e===Et.PLAYING?this.started?this.play():this.start():e===Et.PAUSED&&this.pause()}start(){this.started=!0,this.stopwatch.start(),this.send("start"),this.heartbeatPixels=this.prepareHeartbeatPixels(),this.heartbeatInterval=this.heartbeatPixels[0]?.interval;let e=this.heartbeatPixels[0]?.url,i=this.heartbeatPixels[0]?.delay;if(i!==void 0&&e)try{this.heartbeatFirstTimeoutId=window.setTimeout(()=>{this.sendHeartbeat(e)},i*1e3)}catch(t){this.log({message:t.message})}}play(){this.stopwatch.start(),this.send("resume")}pause(){this.stopwatch.stop(),this.send("pause")}onPosition(e){if(this.position=e,this.heartbeatInterval&&this.stopwatch.time!==0&&this.stopwatch.time%this.heartbeatInterval===0)for(let[i,{url:t}]of this.heartbeatPixels.entries())this.heartbeatLastTimeSent[i]!==this.stopwatch.time&&(this.heartbeatLastTimeSent[i]=this.stopwatch.time,this.sendHeartbeat(t))}onWillSeek(){this.started&&this.send("stop")}onSeeked(){this.started&&this.send("start")}onEnded(){this.stopwatch.stop(),this.send("stop")}validatePixels(e,i){return e?.filter(t=>t.event===i.event&&i.keys.every(o=>!!t[o]))}getFrameTimestamp(){let e;if(this.isActiveLive){let i=Math.floor(Math.random()*25)+5;e=Date.now()/1e3-i}else e=this.position||0;return Math.floor(e)}getUTC(){return Math.floor(Date.now()/1e3)}prepareUrl(e){let i=new URL(e);return i.pathname=i.pathname.replace("{@fts_fake_sec}",String(this.getFrameTimestamp())).replace("{@utc_sec}",String(this.getUTC())),i.search=[...new URLSearchParams(i.search)].filter(([t,o])=>!/={@[\w]+}/.test(`${t}=${o}`)).map(t=>t.join("=")).join("&"),i.toString()}preparePixels(e){return this.validatePixels(this.params.pixels,{event:e,keys:["url"]})}prepareHeartbeatPixels(){return this.validatePixels(this.params.pixels,{event:"heartbeat",keys:["url","interval"]})}call(e){try{this.idleCallbackIds.push(requestIdleCallback(()=>_t().src=this.prepareUrl(e)))}catch(i){this.log({message:i.message})}}send(e){let i=this.preparePixels(e);for(let{url:t}of i)this.call(t)}sendHeartbeat(e){this.call(e)}};export{R as ApiEnv,ae as ConnectionType,se as ContentType,xe as InteractiveInterfaceClick,Te as MediascopePixel,vi as MediascopePixelTypes,ve as OneStat,re as Quality,ne as SeekAction,Pt as ThinOneStat,P as VERSION};
|
|
6
|
+
var Lt=Object.defineProperty;var $t=(r,e)=>{for(var i in e)Lt(r,i,{get:e[i],enumerable:!0})};var F=(l=>(l.PROD="prod",l.VK_ALIAS="vk_alias",l.VIDEOTEST="videotest",l.TEST="test",l.OKCDN="okcdn",l.AUTO="auto",l))(F||{}),de=(a=>(a.Q144P="mobile",a.Q240P="lowest",a.Q360P="low",a.Q480P="medium",a.Q720P="high",a.Q1080P="fullhd",a.Q1440P="quadhd",a.Q2160P="ultrahd",a.UNKNOWN="unknown",a))(de||{}),ce=(g=>(g.MP4="mp4",g.DASH="dash",g.DASH_SEP="dash_sep",g.ONDEMAND_DASH="ondemand_dash",g.HLS="hls",g.HLS_FMP4="hls_fmp4",g.ONDEMAND_HLS="ondemand_hls",g.WEBM="webm",g.AV1="av1",g.ONDEMAND_DASH_LIVE="ondemand_dash_live",g.ONDEMAND_HLS_LIVE="ondemand_hls_live",g.WEBRTC="webrtc",g.UNKNOWN="unknown",g.RTMP="rtmp",g))(ce||{});var le=(t=>(t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3",t))(le||{});var ue=(c=>(c.SLIDER="slider",c.DOUBLE_TAP="double_tap",c.TIME_CODE="time_code",c.EPISODE="episode",c.REWIND="rewind",c.LIVE="live",c.UNKNOWN="unknown",c))(ue||{}),Me=(n=>(n.GRAPH_SHOW="iGraphShow",n.GRAPH_HIDE="iGraphHide",n.NEXT_AREA="iNextChapterArea",n.NEXT_BUTTON="iNextChapterBtn",n.WATCH_AGAIN="iWatchAgainBtn",n))(Me||{}),Fe={action_play:"ap",action_play_interactive:"api",first_bytes:"fb",player_ready:"pr",first_frame:"ff",seek:"sk",watch_coverage_record:"wr",watch_coverage_live:"wl",empty_buffer:"eb",action_stop:"as",close_at_empty_buffer:"cb",content_error:"er",player_interface_click:"pc",next_movie:"nm",track_switch:"ts",failover:"fo",quality:"qt"},Be={vsid:"si",isid:"is",vid:"vi",place:"pl",quality:"qt",cdn_host:"ch",stat_type:"st",param:"pm",vk_app_id:"va",track_code:"tc",connection_type:"cnt",connection_reused:"cr",cached_data:"cd",live:"lv",muted:"mu",mode:"mo",subtitles:"sb",failover:"fo",download_speed:"ds",manual_quality:"mq",ref_domain:"rd",direct_url:"du"},Ue={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},He={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv",minimal:"minimal"};import{fillWithDefault as Rt}from"@vkontakte/videoplayer-shared/evergreen";var qe="CIOPGQJGDIHBABABA",he={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var Dt={apiEnv:"vk_alias",apiKey:qe,requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageInterval:15e3,disabledOperations:["quality"],disabledCustomFields:[],shorten:!0,maxLoops:100,embedUrlParams:[],useBeacon:!0,synchronizeTime:!0,debugLog:!1,clearStorageAtUnload:!0,useVKComIsMobileLogic:!1,backoff:{start:1e3,factor:1.5,max:5*60*1e3,random:.1},useKeepalive:!1},We=r=>Rt(r,Dt);function pe(){let r="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=r[o===19?t&3|8:t]);return e.join("")}import{assertNonNullable as jt,combine as it,fromEvent as ot,isNonNullable as O,isNullable as rt,merge as Gt,now as x,observableFrom as Yt,once as Xt,safeStorage as st,Subject as Jt,Subscription as Se,ValueSubject as Y}from"@vkontakte/videoplayer-shared/evergreen";import{Logger as Zt,detectEmbed as ei}from"@vkontakte/videoplayer-shared/evergreen";var Nt=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(13,"0"),k=class r{static getVSID(){return r.vsid}static generateVSID(){return r.vsid=Nt(),r.vsid}};var Ke=r=>{let{operation:e,custom:i}=r,t=Object.fromEntries(Object.entries(i).map(([o,n])=>{let l=Be[o]??o,c=n;return n&&(o==="mode"?c=He[n]??n:o==="quality"&&(c=Ue[n]??n)),[l,c]}));return{...r,operation:Fe[e]??e,custom:t}};var S="1.0.84-beta.0";import{ValueSubject as Ot,getExponentialDelay as Vt,ErrorCategory as D}from"@vkontakte/videoplayer-shared/evergreen";var Mt=/Mobile|mini|Fennec|Android|iP(ad|od|hone)|opera (mini|mobi)/i,B=class{constructor(e){this.consequentAuthErrors=0;this.authorized$=new Ot(!1);this.params=e}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.externalLog",t=this.createLogParams(e),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;let n=async(l,c=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,o)}catch(s){if(!s||!("error_code"in s)){this.params.error$.next({id:"logRequestUnknown",category:D.NETWORK,message:`Unknown ${i} error`,thrown:s});return}let a=s?.error_code;switch(a){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),c>0?n(l,c-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),c>0?n(l,c-1):void 0;default:{this.params.error$.next({id:`LogRequest#${a}`,category:D.EXTERNAL_API,message:`${i} error`,data:s});return}}}};return n(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){let i="WEB",t=!1,o=`@vkontakte/videoplayer-statistics:${S}`;if(this.params.config.useVKComIsMobileLogic){let{appVersion:n}=window.navigator;t=Mt.test(n)}else this.params.mobile&&(t=!0);return t&&(i="M_WEB"),this.params.vktvVersion&&(i="SMART_TV",o=this.params.vktvVersion),{collector:"ok.mobile.apps.video",data:JSON.stringify({application:o,platform:i,items:this.params.config.shorten?e.map(Ke):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();let e=Vt(this.consequentAuthErrors,this.params.config.backoff);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(t=>this.params.error$.next({id:"AuthorizeBackoff",category:D.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:S.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:D.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:D.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:D.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{ErrorCategory as K,now as ge}from"@vkontakte/videoplayer-shared/evergreen";var U=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=he[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:K.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),he.vk_alias}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this._prepareQueryParams({method:e,queryParams:i,sessionKey:t}),n=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,n)}catch(l){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:K.NETWORK,message:"Unhandled beacon error",thrown:l,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t){let o=ge(),n=c=>{if(c instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(c.message)){this.params.error$.next({id:"Network",category:K.NETWORK,message:"Request failed",thrown:c});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:K.NETWORK,message:"Unhandled request error",thrown:c,data:{method:e,params:i,sessionKey:t,time:ge()-o}})};this.apiBaseUrl=await this.resolveApiBaseUrl();let l={method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:t})};return this.params.config.useKeepalive&&(l.keepalive=!0),fetch(`${this.apiBaseUrl}/fb.do`,l).then(c=>{let s=Number(c.headers.get("content-length"))===0,a=new Date(c.headers.get("date")??"").getTime(),u=ge()-o;if(isFinite(a)&&this.timeSynchronisation?.addServerTime(a,u),!s)return c.json().then(h=>Object.prototype.hasOwnProperty.call(h,"error_msg")?Promise.reject(h):h,n)},n)}_prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as Ft,now as Bt,safeStorage as H,debounceFn as Qe}from"@vkontakte/videoplayer-shared/evergreen";var Q="onestat_events",fe=r=>e=>e.timestamp+r>=Bt(),z=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{operation:i}=e;return["action_play","watch_coverage_record","watch_coverage_live"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=Qe(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=H.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Qe(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:Ft.WTF,message:e?String(e):"Unknown logger error",thrown:e})}}readFromStorage(){let e=H.get(Q);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(fe(this.params.config.storageExpiration));H.set(Q,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(fe(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],H.set(Q,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(fe(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}H.set(Q,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.custom.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};import{HttpConnectionType as me,Surface as N,VideoFormat as I,VideoQuality as A}from"@vkontakte/videoplayer-core/evergreen";import{assertNever as ze}from"@vkontakte/videoplayer-shared/evergreen";var je=r=>r&&{[A.INVARIANT]:"unknown",[A.Q_144P]:"mobile",[A.Q_240P]:"lowest",[A.Q_360P]:"low",[A.Q_480P]:"medium",[A.Q_576P]:"unknown",[A.Q_720P]:"high",[A.Q_1080P]:"fullhd",[A.Q_1440P]:"quadhd",[A.Q_2160P]:"ultrahd",[A.Q_4320P]:"unknown"}[r],ve=r=>r&&{[me.HTTP1]:"http1",[me.HTTP2]:"http2",[me.QUIC]:"http3"}[r],Ge=r=>{if(r!==void 0)switch(r){case I.MPEG:return"mp4";case I.DASH:case I.DASH_LIVE:case I.DASH_STREAMS:return"dash";case I.DASH_SEP:return"dash_sep";case I.DASH_ONDEMAND:return"ondemand_dash";case I.DASH_WEBM:case I.DASH_LIVE_WEBM:return"webm";case I.DASH_WEBM_AV1:return"av1";case I.DASH_LIVE_CMAF:return"ondemand_dash_live";case I.HLS:case I.HLS_LIVE:return"hls";case I.HLS_FMP4:return"hls_fmp4";case I.HLS_ONDEMAND:return"ondemand_hls";case I.HLS_LIVE_CMAF:return"ondemand_hls_live";case I.WEB_RTC_LIVE:return"webrtc";default:return ze(r)}},j=(r,e)=>{if(e)return"minimal";if(r!==void 0)switch(r){case N.NONE:case N.INLINE:return;case N.FULLSCREEN:return"fullscreen";case N.SECOND_SCREEN:return"chromecast";case N.PIP:return"pip";case N.INVISIBLE:return"invisible";default:return ze(r)}},Ye=r=>{switch(r){case"slow-2g":return"poor";case"2g":return"poor";case"3g":return"good";case"4g":return"excellent"}};var G=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};var Xe=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");import{PlaybackState as Je}from"@vkontakte/videoplayer-core/evergreen";import{filter as Ze,filterChanged as Ht,fromEvent as qt,isNullable as et,map as Wt,merge as be,Observable as Kt,Subject as Ie,Subscription as Qt,ValueSubject as zt}from"@vkontakte/videoplayer-shared/evergreen";var tt=(r,e)=>new Kt(i=>{let t=new Qt,o=be(qt(window,"beforeunload"),r.events.willDestruct$),n=new zt(void 0),l;t.add(r.info.isLive$.pipe(Ht()).subscribe(f=>{l&&(l.unsubscribe(),n.next(void 0)),f?l=r.info.liveTime$.pipe(Wt(R=>R&&R/1e3)).subscribe(n):l=r.info.position$.subscribe(n),t.add(l)}));let{playing$:c,paused$:s}=r.events,a=r.events.willSeek$.pipe(Ze(()=>r.info.playbackState$.getValue()===Je.PLAYING)),u=r.events.seeked$.pipe(Ze(()=>r.info.playbackState$.getValue()===Je.PLAYING)),h=!1,d=new Ie;t.add(a.subscribe(()=>{h||d.next(),h=!0})),t.add(u.subscribe(()=>h=!1));let p=new Ie,g=new Ie,m=be(c,u,p),v=be(s,d,o,r.events.looped$,g),y,T=()=>y=n.getValue(),_=()=>{let f=n.getValue();et(y)||y===f||et(f)||(i.next({from:y,to:f}),y=void 0)},P=()=>{g.next(),p.next()};if(t.add(m.subscribe(T)),t.add(v.subscribe(_)),e.forceInterval&&isFinite(e.forceInterval)){let f=0;t.add(m.subscribe(()=>f=window.setTimeout(P,e.forceInterval))),t.add(v.subscribe(()=>window.clearTimeout(f)))}return t});var ti="_one-stat_",nt=`${ti}deviceId`,ye=()=>{let r=new Se;return{subscription:r,subscribe:(e,i)=>{e&&r.add(e.subscribe(i))}}},_e=class{constructor(e,i){this.subscription=new Se;this.debugLogger=new Zt;this.oneStatDebugLog=this.debugLogger.createComponentLog("onestat");this.loopCounter=0;this.disabled=!1;this.isid$=new Y(void 0);this.zenUid$=new Y(void 0);this.seekAction$=new Y("unknown");this.statContext=e,this.config=We(i.config??{}),O(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new G);let t=new Jt;this.experimental={error$:t};let o=st.get(nt);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=pe(),st.set(nt,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??Xe()),this.zenUid$.next(i.zenUid);let n=new U({config:this.config,error$:t,timeSynchronisation:this.timeSynchronisation});this.api=new B({config:this.config,apiTransport:n,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,deviceId:this.deviceId,error$:t,vktvVersion:i.vktvVersion}),this.logger=new z({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:l,topOrigin:c}=ei();this.isEmbed=l,this.embedParent=c?new URL(c).hostname:void 0,this.subscribe()}get vsid$(){return new Y(k.getVSID())}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new Se,t=(d,p)=>i.add(d.subscribe(p));t(e.events.willStart$,()=>{let d=e.info.position$.getValue();this.logActionPlay({position:d}),this.statContext.projectId&&this.logActionPlayInteractive()}),t(e.events.looped$,()=>{this.resetViewSession(),++this.loopCounter>this.config.maxLoops&&(this.disabled=!0),this.logActionPlay({position:e.info.position$.getValue()})}),t(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next("unknown")}),t(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),t(e.events.willResume$,()=>{this.logPlay()}),t(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),t(e.events.playing$,()=>{this.logPlaying()}),t(tt(e,{forceInterval:this.config.watchCoverageInterval}),d=>{let p=e.info.isLive$.getValue(),g=e.info.atLiveEdge$.getValue(),m={start:parseFloat(d.from.toFixed(3)),end:parseFloat(d.to.toFixed(3))};if(g){let v=e.info.liveLatency$.getValue()??0,y=e.info.currentBuffer$.getValue()?.end??0,T=e.info.liveBufferTime$.getValue()??0,_=Math.round((v-(y-T))*1e3),P=Math.round(v*1e3);_&&P&&(m.latency=_,m.bufferLatency=P)}p?this.logWatchCoverageLive(m):this.logWatchCoverageRecord(m)});let o;t(e.info.isStalled$,d=>{d?o=x():(O(o)&&this.logEmptyBuffer({duration:x()-o}),o=void 0)});let n=!1;i.add(e.events.fatalError$.pipe(Xt()).subscribe(()=>n=!0)),t(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){let p=O(o)?x()-o:void 0;this.logCloseAtEmptyBuffer({duration:p??0}),o=void 0}else n||this.logActionStop()}),t(e.events.managedError$,({id:d})=>{this.logError({fatal:!1,errorType:d})}),t(e.events.fatalError$,({id:d})=>{this.logError({fatal:!0,errorType:d})});let l,c,s=!1;t(e.events.firstBytes$,d=>{l=x(),this.logFirstBytes({time:d})}),t(e.events.willStart$,()=>c=x()),t(e.info.currentBuffer$,d=>{!s&&d&&d.end-d.start>0&&O(l)&&(this.logPlayerReady({duration:x()-l}),s=!0)}),t(e.events.firstFrame$,()=>{O(l)&&!s&&(this.logPlayerReady({duration:x()-l}),s=!0),O(c)&&this.logFirstFrame({time:x()-c})});let a;t(e.info.currentVideoStream$,d=>{d&&(a&&d.id!==a&&this.logTrackSwitch(d),a=d.id)});let u;t(e.info.currentAudioStream$,d=>{d&&(u&&d.id!==u&&this.logTrackSwitch(d),u=d.id)}),t(e.info.atLiveEdge$,d=>this.updateContext({liveEdge:d})),t(it({muted:e.info.muted$,volume:e.info.volume$}),({muted:d,volume:p})=>this.updateContext({audible:!d&&p>0})),t(e.info.currentQuality$,d=>{let p=je(d);this.updateContext({quality:p}),p&&this.logQuality(p)}),t(e.info.isAutoQualityEnabled$,d=>this.updateContext({autoQuality:d})),t(e.info.currentFormat$,d=>this.updateContext({contentType:Ge(d)})),t(e.info.currentPlaybackRate$,d=>this.updateContext({rate:d})),t(e.info.is3DVideo$,d=>this.updateContext({is3d:d}));let h;return t(e.info.hostname$,d=>{let p=h!==void 0&&h!==d;this.updateContext({cdnHostname:d,failover:p}),p&&this.logFailover(d),h=d}),t(e.info.throughputEstimation$,d=>this.updateContext({downloadSpeed:d})),t(e.info.httpConnectionType$,d=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:ve(d)}),this.updateContext({connectionType:ve(d)})}),t(e.info.httpConnectionReused$,d=>{rt(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:d}),this.updateContext({connectionReused:d})}),t(e.info.surface$,d=>this.updateContext({mode:j(d,this.statContext.isPreviewPlayerView)})),t(it({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:d,available:p})=>{let g=p.find(({id:v})=>v===d),m=g&&(g.isAuto?`${g.language}_auto`:g.language);this.updateContext({subtitles:m?.split(".")[0]})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){this.uiEvents=e;let{subscription:i,subscribe:t}=ye();return this.player&&(t(e.actionRewind$,()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))}),t(e.actionSeek$,this.seekAction$),t(e.inPiP$,o=>{let n=o?"pip":j(this.player?.info.surface$.getValue(),this.statContext.isPreviewPlayerView);this.updateContext({mode:n})}),t(e.inFullscreen$,o=>{let n=o?"fullscreen":j(this.player?.info.surface$.getValue(),this.statContext.isPreviewPlayerView);this.updateContext({mode:n})}),t(e.actionSetSubtitle$,o=>this.updateContext({subtitles:o.split(".")[0]})),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i)),i}attachToAds(e){let{subscription:i,subscribe:t}=ye();return t(e.slotRequested$,()=>this.logAdSlotRequest()),t(e.started$,o=>this.logAdStarted(o)),t(e.paused$,()=>this.logAdPaused()),t(e.resumed$,()=>this.logAdResumed()),t(e.ended$,()=>this.logAdEnded()),t(e.skipped$,()=>this.logAdSkipped()),t(e.clicked$,()=>this.logAdClicked()),t(e.error$,o=>this.logError({errorType:o,fatal:!1})),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToInteractive(e){let{subscription:i,subscribe:t}=ye();return t(e.click$,o=>this.logInterfaceClick(o)),t(e.nextMovie$,o=>this.logNextMovie(o)),this.resubscribeBeforeunload(),this.subscription.add(i),i}authorize(e){return this.api.authorize(e)}pause(){this.logger.pause(),this.oneStatDebugLog({message:"paused"})}resume(){this.logger.resume(),this.oneStatDebugLog({message:"resumed"})}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.oneStatDebugLog({message:"VSID reset"}),k.generateVSID()}getDeviceId(){return this.deviceId}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}logPlaying(){this.log({operation:"playing"})}logPause(e){this.log({operation:"pause",param:String(Math.round(e.position))})}logSeek(e){this.log({operation:"seek",param:e.action,time:e.time})}logFirstBytes(e){this.log({operation:"first_bytes",param:String(e.time)})}logFirstFrame(e){this.log({operation:"first_frame",param:String(e.time)})}logError(e){this.log({operation:"content_error",param:`${e.fatal?"fatal":"recoverable"}_${e.errorType}`})}logWatchCoverageRecord(e){this.log({operation:"watch_coverage_record",param:`${e.start}-${e.end}`},{in_history:this.statContext.inHistory?1:void 0})}logWatchCoverageLive(e){let i=this.timeSynchronisation?.getOffset()??0,t=e.start+i,o=e.end+i;this.log({operation:"watch_coverage_live",param:`${t}-${o}`},{in_history:this.statContext.inHistory?1:void 0,latency:e.latency,buffer_latency:e.bufferLatency})}logEmptyBuffer(e){this.log({operation:"empty_buffer",param:String(e.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(e){this.log({operation:"adv",param:e})}logAdPaused(){this.log({operation:"adv",param:"pause"})}logAdResumed(){this.log({operation:"adv",param:"resume"})}logAdEnded(){this.log({operation:"adv",param:"ended"})}logAdSkipped(){this.log({operation:"adv",param:"skip"})}logAdClicked(){this.log({operation:"adv",param:"click"})}logInterfaceClick(e){this.log({operation:"player_interface_click",param:e})}logNextMovie(e){this.log({operation:"next_movie",param:String(e)})}subscribe(){this.resubscribeBeforeunload();let e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(Gt(ot(e,"change"),Yt(["init"])).subscribe(()=>this.updateContext({network:Ye(e.effectiveType)}))),this.config.debugLog&&this.debugLogger.log$.subscribe(i=>{console.debug("%c stat ","background:#fa6470;",`component: ${i.component}.`,i.message)})}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=ot(window,"beforeunload").subscribe(()=>this.logger.flush({wantBeacon:!0,clearStorage:this.config.clearStorageAtUnload})),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(e){this.log({operation:"player_ready",param:String(Math.round(e.duration))})}logActionPlay(e){this.log({operation:"action_play",param:String(Math.round(e.position))})}logActionPlayInteractive(){this.statContext.projectId&&this.log({operation:"action_play_interactive",param:String(this.statContext.movieId)},{vid:this.statContext.projectId})}logFailover(e){this.log({operation:"failover",param:e})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}logTrackSwitch(e){this.log({operation:"track_switch",param:e.id})}logQuality(e){this.log({operation:"quality",param:e})}log(e,i={}){if(this.disabled){this.oneStatDebugLog({message:`operation ${e.operation} but statistics is disabled`});return}if(this.config.disabledOperations.includes(e.operation)){this.oneStatDebugLog({message:`operation ${e.operation} but it is disabled`});return}this.oneStatDebugLog({message:`operation ${e.operation} ${e.param}`});let t=this.createLogItem(e,i);this.logger.log(t)}createLogItem({operation:e,param:i,time:t},o={}){let n=this.timeSynchronisation?.now()??x(),l=this.vsid$.getValue();jt(l);let c=this.isid$.getValue(),s=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,u,h;if(this.isEmbed||this.statContext.place==="embed"){u=this.embedParent;let p=[...new URLSearchParams(location.search).entries()].filter(([g,m])=>this.config.embedUrlParams.includes(g));h=new URLSearchParams(p).toString()}else if(this.statContext.place==="direct"){let p=this.statContext.refDomain||document.referrer;p&&URL.canParse(p)?u=new URL(p).hostname:u=p,h=location.href.substring(0,1024)}let d={vsid:l,isid:c,vid:this.statContext.movieId,uid:this.zenUid$.getValue(),ct:this.statContext.contentType,place:this.isEmbed?"embed":this.statContext.place,quality:this.statContext.quality,cdn_host:this.statContext.cdnHostname,stat_type:this.statContext.autoplay===!0?"auto":this.statContext.autoplay===!1?"":void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:s,connection_reused:a===!0?1:a===!1?0:void 0,cached_data:this.statContext.cached===!0?1:this.statContext.cached===!1?0:void 0,live:this.statContext.liveEdge?1:void 0,muted:this.statContext.audible===!1?1:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:1,ref_domain:u,direct_url:h,rate:this.statContext.rate===1||rt(this.statContext.rate)?void 0:this.statContext.rate.toFixed(2),view_360:this.statContext.is3d?1:void 0,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId,...o};for(let p of this.config.disabledCustomFields)delete d[p];return{operation:e,type:1,time:t,network:this.statContext.network,timestamp:n,custom:d}}};var Tt={};$t(Tt,{SeekType:()=>X,ThinOneStat:()=>se,VERSION:()=>S});import{assertNonNullable as mi,detectEmbed as vi,fromEvent as bi,Logger as Ii,merge as $e,combine as yi,filter as Si,filterChanged as _i,safeStorage as _t,Subject as Pi,Subscription as De,ValueSubject as Re}from"@vkontakte/videoplayer-shared/evergreen";import{clientChecker as $,PlaybackState as Pt}from"@vkontakte/videoplayer-core/evergreen";import{fillWithDefault as ii}from"@vkontakte/videoplayer-shared/evergreen";var X=(c=>(c.SLIDER="slider",c.DOUBLE_TAP="double_tap",c.TIME_CODE="time_code",c.EPISODE="episode",c.REWIND="rewind",c.LIVE="live",c.UNKNOWN="unknown",c))(X||{});var dt="CIOPGQJGDIHBABABA",Pe={prod:"https://api.ok.ru",vk_alias:"https://api.mycdn.me",videotest:"https://videotestapi.ok.ru/api",test:"https://apitest.ok.ru",okcdn:"https://api.okcdn.ru",auto:""};var oi={apiKey:dt,apiEnv:"okcdn",requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageHeartbeatInterval:30,synchronizeTime:!0,useBeacon:!1,alwaysSendDesktop:!1},ct=r=>ii(r,oi);import{getExponentialDelay as ri,ErrorCategory as V,ValueSubject as si}from"@vkontakte/videoplayer-shared/evergreen";var J=class{constructor(e){this.params=e,this.authorized$=new si(!1),this.consequentAuthErrors=0}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this.authorizeWithBackoff()}logBeacon(e){let i="log.logUvStat",t=this.createLogParams(e),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,t,o)||this.logRequest(e).catch(()=>{})}async logRequest(e){let i="log.logUvStat",t=this.createLogParams(e),o={},n=this.sessionKey??await this.authorizeWithBackoff();if(!n)return;let l=async(c,s=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,n,o)}catch(a){if(!a||!("error_code"in a)){this.params.error$.next({id:"logRequestUnknown",category:V.NETWORK,message:`Unknown ${i} error`,thrown:a});return}let u=a?.error_code;switch(u){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this.authorizeWithBackoff(),s>0?l(c,s-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this.authorizeWithBackoff(),s>0?l(c,s-1):void 0;default:{this.params.error$.next({id:`LogRequest#${u}`,category:V.EXTERNAL_API,message:`${i} error`,data:a});return}}}};return l(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){return{collector:"ok.mobile.apps.video",uv_stat_data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${S}`,platform:e[0].platform,product:e[0].product,events:e})}}authorizeWithBackoff(){if(!this.consequentAuthErrors)return this.doAuthorize();let e=ri(this.consequentAuthErrors);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(async()=>{try{let t=await this.doAuthorize();i(t)}catch(t){this.params.error$.next({id:"AuthorizeBackoff",category:V.NETWORK,message:"Otherwise unhandled error in authorization",thrown:t})}finally{this.backoffTimeoutId=0}},e))})}doAuthorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);let e="auth.anonymLogin",i={session_data:{version:2,device_id:this.params.deviceId,client_version:S.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(i.session_data.auth_token=this.authToken,i.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,i).then(t=>((!t||!t.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:V.EXTERNAL_API,message:"No session key",data:t}),this.sessionKey=t?.session_key??void 0,this.sessionKey)).catch(async t=>{this.sessionKey=void 0;let o=t?.error_code;switch(o){case 401:return this.authToken=await this.refreshAuthToken(),this.authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:V.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:V.NETWORK,message:"authorize error",thrown:t})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}};import{now as Ae,ErrorCategory as Z}from"@vkontakte/videoplayer-shared/evergreen";var ee=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=Pe[this.apiEnv],this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}sendBeacon(e,i,t){if(!window.Blob||!window.navigator.sendBeacon)return!1;let o=this.prepareQueryParams({method:e,queryParams:i,sessionKey:t}),n=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,n)}catch(l){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:Z.NETWORK,message:"Unhandled beacon error",thrown:l,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t,o){let n=Ae(),l=c=>{if(c instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(c.message)){this.params.error$.next({id:"Network",category:Z.NETWORK,message:"Request failed",thrown:c});return}this.params.error$.next({id:"ThinOneStat:ApiTransport:sendRequest",category:Z.NETWORK,message:"Unhandled request error",thrown:c,data:{method:e,params:i,sessionKey:t,time:Ae()-n}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded",...o},body:this.prepareQueryParams({method:e,queryParams:i,sessionKey:t})}).then(c=>{let s=Number(c.headers.get("content-length"))===0,a=new Date(c.headers.get("date")??"").getTime(),u=Ae()-n;if(isFinite(a)&&this.timeSynchronisation?.addServerTime(a,u),!s)return c.json().then(h=>Object.prototype.hasOwnProperty.call(h,"error_msg")?Promise.reject(h):h,l)},l)}async resolveApiBaseUrl(){if(this.apiEnv!=="auto"||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{let e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await fetch(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(e){return this.params.error$.next({id:"ThinOneStat:ApiTransport:resolveApiBaseUrl",category:Z.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),Pe.vk_alias}finally{this.isApiBaseUrlFetched=!0}}prepareQueryParams(e){let i=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&i.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([t,o])=>i.append(t,typeof o=="string"?o:JSON.stringify(o))),i}};import{ErrorCategory as ni,now as ai,safeStorage as q,debounceFn as lt}from"@vkontakte/videoplayer-shared/evergreen";var te="thinonestat_events",Ee=r=>e=>e.client_time+r>=ai(),ie=class{constructor(e){this.unsaltedStorage=[];this.isPaused=!1;this.isUrgent=e=>{let{event_name:i}=e;return["watch_coverage","watch_coverage_live","watched_n","playback_started"].includes(i)};this.params=e,this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.loggerDebugLog=e.debugLogger.createComponentLog("stat logger"),this.firstFlush=lt(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=q.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=lt(()=>this.safeFlush(),this.params.config.flushDebounceTime,{maxWait:i}),this.subscription=this.api.authorized$.subscribe(t=>{t&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:ni.WTF,message:String(e)||"Unknown logger error",thrown:e})}}readFromStorage(){let e=q.get(te);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}let i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(Ee(this.params.config.storageExpiration));q.set(te,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(Ee(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],q.set(te,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(Ee(this.params.config.storageExpiration));o.length?e[i]=o:delete e[i],this.loggerDebugLog({message:`${t.length} retrieved from storage, ${o.length} of them actual`})}q.set(te,JSON.stringify(e))}log(e){this.addToStorage(e),!this.isPaused&&(this.isUrgent(e)?this.flush():this.lastVsid!==e.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=e.vsid)}flush({wantBeacon:e,clearStorage:i}={wantBeacon:!1,clearStorage:!0}){let t=this.getFromStorage();t.length!==0&&(this.api.authorized$.getValue()?(e&&this.params.config.useBeacon?(this.loggerDebugLog({message:`Flushing ${t.length} events through beacon`}),this.api.logBeacon(t)):(this.loggerDebugLog({message:`Flushing ${t.length} events`}),this.api.logRequest(t)),i&&this.markStorageSent()):this.api.authorize(),this.firstFlush.cancel(),this.debouncedFlush.cancel())}pause(){this.isPaused=!0,this.debouncedFlush.cancel()}resume(){this.isPaused=!1,this.debouncedFlush()}destroy(){this.subscription.unsubscribe(),this.firstFlush.cancel(),this.debouncedFlush.cancel()}};function Te(){let r="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36),i=0,t,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?e[o]="-":o===14?e[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),t=i&15,i=i>>4,e[o]=r[o===19?t&3|8:t]);return e.join("")}var oe=class{constructor(e){this.offset=void 0;this.offset=e}getOffset(){return this.offset??0}setOffset(e){this.offset=e}now(){return Date.now()+(this.offset??0)}date(e=new Date){return e.setTime(e.getTime()+(this.offset??0)),e}addServerTime(e,i){let t=Date.now(),o=e-t-i/2;if(Math.abs(o)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(o):this.offset=Math.round(.2*o+(1-.2)*this.offset)}};import{PlaybackState as ut}from"@vkontakte/videoplayer-core/evergreen";import{Observable as di,Subscription as ci,ValueSubject as li,Subject as we,fromEvent as ui,isNullable as ht,merge as W,filter as pt,filterChanged as gt}from"@vkontakte/videoplayer-shared/evergreen";var ft=(r,e,i)=>new di(t=>{let o=new ci,n=new li(void 0),l;o.add(r.info.isLive$.pipe(gt()).subscribe(w=>{l&&(l.unsubscribe(),n.next(void 0)),w?l=r.info.liveTime$.pipe(gt()).subscribe(n):l=r.info.position$.subscribe(n),o.add(l)}));let{playing$:c,paused$:s,ended$:a,looped$:u}=r.events,h=r.events.willSeek$.pipe(pt(()=>r.info.playbackState$.getValue()===ut.PLAYING)),d=r.events.seeked$.pipe(pt(()=>r.info.playbackState$.getValue()===ut.PLAYING)),p=!1,g=new we;o.add(h.subscribe(()=>{p||g.next(),p=!0})).add(d.subscribe(()=>p=!1));let m=W(ui(window,"beforeunload"),r.events.willDestruct$),v,y=()=>v=n.getValue(),T=()=>{let w=n.getValue();ht(v)||ht(w)||v===w||(t.next({from:v,to:w}),v=void 0)},_=new we,P=new we,f=W(c,g,_),R=W(s,d,m,a,u,P),Oe=e.started$&&e.ended$?W(f,e.ended$):f,Ve=e.started$&&e.ended$?W(R,e.started$):R;if(o.add(Oe.subscribe(y)).add(Ve.subscribe(T)),i.heartbeatInterval&&isFinite(i.heartbeatInterval)){let w=[],kt=i.heartbeatInterval*1e3,Ct=()=>{P.next(),_.next()};o.add(Oe.subscribe(()=>{let ae=window.setTimeout(Ct,kt);w.push(ae)})).add(Ve.subscribe(()=>{w.forEach(ae=>{window.clearTimeout(ae)}),w=[]}))}return o});import{Subscription as hi}from"@vkontakte/videoplayer-core/evergreen";import{Observable as pi}from"@vkontakte/videoplayer-shared/evergreen";var mt=(r,e)=>new pi(i=>{let t=new hi,o=0;return t.add(r.info.position$.subscribe(()=>{let n=e.getTotalViewTime()*1e3;n>o&&n%e.targetDuration===0&&(o=n,i.next({target_duration:e.targetDuration,current_tvt:n}))})),t});import{Observable as gi,Subscription as fi,merge as vt}from"@vkontakte/videoplayer-shared/evergreen";var bt=r=>new gi(e=>{let i=new fi,t=0,o=1,n=0,l=!1,c=!1,s=()=>{if(!l)return;let f=Date.now();n+=(f-t)*o,t=f},a=()=>{(!l||c)&&(t=Date.now(),l=!0,c=!1)},u=()=>{l&&(s(),l=!1)},h=()=>{l&&(s(),l=!1,c=!0)},d=f=>{l&&s(),o=f,t=Date.now()},{started$:p,playing$:g,paused$:m,willSeek$:v,ended$:y,willDestruct$:T}=r.events,{currentPlaybackRate$:_}=r.info;i.add(v.subscribe(h)).add(vt(p,g).subscribe(a)).add(vt(m,y,T).subscribe(u)).add(_.subscribe(d));let P=()=>{let f=n;return l&&(f+=(Date.now()-t)*o),Math.floor(f/1e3)};return e.next(P),i});import{assertNever as It}from"@vkontakte/videoplayer-shared/evergreen";import{HttpConnectionType as xe,Surface as M,VideoFormat as b,VideoQuality as E}from"@vkontakte/videoplayer-core/evergreen";var ke=r=>r&&{[xe.HTTP1]:"http1",[xe.HTTP2]:"http2",[xe.QUIC]:"http3"}[r],Ce=r=>{if(r!==void 0)switch(r){case b.MPEG:return"MP4";case b.DASH:case b.DASH_LIVE:return"DASH";case b.DASH_SEP:return"DASH_SEP";case b.DASH_ONDEMAND:return"ONDEMAND_DASH";case b.HLS_ONDEMAND:return"ONDEMAND_HLS";case b.HLS:case b.HLS_LIVE:return"HLS";case b.HLS_FMP4:return"HLS_FMP4";case b.DASH_WEBM:case b.DASH_LIVE_WEBM:return"WEBM";case b.DASH_LIVE_CMAF:return"ONDEMAND_DASH_LIVE";case b.HLS_LIVE_CMAF:return"ONDEMAND_HLS_LIVE";case b.WEB_RTC_LIVE:return"WEBRTC";case b.DASH_WEBM_AV1:return"AV1";case b.DASH_STREAMS:return"MULTI_DASH";default:return It(r)}},C=r=>{if(r!==void 0)switch(r){case E.Q_144P:return"144p";case E.Q_240P:return"240p";case E.Q_360P:return"360p";case E.Q_480P:return"480p";case E.Q_720P:return"720p";case E.Q_1080P:return"1080p";case E.Q_1440P:return"1440p";case E.Q_2160P:return"2160p";case E.INVARIANT:case E.Q_576P:case E.Q_4320P:return"UNKNOWN";default:return It(r)}},yt=r=>{if(r!==void 0)switch(r){case"MP4":case"ONDEMAND_DASH":case"ONDEMAND_DASH_LIVE":case"ONDEMAND_HLS":case"ONDEMAND_HLS_LIVE":case"MULTI_DASH":case"WEBM":case"AV1":return"vod";case"DASH":case"HLS":case"HLS_FMP4":case"WEBRTC":return"live";default:return}},L=(r,e,i)=>{if(r&&e)switch(r){case b.MPEG:return i&&e[r]&&e[r][i];default:return e[r]?.url}},Le=(r,e=!1)=>{if(e)return"minimal";if(r!==void 0)switch(r){case M.NONE:return;case M.INLINE:return"inline";case M.FULLSCREEN:return"fullscreen";case M.SECOND_SCREEN:return"chromecast";case M.PIP:return"pip_external"}},re=r=>{if(r!==void 0)return r===M.INVISIBLE?"background":"foreground"};var St=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");var Ai="_thin-one-stat_",At=`${Ai}deviceId`,Et=()=>{let r=new De;return{subscription:r,subscribe:(e,i)=>{e&&r.add(e.subscribe(i))}}},se=class{constructor(e,i){this.debugLogger=new Ii;this.thinOneStatDebugLog=this.debugLogger.createComponentLog("ThinOneStat");this.eventNumber=1;this.playerSize={width:0,height:0};this.seekAction$=new Re("unknown");this.isid$=new Re(void 0);this.statContext=e,this.config=ct(i.config??{}),this.subscription=new De,this.config.synchronizeTime&&(this.timeSynchronisation=new oe);let t=new Pi,o=_t.get(At);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=Te(),_t.set(At,this.deviceId)),this.statContext.targetDuration?this.targetDuration=this.statContext.targetDuration:this.targetDuration=1e3,this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??St());let n=new ee({error$:t,config:this.config,timeSynchronisation:this.timeSynchronisation});this.api=new J({config:this.config,apiTransport:n,error$:t,deviceId:this.deviceId,refreshAuthToken:i.refreshAuthToken}),this.logger=new ie({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:l,topOrigin:c}=vi();this.isEmbed=l,this.embedHostname=c?new URL(c).hostname:void 0}get vsid$(){return new Re(k.getVSID())}authorize(e){return this.api.authorize(e)}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e,i){let t=new De,o=(s,a)=>t.add(s.subscribe(a));o(bt(e),s=>{this.getTotalViewTime=s}),o(e.info.isLive$,s=>this.isLive=s),o(e.info.position$,s=>this.position=s);let n;o(e.info.hostname$,s=>{n!==void 0&&n!==s&&this.logFailover({cdn_host:s});let u={cdn_host:s,connection_type:ke(e.info.httpConnectionType$.getValue()),connection_reused:e.info.httpConnectionReused$.getValue()};this.logCdnHostChanged(u),this.cdnHostname=n=s}),o(e.info.httpConnectionType$,s=>{this.connectionType=ke(s)}),o(e.info.httpConnectionReused$,s=>{this.connectionReused=s}),o(ft(e,i,{heartbeatInterval:this.config.watchCoverageHeartbeatInterval}),s=>{let a=Math.round(s.from*1e3),u=Math.round(s.to*1e3),h={watch_interval:`${a}-${u}`,in_history:!!this.statContext.inHistory,content_type:Ce(e.info.currentFormat$.getValue()),playback_quality:C(e.info.currentQuality$.getValue()),recom_info:this.statContext.recomInfo};if(!e.info.isLive$.getValue())this.logWatchCoverage(h);else{let p=e.info.atLiveEdge$.getValue();this.logWatchCoverageLive({...h,live:!!p})}}),o(mt(e,{targetDuration:this.targetDuration,getTotalViewTime:this.getTotalViewTime}),s=>{this.logWatchedN(s)}),o($e(e.events.willStart$,e.events.looped$),s=>{s&&this.resetViewSession();let a={isid:this.isid$.getValue(),stream_profile:yt(Ce(e.info.currentFormat$.getValue())),dpi:$.display.pixelRatio,web_layout:$.device.isMobile?"mobile":"desktop",preloaded:this.statContext.preload,navigation:this.statContext.navigation,recom_info:this.statContext.recomInfo};this.isEmbed&&(a.iframe_host=this.embedHostname??"unknown"),this.logStartSession(a)}),o(e.events.willReady$,()=>{if(this.statContext.preload){let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentBuffer$.getValue(),h=e.info.currentQuality$.getValue(),d={target_buffer_time:u?u.end-u.start:void 0,playback_url:L(s,a,h),playback_quality:C(h)};this.logPreloadStarted(d)}}),o(e.events.ready$,()=>{let s=e.info.currentBuffer$.getValue();if(this.statContext.preload){let a={buffer_time:s?s.end-s.start:void 0};this.logPreloadEnded(a)}this.logReady({buffer_time:s?s.end-s.start:void 0})}),o($e(e.events.fetcherRecoverableError$,e.events.fatalError$),()=>{this.statContext.preload&&this.logPreloadError()}),o(e.events.playing$,()=>{this.logPlay()}),o(e.events.manifestRequested$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logManifestRequest(h)}),o(e.events.firstBytesRequested$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logFirstMediaRequest(h)}),o(e.events.firstBytesReceived$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logFirstByteMedia(h)}),o(e.events.manifestReceived$,()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused};this.logManifestReceived(h)}),o(yi({connectionType:e.info.httpConnectionType$,connectionReused:e.info.httpConnectionReused$}).pipe(Si(({connectionReused:s})=>s!==void 0),_i((s,a)=>s.connectionType===a.connectionType)),()=>{let s=e.info.currentFormat$.getValue(),a=e.info.availableSources$.getValue(),u=e.info.currentQuality$.getValue(),h={playback_url:L(s,a,u),cdn_host:this.cdnHostname,connection_type:this.connectionType,connection_reused:this.connectionReused,rtt:e.info.rttEstimation$.getValue()};this.logConnectionEstablished(h)}),o(e.events.firstFrame$,()=>{this.logFirstVideoFrameDecoded()}),o(e.info.playbackState$,s=>{if(s===Pt.PLAYING){let a=e.info.currentBuffer$.getValue(),u={buffer_time:a?a.end-a.start:void 0};if(this.logPlaying(u),this.isStarted)this.logResume();else{this.isStarted=!0;let h=e.info.currentQuality$.getValue(),d=e.info.isAutoQualityEnabled$.getValue(),p=e.info.muted$.getValue(),g=e.info.volume$.getValue(),m=e.info.surface$.getValue(),v=e.info.availableTextTracks$.getValue(),y=e.info.currentTextTrack$.getValue(),T=e.info.currentAudioStream$.getValue(),_=e.info.currentPlaybackRate$.getValue(),P={playback_quality:C(h),user_quality:d?"auto":C(h),player_width:this.playerSize.width,player_height:this.playerSize.height,muted:p,sound_volume:g,buffer_time:a?Math.round(a.end-a.start):void 0,mode:Le(m,this.statContext.isPreviewPlayerView),visibility:re(m),subtitles_enabled:!!y,auto_subtitles:!!v.find(({id:f})=>f===y)?.isAuto,audio_track_lang:T?.language,playback_rate:_,recom_info:this.statContext.recomInfo};this.logPlaybackStarted(P)}}else s===Pt.PAUSED&&this.logPause()}),o(e.events.willSeek$,({to:s})=>{let a={target_position:s,seek_type:this.seekAction$.getValue()};this.logSeeking(a)}),o(e.events.seeked$,()=>{let a={target_position:e.info.position$.getValue(),seek_type:this.seekAction$.getValue()};this.logSeeked(a),this.seekAction$.next("unknown")}),o($e(e.info.isBuffering$,e.info.isStalled$),s=>{if(s){let a=e.info.currentBuffer$.getValue();this.logBufferStarvation({buffer_time:a?a.end-a.start:void 0}),this.logShowLoader()}}),o(e.info.currentQuality$,s=>{if(s){let a=e.info.isAutoQualityEnabled$.getValue(),u=e.info.currentVideoStream$.getValue()?.codec,h=e.info.currentAudioStream$.getValue()?.codec,d={user_quality:a?"auto":C(s),playback_quality:C(s),download_quality:C(s),codec_info:u&&h?`${u},${h}`:void 0,manual_switch:!a};this.logQualityChanged(d)}});let l,c;return o(e.info.surface$,s=>{this.logModeChanged({mode:Le(s,this.statContext.isPreviewPlayerView)}),c=re(s),l!==c&&(l=re(s),this.logVisibilityChanged({visibility:c}))}),o(e.events.stopped$,()=>{this.logStop()}),this.player=e,this.resubscribeBeforeunload(),this.subscription.add(t),t}attachToUi(e){let{subscribe:i,subscription:t}=Et();return i(e.actionSeek$,this.seekAction$),i(e.playerSize$,({width:o,height:n})=>{this.playerSize={width:o,height:n},this.logViewPortChanged({player_width:o,player_height:n})}),this.resubscribeBeforeunload(),this.subscription.add(t),t}attachToAds(e){let{subscription:i,subscribe:t}=Et();return t(e.init$,o=>{let n={slot:o};this.logAdvConfiguration(n)}),t(e.slotRequested$,()=>{this.logAdvRequest()}),t(e.started$,o=>{let n={adv_section:o};this.logAdvBreakStarted(n)}),t(e.ended$,o=>{let n={adv_section:o};this.logAdvBreakEnded(n)}),t(e.error$,o=>{let n={error_message:o};this.logAdvError(n)}),this.resubscribeBeforeunload(),this.subscription.add(i),i}getDeviceId(){return this.deviceId}resetViewSession(){this.thinOneStatDebugLog({message:"VSID reset"}),k.generateVSID(),this.eventNumber=0}destroy(){this.api.destroy()}createRequiredParams(e){let i=this.vsid$.getValue();mi(i);let t=this.eventNumber++;return{vsid:i,uv_movie_id:this.statContext.movieId,event_name:e,client_time:Date.now(),application:`@vkontakte/videoplayer-statistics:${S}`,platform:`web:${$.device.isMobile?"mobile":"desktop"}`,product:this.statContext.product,event_number:t,playback_position:this.isLive?void 0:Math.round(this.position),current_tvt:this.getTotalViewTime(),cdn_host:this.cdnHostname}}createRequiredFatParams(){return{stats_version:"2.1.1",browser:$.browser.current,browser_version:String($.browser.currentVersion),os:$.device.current,os_version:"",device_type:$.device.isMobile?"mobile":"desktop",navigation:this.statContext.navigation}}log(e,i,t=!1){let o=this.createRequiredParams(e),n={};t&&(n=this.createRequiredFatParams()),this.logger.log({...o,...n,...i})}logWatchCoverage(e){this.log("watch_coverage",e,!0)}logWatchCoverageLive(e){this.log("watch_coverage_live",e,!0)}logWatchedN(e){this.log("watched_n",e,!0)}logStartSession(e){this.log("start_session",e,!0)}logPreloadStarted(e){this.log("preload_started",e)}logPreloadEnded(e){this.log("preload_ended",e)}logPreloadError(){this.log("preload_error")}logPlaybackStarted(e){this.log("playback_started",e,!0)}logPlay(){this.log("play")}logManifestRequest(e){this.log("manifest_request",e)}logFirstMediaRequest(e){this.log("first_media_request",e)}logFirstByteMedia(e){this.log("first_byte_media",e)}logManifestReceived(e){this.log("manifest_received",e)}logConnectionEstablished(e){this.log("connection_established",e)}logFirstVideoFrameDecoded(){this.log("first_video_frame_decoded")}logReady(e){this.log("ready",e)}logPlaying(e){this.log("playing",e)}logPause(){this.log("pause")}logResume(){this.log("resume")}logSeeking(e){this.log("seeking",e)}logSeeked(e){this.log("seeked",e)}logStop(){this.log("stop")}logBufferStarvation(e){this.log("buffer_starvation",e)}logShowLoader(){this.log("show_loader")}logQualityChanged(e){this.log("quality_changed",e)}logCdnHostChanged(e){this.log("cdn_host_changed",e)}logViewPortChanged(e){this.log("view_port_changed",e)}logModeChanged(e){this.log("mode_changed",e)}logVisibilityChanged(e){this.log("visibility_changed",e)}logFailover(e){this.log("failover",e)}logAdvConfiguration(e){this.log("adv_configuration",e)}logAdvRequest(){this.log("adv_request")}logAdvBreakStarted(e){this.log("adv_break_started",e)}logAdvBreakEnded(e){this.log("adv_break_ended",e)}logAdvError(e){this.log("adv_error",e)}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=bi(window,"beforeunload").subscribe(()=>{}),this.subscription.add(this.beforeunloadSubscription)}};var Ei={};import{PlaybackState as xt,Subscription as Ti}from"@vkontakte/videoplayer-core/evergreen";import{Logger as wi}from"@vkontakte/videoplayer-shared/evergreen";var ne=class{constructor(){this.startTime=null;this.stopTime=null;this.accumulatedTime=0}get time(){return Math.floor(this.timeMs/1e3)}get timeMs(){return this.startTime===null?0:(this.stopTime??this.now())-this.startTime-this.accumulatedTime}get isRunning(){return this.startTime!==null&&this.stopTime===null}start(){this.isRunning||(this.stopTime!==null?(this.accumulatedTime+=this.now()-this.stopTime,this.stopTime=null):this.startTime=this.now())}stop(){this.isRunning&&(this.stopTime=this.now())}reset(){this.startTime=null,this.stopTime=null,this.accumulatedTime=0}now(){return Date.now()}};var wt=()=>window.Image?new Image:document.createElement("img");var Ne=class{constructor(e){this.position=0;this.started=!1;this.heartbeatPixels=[];this.heartbeatLastTimeSent={};this.idleCallbackIds=[];this.stopwatch=new ne;this.subscription=new Ti;this.params=e;let i=new wi;this.log=i.createComponentLog("MediascopePixel")}attachTo(e){this.subscription.add(e.info.playbackState$.subscribe(i=>this.onPlaybackState(i))).add(e.info.position$.subscribe(i=>this.onPosition(i))).add(e.info.atLiveEdge$.subscribe(i=>this.isActiveLive=i)),this.subscription.add(e.events.willSeek$.subscribe(()=>this.onWillSeek())).add(e.events.seeked$.subscribe(()=>this.onSeeked())).add(e.events.ended$.subscribe(()=>this.onEnded()))}destroy(){this.stopwatch.reset(),this.subscription.unsubscribe(),window.clearTimeout(this.heartbeatFirstTimeoutId),this.idleCallbackIds.forEach(e=>window.cancelIdleCallback(e)),this.send("stop")}onPlaybackState(e){e===xt.PLAYING?this.started?this.play():this.start():e===xt.PAUSED&&this.pause()}start(){this.started=!0,this.stopwatch.start(),this.send("start"),this.heartbeatPixels=this.prepareHeartbeatPixels(),this.heartbeatInterval=this.heartbeatPixels[0]?.interval;let e=this.heartbeatPixels[0]?.url,i=this.heartbeatPixels[0]?.delay;if(i!==void 0&&e)try{this.heartbeatFirstTimeoutId=window.setTimeout(()=>{this.sendHeartbeat(e)},i*1e3)}catch(t){this.log({message:t.message})}}play(){this.stopwatch.start(),this.send("resume")}pause(){this.stopwatch.stop(),this.send("pause")}onPosition(e){if(this.position=e,this.heartbeatInterval&&this.stopwatch.time!==0&&this.stopwatch.time%this.heartbeatInterval===0)for(let[i,{url:t}]of this.heartbeatPixels.entries())this.heartbeatLastTimeSent[i]!==this.stopwatch.time&&(this.heartbeatLastTimeSent[i]=this.stopwatch.time,this.sendHeartbeat(t))}onWillSeek(){this.started&&this.send("stop")}onSeeked(){this.started&&this.send("start")}onEnded(){this.stopwatch.stop(),this.send("stop")}validatePixels(e,i){return e?.filter(t=>t.event===i.event&&i.keys.every(o=>!!t[o]))}getFrameTimestamp(){let e;if(this.isActiveLive){let i=Math.floor(Math.random()*25)+5;e=Date.now()/1e3-i}else e=this.position||0;return Math.floor(e)}getUTC(){return Math.floor(Date.now()/1e3)}prepareUrl(e){let i=new URL(e);return i.pathname=i.pathname.replace("{@fts_fake_sec}",String(this.getFrameTimestamp())).replace("{@utc_sec}",String(this.getUTC())),i.search=[...new URLSearchParams(i.search)].filter(([t,o])=>!/={@[\w]+}/.test(`${t}=${o}`)).map(t=>t.join("=")).join("&"),i.toString()}preparePixels(e){return this.validatePixels(this.params.pixels,{event:e,keys:["url"]})}prepareHeartbeatPixels(){return this.validatePixels(this.params.pixels,{event:"heartbeat",keys:["url","interval"]})}call(e){try{this.idleCallbackIds.push(requestIdleCallback(()=>wt().src=this.prepareUrl(e)))}catch(i){this.log({message:i.message})}}send(e){let i=this.preparePixels(e);for(let{url:t}of i)this.call(t)}sendHeartbeat(e){this.call(e)}};export{F as ApiEnv,le as ConnectionType,ce as ContentType,Me as InteractiveInterfaceClick,Ne as MediascopePixel,Ei as MediascopePixelTypes,_e as OneStat,de as Quality,ue as SeekAction,Tt as ThinOneStat,S as VERSION};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vkontakte/videoplayer-statistics",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.84-beta.0",
|
|
4
4
|
"author": "vk.com",
|
|
5
5
|
"description": "Statistics library for vk.com videoplayer",
|
|
6
6
|
"homepage": "https://vk.com",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"**/*.d.ts"
|
|
55
55
|
],
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@vkontakte/videoplayer-core": "2.0.
|
|
58
|
-
"@vkontakte/videoplayer-shared": "1.0.
|
|
57
|
+
"@vkontakte/videoplayer-core": "2.0.138-beta.0",
|
|
58
|
+
"@vkontakte/videoplayer-shared": "1.0.66-beta.0"
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -237,6 +237,10 @@ export interface IStatContext {
|
|
|
237
237
|
refDomain?: string;
|
|
238
238
|
inHistory?: boolean;
|
|
239
239
|
deviceId?: string;
|
|
240
|
+
/**
|
|
241
|
+
* Плеер в режиме превью.
|
|
242
|
+
*/
|
|
243
|
+
isPreviewPlayerView?: boolean;
|
|
240
244
|
}
|
|
241
245
|
export interface IConstructorParams {
|
|
242
246
|
/** @deprecated Используете config.apiEnv */
|
|
@@ -270,7 +274,7 @@ export declare class OneStat implements IOneStat {
|
|
|
270
274
|
experimental: {
|
|
271
275
|
error$: IObservable<IError>;
|
|
272
276
|
};
|
|
273
|
-
vsid
|
|
277
|
+
get vsid$(): ValueSubject<string | undefined>;
|
|
274
278
|
isid$: ValueSubject<string | undefined>;
|
|
275
279
|
zenUid$: ValueSubject<string | undefined>;
|
|
276
280
|
private statContext;
|
|
@@ -3,5 +3,5 @@ import { ConnectionType as StatisticsConnectionType, ContentType, Mode, Network,
|
|
|
3
3
|
export declare const quality: (coreQuality: VideoQuality | undefined) => Quality | undefined;
|
|
4
4
|
export declare const connectionType: (coreType: CoreConnectionType | undefined) => StatisticsConnectionType | undefined;
|
|
5
5
|
export declare const contentType: (format: VideoFormat | undefined) => ContentType | undefined;
|
|
6
|
-
export declare const surface: (surface: Surface | undefined) => Mode | undefined;
|
|
6
|
+
export declare const surface: (surface: Surface | undefined, isPreviewPlayerView?: boolean) => Mode | undefined;
|
|
7
7
|
export declare const network: (effectiveType: "slow-2g" | "2g" | "3g" | "4g" | string) => Network | undefined;
|
|
@@ -26,6 +26,7 @@ export declare enum ContentType {
|
|
|
26
26
|
DASH_SEP = "dash_sep",
|
|
27
27
|
ONDEMAND_DASH = "ondemand_dash",
|
|
28
28
|
HLS = "hls",
|
|
29
|
+
HLS_FMP4 = "hls_fmp4",
|
|
29
30
|
ONDEMAND_HLS = "ondemand_hls",
|
|
30
31
|
WEBM = "webm",
|
|
31
32
|
AV1 = "av1",
|
|
@@ -61,7 +62,8 @@ export declare enum Mode {
|
|
|
61
62
|
PREFETCH = "prefetch",
|
|
62
63
|
AIRPLAY = "airplay",
|
|
63
64
|
CHROMECAST = "chromecast",
|
|
64
|
-
INVISIBLE = "invisible"
|
|
65
|
+
INVISIBLE = "invisible",
|
|
66
|
+
MINIMAL = "minimal"
|
|
65
67
|
}
|
|
66
68
|
export declare enum SeekAction {
|
|
67
69
|
SLIDER = "slider",
|
|
@@ -2,8 +2,8 @@ import type { ISubscription, IValueObservable, Milliseconds, Seconds } from '@vk
|
|
|
2
2
|
import { ValueSubject } from '@vkontakte/videoplayer-shared';
|
|
3
3
|
import type { IPlayer } from '@vkontakte/videoplayer-core';
|
|
4
4
|
import type { IOptionalConfig } from './config';
|
|
5
|
-
import { Mode, Quality, SeekType, AutoQuality, Visibility } from './values';
|
|
6
|
-
import type { IUIEvents } from './
|
|
5
|
+
import { Mode, Quality, SeekType, AutoQuality, Visibility, ConnectionType } from './values';
|
|
6
|
+
import type { IAdsEvents, IUIEvents } from './events';
|
|
7
7
|
export interface IThinOneStat {
|
|
8
8
|
vsid$: IValueObservable<string | undefined>;
|
|
9
9
|
isid$: IValueObservable<string | undefined>;
|
|
@@ -21,8 +21,9 @@ export interface IThinOneStat {
|
|
|
21
21
|
/**
|
|
22
22
|
* Привязываемся к событиям и разным изменениям состояний плеера
|
|
23
23
|
*/
|
|
24
|
-
attachTo(player: IPlayer): ISubscription;
|
|
24
|
+
attachTo(player: IPlayer, adsEvents: IAdsEvents): ISubscription;
|
|
25
25
|
attachToUi(uiEvents: IUIEvents): ISubscription;
|
|
26
|
+
attachToAds(adsEvents: IAdsEvents): ISubscription;
|
|
26
27
|
/**
|
|
27
28
|
* Идентификатор текущего устройства
|
|
28
29
|
*/
|
|
@@ -36,10 +37,15 @@ export interface IStatContext {
|
|
|
36
37
|
movieId?: number;
|
|
37
38
|
deviceId?: string;
|
|
38
39
|
preload?: boolean;
|
|
40
|
+
targetDuration?: Milliseconds;
|
|
39
41
|
inHistory?: boolean;
|
|
40
42
|
recomInfo?: Record<string, unknown>;
|
|
41
43
|
product?: string;
|
|
42
44
|
navigation?: Record<string, unknown>;
|
|
45
|
+
/**
|
|
46
|
+
* Плеер в режиме превью.
|
|
47
|
+
*/
|
|
48
|
+
isPreviewPlayerView?: boolean;
|
|
43
49
|
}
|
|
44
50
|
export interface IConstructorParams {
|
|
45
51
|
config: IOptionalConfig;
|
|
@@ -97,6 +103,40 @@ export interface IPlaybackStartedPayload {
|
|
|
97
103
|
playback_rate?: number;
|
|
98
104
|
recom_info?: Record<string, unknown>;
|
|
99
105
|
}
|
|
106
|
+
export interface IManifestRequestPayload {
|
|
107
|
+
playback_url?: string;
|
|
108
|
+
cdn_host?: string;
|
|
109
|
+
connection_type?: ConnectionType;
|
|
110
|
+
connection_reused?: boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface IFirstMediaRequestPayload {
|
|
113
|
+
playback_url?: string;
|
|
114
|
+
cdn_host?: string;
|
|
115
|
+
connection_type?: ConnectionType;
|
|
116
|
+
connection_reused?: boolean;
|
|
117
|
+
}
|
|
118
|
+
export interface IFirstByteMediaPayload {
|
|
119
|
+
playback_url?: string;
|
|
120
|
+
cdn_host?: string;
|
|
121
|
+
connection_type?: ConnectionType;
|
|
122
|
+
connection_reused?: boolean;
|
|
123
|
+
}
|
|
124
|
+
export interface IManifestReceivedPayload {
|
|
125
|
+
playback_url?: string;
|
|
126
|
+
cdn_host?: string;
|
|
127
|
+
connection_type?: ConnectionType;
|
|
128
|
+
connection_reused?: boolean;
|
|
129
|
+
}
|
|
130
|
+
export interface IConnectionEstablishedPayload {
|
|
131
|
+
playback_url?: string;
|
|
132
|
+
cdn_host?: string;
|
|
133
|
+
connection_type?: ConnectionType;
|
|
134
|
+
connection_reused?: boolean;
|
|
135
|
+
rtt?: Milliseconds;
|
|
136
|
+
}
|
|
137
|
+
export interface IReadyPayload {
|
|
138
|
+
buffer_time?: Milliseconds;
|
|
139
|
+
}
|
|
100
140
|
export interface IPlayingPayload {
|
|
101
141
|
buffer_time?: Milliseconds;
|
|
102
142
|
}
|
|
@@ -108,6 +148,9 @@ export interface ISeekedPayload {
|
|
|
108
148
|
target_position?: number;
|
|
109
149
|
seek_type?: SeekType;
|
|
110
150
|
}
|
|
151
|
+
export interface IBufferStarvationPayload {
|
|
152
|
+
buffer_time?: Milliseconds;
|
|
153
|
+
}
|
|
111
154
|
export interface IQualityChangedPayload {
|
|
112
155
|
user_quality?: Quality | AutoQuality;
|
|
113
156
|
playback_quality?: Quality | AutoQuality;
|
|
@@ -115,9 +158,36 @@ export interface IQualityChangedPayload {
|
|
|
115
158
|
codec_info?: string;
|
|
116
159
|
manual_switch?: boolean;
|
|
117
160
|
}
|
|
161
|
+
export interface ICdnHostChangedPayload {
|
|
162
|
+
cdn_host?: string;
|
|
163
|
+
connection_type?: ConnectionType;
|
|
164
|
+
connection_reused?: boolean;
|
|
165
|
+
}
|
|
166
|
+
export interface IViewPortChangedPayload {
|
|
167
|
+
player_width?: number;
|
|
168
|
+
player_height?: number;
|
|
169
|
+
}
|
|
170
|
+
export interface IModeChangedPayload {
|
|
171
|
+
mode?: Mode;
|
|
172
|
+
}
|
|
173
|
+
export interface IVisibilityChangedPayload {
|
|
174
|
+
visibility?: Visibility;
|
|
175
|
+
}
|
|
118
176
|
export interface IFailoverPayload {
|
|
119
177
|
cdn_host?: string;
|
|
120
178
|
}
|
|
179
|
+
export interface IAdvConfigurationPayload {
|
|
180
|
+
slot?: number;
|
|
181
|
+
}
|
|
182
|
+
export interface IAdvBreakStartedPayload {
|
|
183
|
+
adv_section?: string;
|
|
184
|
+
}
|
|
185
|
+
export interface IAdvBreakEndedPayload {
|
|
186
|
+
adv_section?: string;
|
|
187
|
+
}
|
|
188
|
+
export interface IAdvErrorPayload {
|
|
189
|
+
error_message?: string;
|
|
190
|
+
}
|
|
121
191
|
export declare class ThinOneStat implements IThinOneStat {
|
|
122
192
|
private api;
|
|
123
193
|
private logger;
|
|
@@ -127,6 +197,7 @@ export declare class ThinOneStat implements IThinOneStat {
|
|
|
127
197
|
private timeSynchronisation?;
|
|
128
198
|
private statContext;
|
|
129
199
|
private deviceId;
|
|
200
|
+
private targetDuration;
|
|
130
201
|
private debugLogger;
|
|
131
202
|
private thinOneStatDebugLog;
|
|
132
203
|
private eventNumber;
|
|
@@ -136,16 +207,20 @@ export declare class ThinOneStat implements IThinOneStat {
|
|
|
136
207
|
private cdnHostname?;
|
|
137
208
|
private isEmbed;
|
|
138
209
|
private embedHostname?;
|
|
210
|
+
private connectionType?;
|
|
211
|
+
private connectionReused?;
|
|
212
|
+
private player;
|
|
213
|
+
private playerSize;
|
|
139
214
|
private seekAction$;
|
|
140
|
-
|
|
141
|
-
vsid$: ValueSubject<string | undefined>;
|
|
215
|
+
get vsid$(): ValueSubject<string | undefined>;
|
|
142
216
|
isid$: ValueSubject<string | undefined>;
|
|
143
217
|
getTotalViewTime: () => Seconds;
|
|
144
218
|
constructor(statContext: IStatContext, params: IConstructorParams);
|
|
145
219
|
authorize(authToken?: string): Promise<unknown>;
|
|
146
220
|
updateContext(newContext: Partial<IStatContext>): void;
|
|
147
|
-
attachTo(player: IPlayer): ISubscription;
|
|
221
|
+
attachTo(player: IPlayer, adsEvents: IAdsEvents): ISubscription;
|
|
148
222
|
attachToUi(events: IUIEvents): ISubscription;
|
|
223
|
+
attachToAds(events: IAdsEvents): ISubscription;
|
|
149
224
|
getDeviceId(): string;
|
|
150
225
|
resetViewSession(): void;
|
|
151
226
|
destroy(): void;
|
|
@@ -158,15 +233,34 @@ export declare class ThinOneStat implements IThinOneStat {
|
|
|
158
233
|
private logStartSession;
|
|
159
234
|
private logPreloadStarted;
|
|
160
235
|
private logPreloadEnded;
|
|
236
|
+
private logPreloadError;
|
|
161
237
|
private logPlaybackStarted;
|
|
162
238
|
private logPlay;
|
|
239
|
+
private logManifestRequest;
|
|
240
|
+
private logFirstMediaRequest;
|
|
241
|
+
private logFirstByteMedia;
|
|
242
|
+
private logManifestReceived;
|
|
243
|
+
private logConnectionEstablished;
|
|
244
|
+
private logFirstVideoFrameDecoded;
|
|
245
|
+
private logReady;
|
|
163
246
|
private logPlaying;
|
|
164
247
|
private logPause;
|
|
165
248
|
private logResume;
|
|
166
249
|
private logSeeking;
|
|
167
250
|
private logSeeked;
|
|
251
|
+
private logStop;
|
|
252
|
+
private logBufferStarvation;
|
|
168
253
|
private logShowLoader;
|
|
169
254
|
private logQualityChanged;
|
|
255
|
+
private logCdnHostChanged;
|
|
256
|
+
private logViewPortChanged;
|
|
257
|
+
private logModeChanged;
|
|
258
|
+
private logVisibilityChanged;
|
|
170
259
|
private logFailover;
|
|
260
|
+
private logAdvConfiguration;
|
|
261
|
+
private logAdvRequest;
|
|
262
|
+
private logAdvBreakStarted;
|
|
263
|
+
private logAdvBreakEnded;
|
|
264
|
+
private logAdvError;
|
|
171
265
|
private resubscribeBeforeunload;
|
|
172
266
|
}
|
|
@@ -7,3 +7,10 @@ export interface IUIEvents {
|
|
|
7
7
|
height: number;
|
|
8
8
|
}>;
|
|
9
9
|
}
|
|
10
|
+
export interface IAdsEvents {
|
|
11
|
+
init$?: IObservable<number>;
|
|
12
|
+
slotRequested$?: IObservable<void>;
|
|
13
|
+
started$?: IObservable<string>;
|
|
14
|
+
ended$?: IObservable<string>;
|
|
15
|
+
error$?: IObservable<string>;
|
|
16
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ISources, Surface, VideoFormat, VideoQuality } from '@vkontakte/videoplayer-core';
|
|
2
|
-
import { ContentType, Mode, Quality, StreamingProfile, Visibility } from '../values';
|
|
1
|
+
import { HttpConnectionType as CoreConnectionType, ISources, Surface, VideoFormat, VideoQuality } from '@vkontakte/videoplayer-core';
|
|
2
|
+
import { ConnectionType as StatisticsConnectionType, ContentType, Mode, Quality, StreamingProfile, Visibility } from '../values';
|
|
3
|
+
export declare const connectionType: (coreType?: CoreConnectionType) => StatisticsConnectionType | undefined;
|
|
3
4
|
export declare const contentType: (format?: VideoFormat) => ContentType | undefined;
|
|
4
5
|
export declare const quality: (coreQuality?: VideoQuality) => Quality | undefined;
|
|
5
6
|
export declare const streamingProfile: (contentType?: ContentType) => StreamingProfile | undefined;
|
|
6
7
|
export declare const formatUrl: (format?: VideoFormat, sources?: ISources, quality?: VideoQuality) => string | undefined;
|
|
7
|
-
export declare const mode: (surface?: Surface) => Mode | undefined;
|
|
8
|
+
export declare const mode: (surface?: Surface, isPreviewPlayerView?: boolean) => Mode | undefined;
|
|
8
9
|
export declare const visibility: (surface?: Surface) => Visibility | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { IPlayer } from '@vkontakte/videoplayer-core';
|
|
2
2
|
import type { Seconds, IObservable, IRange } from '@vkontakte/videoplayer-shared';
|
|
3
|
+
import { IAdsEvents } from '../events';
|
|
3
4
|
export type IParams = {
|
|
4
5
|
heartbeatInterval?: Seconds;
|
|
5
6
|
};
|
|
6
|
-
export declare const watchCoverage: (player: IPlayer, params: IParams) => IObservable<IRange<Seconds>>;
|
|
7
|
+
export declare const watchCoverage: (player: IPlayer, adsEvents: IAdsEvents, params: IParams) => IObservable<IRange<Seconds>>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { IPlayer } from '@vkontakte/videoplayer-core';
|
|
2
|
-
import type { IObservable, Seconds } from '@vkontakte/videoplayer-shared';
|
|
2
|
+
import type { IObservable, Milliseconds, Seconds } from '@vkontakte/videoplayer-shared';
|
|
3
3
|
import { IWatchedNPayload } from '../ThinOneStat';
|
|
4
4
|
export type IParams = {
|
|
5
|
+
targetDuration: Milliseconds;
|
|
5
6
|
getTotalViewTime: () => Seconds;
|
|
6
7
|
};
|
|
7
8
|
export declare const watchedN: (player: IPlayer, params: IParams) => IObservable<IWatchedNPayload>;
|