@vkontakte/videoplayer-statistics 1.0.81-dev.5dab7ad1.0 → 1.0.81-dev.6c99e2bc.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.
Files changed (48) hide show
  1. package/es2015.cjs.js +3 -3
  2. package/es2015.esm.js +3 -3
  3. package/es2018.cjs.js +3 -3
  4. package/es2018.esm.js +3 -3
  5. package/es2024.cjs.js +3 -3
  6. package/es2024.esm.js +3 -3
  7. package/esnext.cjs.js +3 -3
  8. package/esnext.esm.js +3 -3
  9. package/evergreen.esm.js +3 -3
  10. package/package.json +3 -5
  11. package/types/index.d.ts +2 -8
  12. package/types/oneStat/index.d.ts +6 -0
  13. package/types/thinOneStat/Api.d.ts +38 -0
  14. package/types/thinOneStat/ApiTransport.d.ts +25 -0
  15. package/types/thinOneStat/Logger.d.ts +42 -0
  16. package/types/thinOneStat/ThinOneStat.d.ts +172 -0
  17. package/types/thinOneStat/config.d.ts +17 -0
  18. package/types/thinOneStat/env.d.ts +7 -0
  19. package/types/thinOneStat/index.d.ts +4 -0
  20. package/types/thinOneStat/types.d.ts +28 -0
  21. package/types/thinOneStat/uiEvents.d.ts +9 -0
  22. package/types/thinOneStat/utils/calculateTotalViewTime.d.ts +5 -0
  23. package/types/thinOneStat/utils/mappers.d.ts +8 -0
  24. package/types/thinOneStat/utils/timeSynchronisation.d.ts +10 -0
  25. package/types/thinOneStat/utils/uuid.d.ts +1 -0
  26. package/types/thinOneStat/utils/vsid.d.ts +2 -0
  27. package/types/thinOneStat/utils/watchCoverage.d.ts +6 -0
  28. package/types/thinOneStat/utils/watchedN.d.ts +7 -0
  29. package/types/thinOneStat/values.d.ts +74 -0
  30. package/types/MediascopePixel/MediascopePixel.d.ts +0 -38
  31. package/types/MediascopePixel/Stopwatch.d.ts +0 -12
  32. package/types/MediascopePixel/types.d.ts +0 -9
  33. package/types/MediascopePixel/utils/image.d.ts +0 -1
  34. /package/types/{OneStat → oneStat}/Api.d.ts +0 -0
  35. /package/types/{OneStat → oneStat}/ApiTransport.d.ts +0 -0
  36. /package/types/{OneStat → oneStat}/Logger.d.ts +0 -0
  37. /package/types/{OneStat → oneStat}/OneStat.d.ts +0 -0
  38. /package/types/{OneStat → oneStat}/config.d.ts +0 -0
  39. /package/types/{OneStat → oneStat}/env.d.ts +0 -0
  40. /package/types/{OneStat → oneStat}/types.d.ts +0 -0
  41. /package/types/{OneStat → oneStat}/uiEvents.d.ts +0 -0
  42. /package/types/{OneStat → oneStat}/utils/mappers.d.ts +0 -0
  43. /package/types/{OneStat → oneStat}/utils/shorten.d.ts +0 -0
  44. /package/types/{OneStat → oneStat}/utils/timeSynchronisation.d.ts +0 -0
  45. /package/types/{OneStat → oneStat}/utils/uuid.d.ts +0 -0
  46. /package/types/{OneStat → oneStat}/utils/vsid.d.ts +0 -0
  47. /package/types/{OneStat → oneStat}/utils/watchCoverage.d.ts +0 -0
  48. /package/types/{OneStat → oneStat}/values.d.ts +0 -0
package/evergreen.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @vkontakte/videoplayer-statistics v1.0.81-dev.5dab7ad1.0
3
- * Fri, 20 Jun 2025 11:39:07 GMT
2
+ * @vkontakte/videoplayer-statistics v1.0.81-dev.6c99e2bc.0
3
+ * Tue, 01 Jul 2025 12:01:18 GMT
4
4
  * https://st.mycdn.me/static/vkontakte-videoplayer/1-0-81/doc/
5
5
  */
6
- var E=(a=>(a.PROD="prod",a.VK_ALIAS="vk_alias",a.VIDEOTEST="videotest",a.TEST="test",a.OKCDN="okcdn",a.AUTO="auto",a))(E||{}),H=(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))(H||{}),W=(d=>(d.MP4="mp4",d.DASH="dash",d.DASH_SEP="dash_sep",d.ONDEMAND_DASH="ondemand_dash",d.HLS="hls",d.ONDEMAND_HLS="ondemand_hls",d.WEBM="webm",d.AV1="av1",d.ONDEMAND_DASH_LIVE="ondemand_dash_live",d.ONDEMAND_HLS_LIVE="ondemand_hls_live",d.WEBRTC="webrtc",d.UNKNOWN="unknown",d.RTMP="rtmp",d))(W||{});var K=(t=>(t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3",t))(K||{});var q=(l=>(l.SLIDER="slider",l.DOUBLE_TAP="double_tap",l.TIME_CODE="time_code",l.EPISODE="episode",l.REWIND="rewind",l.LIVE="live",l.UNKNOWN="unknown",l))(q||{}),se=(n=>(n.GRAPH_SHOW="iGraphShow",n.GRAPH_HIDE="iGraphHide",n.NEXT_AREA="iNextChapterArea",n.NEXT_BUTTON="iNextChapterBtn",n.WATCH_AGAIN="iWatchAgainBtn",n))(se||{}),re={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"},ne={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"},ae={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},de={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"};import{fillWithDefault as $e}from"@vkontakte/videoplayer-shared/evergreen";var L="__VERSION__",le="CIOPGQJGDIHBABABA",z={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 Re={apiEnv:"vk_alias",apiKey:le,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}},ce=r=>$e(r,Re);function Q(){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 ze,combine as xe,fromEvent as _e,isNonNullable as _,isNullable as Ee,merge as Qe,now as v,observableFrom as je,once as Ge,safeStorage as M,Subject as Ye,Subscription as te,ValueSubject as V,createURL as Ae}from"@vkontakte/videoplayer-shared/evergreen";import{Logger as Xe,detectEmbed as Je}from"@vkontakte/videoplayer-shared/evergreen";var ue=r=>{let{operation:e,custom:i}=r,t=Object.fromEntries(Object.entries(i).map(([o,n])=>{let a=ne[o]??o,l=n;return n&&(o==="mode"?l=de[n]??n:o==="quality"&&(l=ae[n]??n)),[a,l]}));return{...r,operation:re[e]??e,custom:t}};import{ValueSubject as De,getExponentialDelay as Oe,ErrorCategory as P}from"@vkontakte/videoplayer-shared/evergreen";var Ne=/Mobile|mini|Fennec|Android|iP(ad|od|hone)|opera (mini|mobi)/i,A=class{constructor(e){this.consequentAuthErrors=0;this.authorized$=new De(!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(a,l=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,o)}catch(u){if(!u||!("error_code"in u)){this.params.error$.next({id:"logRequestUnknown",category:P.NETWORK,message:`Unknown ${i} error`,thrown:u});return}let c=u?.error_code;switch(c){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${c}`,category:P.EXTERNAL_API,message:`${i} error`,data:u});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:${L}`;if(this.params.config.useVKComIsMobileLogic){let{appVersion:n}=window.navigator;t=Ne.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(ue):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();let e=Oe(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:P.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:L.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:P.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:P.EXTERNAL_API,message:"authorize error",data:t}):this.params.error$.next({id:"AuthorizeUnknown",category:P.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 $,now as j}from"@vkontakte/videoplayer-shared/evergreen";var T=class{constructor(e){this.params=e,this.apiKey=e.config.apiKey,this.apiEnv=e.config.apiEnv,this.apiBaseUrl=z[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:$.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),z.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(a){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:$.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t){let o=j(),n=a=>{if(a instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(a.message)){this.params.error$.next({id:"Network",category:$.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:$.NETWORK,message:"Unhandled request error",thrown:a,data:{method:e,params:i,sessionKey:t,time:j()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:t})}).then(a=>{let l=Number(a.headers.get("content-length"))===0,u=new Date(a.headers.get("date")??"").getTime(),c=j()-o;if(isFinite(u)&&this.timeSynchronisation?.addServerTime(u,c),!l)return a.json().then(p=>Object.prototype.hasOwnProperty.call(p,"error_msg")?Promise.reject(p):p,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 Me,now as Ve,safeStorage as w,debounceFn as pe}from"@vkontakte/videoplayer-shared/evergreen";var R="onestat_events",G=r=>e=>e.timestamp+r>=Ve(),D=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=pe(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=w.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=pe(()=>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:Me.WTF,message:e?String(e):"Unknown logger error",thrown:e})}}readFromStorage(){let e=w.get(R);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(G(this.params.config.storageExpiration));w.set(R,JSON.stringify({...i,[this.userSalt]:[...o,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(G(this.params.config.storageExpiration)):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}let e=this.readFromStorage();delete e[this.userSalt],w.set(R,JSON.stringify(e))}housekeepStorage(){let e=this.readFromStorage();for(let[i,t]of Object.entries(e)){let o=t.filter(G(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`})}w.set(R,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 Y,Surface as x,VideoFormat as h,VideoQuality as m}from"@vkontakte/videoplayer-core/evergreen";import{assertNever as he}from"@vkontakte/videoplayer-shared/evergreen";var fe=r=>r&&{[m.INVARIANT]:"unknown",[m.Q_144P]:"mobile",[m.Q_240P]:"lowest",[m.Q_360P]:"low",[m.Q_480P]:"medium",[m.Q_576P]:"unknown",[m.Q_720P]:"high",[m.Q_1080P]:"fullhd",[m.Q_1440P]:"quadhd",[m.Q_2160P]:"ultrahd",[m.Q_4320P]:"unknown"}[r],X=r=>r&&{[Y.HTTP1]:"http1",[Y.HTTP2]:"http2",[Y.QUIC]:"http3"}[r],ge=r=>{if(r!==void 0)switch(r){case h.MPEG:return"mp4";case h.DASH:case h.DASH_LIVE:case h.DASH_STREAMS:return"dash";case h.DASH_SEP:return"dash_sep";case h.DASH_ONDEMAND:return"ondemand_dash";case h.DASH_WEBM:case h.DASH_LIVE_WEBM:return"webm";case h.DASH_WEBM_AV1:return"av1";case h.DASH_LIVE_CMAF:return"ondemand_dash_live";case h.HLS:case h.HLS_LIVE:return"hls";case h.HLS_ONDEMAND:return"ondemand_hls";case h.HLS_LIVE_CMAF:return"ondemand_hls_live";case h.WEB_RTC_LIVE:return"webrtc";default:return he(r)}},O=r=>{if(r!==void 0)switch(r){case x.NONE:case x.INLINE:return;case x.FULLSCREEN:return"fullscreen";case x.SECOND_SCREEN:return"chromecast";case x.PIP:return"pip";case x.INVISIBLE:return"invisible";default:return he(r)}},me=r=>{switch(r){case"slow-2g":return"poor";case"2g":return"poor";case"3g":return"good";case"4g":return"excellent"}};var N=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"),ve=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");import{PlaybackState as Ie}from"@vkontakte/videoplayer-core/evergreen";import{filter as ye,filterChanged as Be,fromEvent as Ue,isNullable as Se,map as He,merge as J,Observable as We,Subject as Z,Subscription as Ke,ValueSubject as qe}from"@vkontakte/videoplayer-shared/evergreen";var Pe=(r,e)=>new We(i=>{let t=new Ke,o=J(Ue(window,"beforeunload"),r.events.willDestruct$),n=new qe(void 0),a;t.add(r.info.isLive$.pipe(Be()).subscribe(I=>{a&&(a.unsubscribe(),n.next(void 0)),I?a=r.info.liveTime$.pipe(He(U=>U&&U/1e3)).subscribe(n):a=r.info.position$.subscribe(n),t.add(a)}));let{playing$:l,paused$:u}=r.events,c=r.events.willSeek$.pipe(ye(()=>r.info.playbackState$.getValue()===Ie.PLAYING)),p=r.events.seeked$.pipe(ye(()=>r.info.playbackState$.getValue()===Ie.PLAYING)),f=!1,s=new Z;t.add(c.subscribe(()=>{f||s.next(),f=!0})),t.add(p.subscribe(()=>f=!1));let d=new Z,g=new Z,b=J(l,p,d),y=J(u,s,o,r.events.looped$,g),S,B=()=>S=n.getValue(),C=()=>{let I=n.getValue();Se(S)||S===I||Se(I)||(i.next({from:S,to:I}),S=void 0)},k=()=>{g.next(),d.next()};if(t.add(b.subscribe(B)),t.add(y.subscribe(C)),e.forceInterval&&isFinite(e.forceInterval)){let I=0;t.add(b.subscribe(()=>I=window.setTimeout(k,e.forceInterval))),t.add(y.subscribe(()=>window.clearTimeout(I)))}return t});var Ce="_one-stat_",Te=`${Ce}uuid`,we=`${Ce}deviceId`,ee=()=>{let r=new te;return{subscription:r,subscribe:(e,i)=>{e&&r.add(e.subscribe(i))}}},ie=class{constructor(e,i){this.subscription=new te;this.debugLogger=new Xe;this.oneStatDebugLog=this.debugLogger.createComponentLog("onestat");this.loopCounter=0;this.disabled=!1;this.vsid$=new V(void 0);this.isid$=new V(void 0);this.zenUid$=new V(void 0);this.seekAction$=new V("unknown");this.statContext=e,this.config=ce(i.config??{}),_(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new N);let t=new Ye;this.experimental={error$:t},M.get(Te)&&M.remove(Te);let n=M.get(we);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:n?this.deviceId=n:(this.deviceId=Q(),M.set(we,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??ve()),this.zenUid$.next(i.zenUid);let a=new T({config:this.config,error$:t,timeSynchronisation:this.timeSynchronisation});this.api=new A({config:this.config,apiTransport:a,refreshAuthToken:i.refreshAuthToken,mobile:this.statContext.mobile??!1,deviceId:this.deviceId,error$:t,vktvVersion:i.vktvVersion}),this.logger=new D({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:l,topOrigin:u}=Je();this.isEmbed=l,this.embedParent=u?new URL(u).hostname:void 0,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new te,t=(s,d)=>i.add(s.subscribe(d));t(e.events.willStart$,()=>{let s=e.info.position$.getValue();this.logActionPlay({position:s}),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(Pe(e,{forceInterval:this.config.watchCoverageInterval}),s=>{let d=e.info.isLive$.getValue(),g=e.info.atLiveEdge$.getValue(),b={start:parseFloat(s.from.toFixed(3)),end:parseFloat(s.to.toFixed(3))};if(g){let y=e.info.liveLatency$.getValue()??0,S=e.info.currentBuffer$.getValue()?.end??0,B=e.info.liveBufferTime$.getValue()??0,C=Math.round((y-(S-B))*1e3),k=Math.round(y*1e3);C&&k&&(b.latency=C,b.bufferLatency=k)}d?this.logWatchCoverageLive(b):this.logWatchCoverageRecord(b)});let o;t(e.info.isStalled$,s=>{s?o=v():(_(o)&&this.logEmptyBuffer({duration:v()-o}),o=void 0)});let n=!1;i.add(e.events.fatalError$.pipe(Ge()).subscribe(()=>n=!0)),t(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){let d=_(o)?v()-o:void 0;this.logCloseAtEmptyBuffer({duration:d??0}),o=void 0}else n||this.logActionStop()}),t(e.events.managedError$,({id:s})=>{this.logError({fatal:!1,errorType:s})}),t(e.events.fatalError$,({id:s})=>{this.logError({fatal:!0,errorType:s})});let a,l,u=!1;t(e.events.firstBytes$,s=>{a=v(),this.logFirstBytes({time:s})}),t(e.events.willStart$,()=>l=v()),t(e.info.currentBuffer$,s=>{!u&&s&&s.end-s.start>0&&_(a)&&(this.logPlayerReady({duration:v()-a}),u=!0)}),t(e.events.firstFrame$,()=>{_(a)&&!u&&(this.logPlayerReady({duration:v()-a}),u=!0),_(l)&&this.logFirstFrame({time:v()-l})});let c;t(e.info.currentVideoStream$,s=>{s&&(c&&s.id!==c&&this.logTrackSwitch(s),c=s.id)});let p;t(e.info.currentAudioStream$,s=>{s&&(p&&s.id!==p&&this.logTrackSwitch(s),p=s.id)}),t(e.info.atLiveEdge$,s=>this.updateContext({liveEdge:s})),t(xe({muted:e.info.muted$,volume:e.info.volume$}),({muted:s,volume:d})=>this.updateContext({audible:!s&&d>0})),t(e.info.currentQuality$,s=>{let d=fe(s);this.updateContext({quality:d}),d&&this.logQuality(d)}),t(e.info.isAutoQualityEnabled$,s=>this.updateContext({autoQuality:s})),t(e.info.currentFormat$,s=>this.updateContext({contentType:ge(s)})),t(e.info.currentPlaybackRate$,s=>this.updateContext({rate:s})),t(e.info.is3DVideo$,s=>this.updateContext({is3d:s}));let f;return t(e.info.hostname$,s=>{let d=f!==void 0&&f!==s;this.updateContext({cdnHostname:s,failover:d}),d&&this.logFailover(s),f=s}),t(e.info.throughputEstimation$,s=>this.updateContext({downloadSpeed:s})),t(e.info.httpConnectionType$,s=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:X(s)}),this.updateContext({connectionType:X(s)})}),t(e.info.httpConnectionReused$,s=>{Ee(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:s}),this.updateContext({connectionReused:s})}),t(e.info.surface$,s=>this.updateContext({mode:O(s)})),t(xe({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:s,available:d})=>{let g=d.find(({id:y})=>y===s),b=g&&(g.isAuto?`${g.language}_auto`:g.language);this.updateContext({subtitles:b?.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}=ee();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":O(this.player?.info.surface$.getValue());this.updateContext({mode:n})}),t(e.inFullscreen$,o=>{let n=o?"fullscreen":O(this.player?.info.surface$.getValue());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}=ee();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}=ee();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(Qe(_e(e,"change"),je(["init"])).subscribe(()=>this.updateContext({network:me(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=_e(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()??v(),a=this.vsid$.getValue();ze(a);let l=this.isid$.getValue(),u=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,c=this.statContext.firstConnectionReused,p,f;if(this.isEmbed||this.statContext.place==="embed"){p=this.embedParent;let d=[...new URLSearchParams(location.search).entries()].filter(([g,b])=>this.config.embedUrlParams.includes(g));f=new URLSearchParams(d).toString()}else this.statContext.place==="direct"&&(this.statContext.refDomain?p=Ae(this.statContext.refDomain)?.hostname??this.statContext.refDomain:document.referrer&&(p=Ae(document.referrer)?.hostname??document.referrer),f=location.href.substring(0,1024));let s={vsid:a,isid:l,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:u,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:p,direct_url:f,rate:this.statContext.rate===1||Ee(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 d of this.config.disabledCustomFields)delete s[d];return{operation:e,type:1,time:t,network:this.statContext.network,timestamp:n,custom:s}}};var Ze={};import{PlaybackState as Le,Subscription as et}from"@vkontakte/videoplayer-core/evergreen";var F=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 ke=()=>window.Image?new Image:document.createElement("img");var oe=class{constructor(e){this.position=0;this.started=!1;this.heartbeatPixels=[];this.heartbeatLastTimeSent={};this.stopwatch=new F;this.subscription=new et;this.params=e}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.send("stop")}onPlaybackState(e){e===Le.PLAYING?this.started?this.play():this.start():e===Le.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;i!==void 0&&e&&(this.heartbeatFirstTimeoutId=window.setTimeout(()=>{this.sendHeartbeat(e)},i*1e3))}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){return e.replace("{@fts_fake_sec}",String(this.getFrameTimestamp())).replace("{@utc_sec}",String(this.getUTC())).split("&").filter(i=>!/={@[a-zA-Z_]+}/.test(i)).join("&")}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){requestIdleCallback(()=>ke().src=this.prepareUrl(e))}send(e){let i=this.preparePixels(e);for(let{url:t}of i)this.call(t)}sendHeartbeat(e){this.call(e)}};export{E as ApiEnv,K as ConnectionType,W as ContentType,se as InteractiveInterfaceClick,oe as MediascopePixel,Ze as MediascopePixelTypes,ie as OneStat,H as Quality,q as SeekAction,L as VERSION};
6
+ var Et=Object.defineProperty;var At=(s,e)=>{for(var i in e)Et(s,i,{get:e[i],enumerable:!0})};var R=(n=>(n.PROD="prod",n.VK_ALIAS="vk_alias",n.VIDEOTEST="videotest",n.TEST="test",n.OKCDN="okcdn",n.AUTO="auto",n))(R||{}),re=(u=>(u.Q144P="mobile",u.Q240P="lowest",u.Q360P="low",u.Q480P="medium",u.Q720P="high",u.Q1080P="fullhd",u.Q1440P="quadhd",u.Q2160P="ultrahd",u.UNKNOWN="unknown",u))(re||{}),se=(c=>(c.MP4="mp4",c.DASH="dash",c.DASH_SEP="dash_sep",c.ONDEMAND_DASH="ondemand_dash",c.HLS="hls",c.ONDEMAND_HLS="ondemand_hls",c.WEBM="webm",c.AV1="av1",c.ONDEMAND_DASH_LIVE="ondemand_dash_live",c.ONDEMAND_HLS_LIVE="ondemand_hls_live",c.WEBRTC="webrtc",c.UNKNOWN="unknown",c.RTMP="rtmp",c))(se||{});var ne=(t=>(t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3",t))(ne||{});var ae=(d=>(d.SLIDER="slider",d.DOUBLE_TAP="double_tap",d.TIME_CODE="time_code",d.EPISODE="episode",d.REWIND="rewind",d.LIVE="live",d.UNKNOWN="unknown",d))(ae||{}),Te=(r=>(r.GRAPH_SHOW="iGraphShow",r.GRAPH_HIDE="iGraphHide",r.NEXT_AREA="iNextChapterArea",r.NEXT_BUTTON="iNextChapterBtn",r.WATCH_AGAIN="iWatchAgainBtn",r))(Te||{}),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"},xe={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"},Le={unknown:"un",mobile:"m",lowest:"ls",low:"l",medium:"md",high:"h",fullhd:"f",quadhd:"q",ultrahd:"u"},Ce={pip:"pi",fullscreen:"fs",external:"ex",prefetch:"pr",airplay:"ap",chromecast:"cc",invisible:"iv"};import{fillWithDefault as wt}from"@vkontakte/videoplayer-shared/evergreen";var U="__VERSION__",$e="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 Tt={apiEnv:"vk_alias",apiKey:$e,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}},De=s=>wt(s,Tt);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 Ft,combine as ze,fromEvent as Qe,isNonNullable as D,isNullable as je,merge as Ut,now as T,observableFrom as Ht,once as Wt,safeStorage as Ge,Subject as Kt,Subscription as be,ValueSubject as Q,createURL as Ye}from"@vkontakte/videoplayer-shared/evergreen";import{Logger as qt,detectEmbed as zt}from"@vkontakte/videoplayer-shared/evergreen";var Ne=s=>{let{operation:e,custom:i}=s,t=Object.fromEntries(Object.entries(i).map(([o,r])=>{let n=xe[o]??o,d=r;return r&&(o==="mode"?d=Ce[r]??r:o==="quality"&&(d=Le[r]??r)),[n,d]}));return{...s,operation:ke[e]??e,custom:t}};import{ValueSubject as kt,getExponentialDelay as xt,ErrorCategory as C}from"@vkontakte/videoplayer-shared/evergreen";var Lt=/Mobile|mini|Fennec|Android|iP(ad|od|hone)|opera (mini|mobi)/i,V=class{constructor(e){this.consequentAuthErrors=0;this.authorized$=new kt(!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(n,d=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 u=l?.error_code;switch(u){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),d>0?r(n,d-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),d>0?r(n,d-1):void 0;default:{this.params.error$.next({id:`LogRequest#${u}`,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:${U}`;if(this.params.config.useVKComIsMobileLogic){let{appVersion:r}=window.navigator;t=Lt.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(Ne):e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();let e=xt(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:U.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 H,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:H.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(n){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:H.NETWORK,message:"Unhandled beacon error",thrown:n,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:H.NETWORK,message:"Request failed",thrown:n});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:H.NETWORK,message:"Unhandled request error",thrown:n,data:{method:e,params:i,sessionKey:t,time:ue()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),fetch(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:i,sessionKey:t})}).then(n=>{let d=Number(n.headers.get("content-length"))===0,l=new Date(n.headers.get("date")??"").getTime(),u=ue()-o;if(isFinite(l)&&this.timeSynchronisation?.addServerTime(l,u),!d)return n.json().then(h=>Object.prototype.hasOwnProperty.call(h,"error_msg")?Promise.reject(h):h,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 Ct,now as $t,safeStorage as B,debounceFn as Oe}from"@vkontakte/videoplayer-shared/evergreen";var W="onestat_events",le=s=>e=>e.timestamp+s>=$t(),K=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=Oe(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=B.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=Oe(()=>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:Ct.WTF,message:e?String(e):"Unknown logger error",thrown:e})}}readFromStorage(){let e=B.get(W);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));B.set(W,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],B.set(W,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`})}B.set(W,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 Re}from"@vkontakte/videoplayer-shared/evergreen";var Ve=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],Me=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 Re(s)}},q=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 Re(s)}},Be=s=>{switch(s){case"slow-2g":return"poor";case"2g":return"poor";case"3g":return"good";case"4g":return"excellent"}};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)}};var Fe=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(7,"0"),Ue=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");import{PlaybackState as He}from"@vkontakte/videoplayer-core/evergreen";import{filter as We,filterChanged as Nt,fromEvent as Ot,isNullable as Ke,map as Rt,merge as fe,Observable as Vt,Subject as ge,Subscription as Mt,ValueSubject as Bt}from"@vkontakte/videoplayer-shared/evergreen";var qe=(s,e)=>new Vt(i=>{let t=new Mt,o=fe(Ot(window,"beforeunload"),s.events.willDestruct$),r=new Bt(void 0),n;t.add(s.info.isLive$.pipe(Nt()).subscribe(g=>{n&&(n.unsubscribe(),r.next(void 0)),g?n=s.info.liveTime$.pipe(Rt(y=>y&&y/1e3)).subscribe(r):n=s.info.position$.subscribe(r),t.add(n)}));let{playing$:d,paused$:l}=s.events,u=s.events.willSeek$.pipe(We(()=>s.info.playbackState$.getValue()===He.PLAYING)),h=s.events.seeked$.pipe(We(()=>s.info.playbackState$.getValue()===He.PLAYING)),p=!1,a=new ge;t.add(u.subscribe(()=>{p||a.next(),p=!0})),t.add(h.subscribe(()=>p=!1));let c=new ge,m=new ge,f=fe(d,h,c),I=fe(l,a,o,s.events.looped$,m),S,E=()=>S=r.getValue(),A=()=>{let g=r.getValue();Ke(S)||S===g||Ke(g)||(i.next({from:S,to:g}),S=void 0)},w=()=>{m.next(),c.next()};if(t.add(f.subscribe(E)),t.add(I.subscribe(A)),e.forceInterval&&isFinite(e.forceInterval)){let g=0;t.add(f.subscribe(()=>g=window.setTimeout(w,e.forceInterval))),t.add(I.subscribe(()=>window.clearTimeout(g)))}return t});var Qt="_one-stat_",Xe=`${Qt}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 qt;this.oneStatDebugLog=this.debugLogger.createComponentLog("onestat");this.loopCounter=0;this.disabled=!1;this.vsid$=new Q(void 0);this.isid$=new Q(void 0);this.zenUid$=new Q(void 0);this.seekAction$=new Q("unknown");this.statContext=e,this.config=De(i.config??{}),D(i.apiEnv)&&(this.config.apiEnv=i.apiEnv),this.config.synchronizeTime&&(this.timeSynchronisation=new z);let t=new Kt;this.experimental={error$:t};let o=Ge.get(Xe);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=ce(),Ge.set(Xe,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??Ue()),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 K({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:n,topOrigin:d}=zt();this.isEmbed=n,this.embedParent=d?new URL(d).hostname:void 0,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){let i=new be,t=(a,c)=>i.add(a.subscribe(c));t(e.events.willStart$,()=>{let a=e.info.position$.getValue();this.logActionPlay({position:a}),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(qe(e,{forceInterval:this.config.watchCoverageInterval}),a=>{let c=e.info.isLive$.getValue(),m=e.info.atLiveEdge$.getValue(),f={start:parseFloat(a.from.toFixed(3)),end:parseFloat(a.to.toFixed(3))};if(m){let I=e.info.liveLatency$.getValue()??0,S=e.info.currentBuffer$.getValue()?.end??0,E=e.info.liveBufferTime$.getValue()??0,A=Math.round((I-(S-E))*1e3),w=Math.round(I*1e3);A&&w&&(f.latency=A,f.bufferLatency=w)}c?this.logWatchCoverageLive(f):this.logWatchCoverageRecord(f)});let o;t(e.info.isStalled$,a=>{a?o=T():(D(o)&&this.logEmptyBuffer({duration:T()-o}),o=void 0)});let r=!1;i.add(e.events.fatalError$.pipe(Wt()).subscribe(()=>r=!0)),t(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){let c=D(o)?T()-o:void 0;this.logCloseAtEmptyBuffer({duration:c??0}),o=void 0}else r||this.logActionStop()}),t(e.events.managedError$,({id:a})=>{this.logError({fatal:!1,errorType:a})}),t(e.events.fatalError$,({id:a})=>{this.logError({fatal:!0,errorType:a})});let n,d,l=!1;t(e.events.firstBytes$,a=>{n=T(),this.logFirstBytes({time:a})}),t(e.events.willStart$,()=>d=T()),t(e.info.currentBuffer$,a=>{!l&&a&&a.end-a.start>0&&D(n)&&(this.logPlayerReady({duration:T()-n}),l=!0)}),t(e.events.firstFrame$,()=>{D(n)&&!l&&(this.logPlayerReady({duration:T()-n}),l=!0),D(d)&&this.logFirstFrame({time:T()-d})});let u;t(e.info.currentVideoStream$,a=>{a&&(u&&a.id!==u&&this.logTrackSwitch(a),u=a.id)});let h;t(e.info.currentAudioStream$,a=>{a&&(h&&a.id!==h&&this.logTrackSwitch(a),h=a.id)}),t(e.info.atLiveEdge$,a=>this.updateContext({liveEdge:a})),t(ze({muted:e.info.muted$,volume:e.info.volume$}),({muted:a,volume:c})=>this.updateContext({audible:!a&&c>0})),t(e.info.currentQuality$,a=>{let c=Ve(a);this.updateContext({quality:c}),c&&this.logQuality(c)}),t(e.info.isAutoQualityEnabled$,a=>this.updateContext({autoQuality:a})),t(e.info.currentFormat$,a=>this.updateContext({contentType:Me(a)})),t(e.info.currentPlaybackRate$,a=>this.updateContext({rate:a})),t(e.info.is3DVideo$,a=>this.updateContext({is3d:a}));let p;return t(e.info.hostname$,a=>{let c=p!==void 0&&p!==a;this.updateContext({cdnHostname:a,failover:c}),c&&this.logFailover(a),p=a}),t(e.info.throughputEstimation$,a=>this.updateContext({downloadSpeed:a})),t(e.info.httpConnectionType$,a=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:pe(a)}),this.updateContext({connectionType:pe(a)})}),t(e.info.httpConnectionReused$,a=>{je(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:a}),this.updateContext({connectionReused:a})}),t(e.info.surface$,a=>this.updateContext({mode:q(a)})),t(ze({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:a,available:c})=>{let m=c.find(({id:I})=>I===a),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":q(this.player?.info.surface$.getValue());this.updateContext({mode:r})}),t(e.inFullscreen$,o=>{let r=o?"fullscreen":q(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(Fe())}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(Ut(Qe(e,"change"),Ht(["init"])).subscribe(()=>this.updateContext({network:Be(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=Qe(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()??T(),n=this.vsid$.getValue();Ft(n);let d=this.isid$.getValue(),l=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,u=this.statContext.firstConnectionReused,h,p;if(this.isEmbed||this.statContext.place==="embed"){h=this.embedParent;let c=[...new URLSearchParams(location.search).entries()].filter(([m,f])=>this.config.embedUrlParams.includes(m));p=new URLSearchParams(c).toString()}else this.statContext.place==="direct"&&(this.statContext.refDomain?h=Ye(this.statContext.refDomain)?.hostname??this.statContext.refDomain:document.referrer&&(h=Ye(document.referrer)?.hostname??document.referrer),p=location.href.substring(0,1024));let a={vsid:n,isid:d,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:u===!0?1:u===!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||je(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 c of this.config.disabledCustomFields)delete a[c];return{operation:e,type:1,time:t,network:this.statContext.network,timestamp:r,custom:a}}};var yt={};At(yt,{SeekType:()=>j,ThinOneStat:()=>ie,VERSION:()=>k});import{assertNonNullable as di,detectEmbed as ci,fromEvent as ui,Logger as li,merge as bt,safeStorage as vt,Subject as hi,Subscription as we,ValueSubject as te}from"@vkontakte/videoplayer-shared/evergreen";import{clientChecker as L,PlaybackState as It}from"@vkontakte/videoplayer-core/evergreen";import{fillWithDefault as jt}from"@vkontakte/videoplayer-shared/evergreen";var j=(d=>(d.SLIDER="slider",d.DOUBLE_TAP="double_tap",d.TIME_CODE="time_code",d.EPISODE="episode",d.REWIND="rewind",d.LIVE="live",d.UNKNOWN="unknown",d))(j||{});var k="__VERSION__",Ze="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 Gt={apiKey:Ze,apiEnv:"vk_alias",requestRetryCount:1,firstFlushTime:5e3,flushDebounceTime:1e4,flushMaxWait:6e4,storageExpiration:36*60*60*1e3,watchCoverageHeartbeatInterval:15,synchronizeTime:!0,useBeacon:!1,alwaysSendDesktop:!1},et=s=>jt(s,Gt);import{getExponentialDelay as Yt,ErrorCategory as N,ValueSubject as Xt}from"@vkontakte/videoplayer-shared/evergreen";var G=class{constructor(e){this.params=e,this.authorized$=new Xt(!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 n=async(d,l=this.params.config.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,t,r,o)}catch(u){if(!u||!("error_code"in u)){this.params.error$.next({id:"logRequestUnknown",category:N.NETWORK,message:`Unknown ${i} error`,thrown:u});return}let h=u?.error_code;switch(h){case 102:case 103:case 104:return this.authorized$.next(!1),this.sessionKey=await this.authorizeWithBackoff(),l>0?n(d,l-1):void 0;case 401:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this.authorizeWithBackoff(),l>0?n(d,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${h}`,category:N.EXTERNAL_API,message:`${i} error`,data:u});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){return{collector:"ok.mobile.apps.video",uv_stat_data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${k}`,platform:e[0].platform,product:e[0].product,events:e})}}authorizeWithBackoff(){if(!this.consequentAuthErrors)return this.doAuthorize();let e=Yt(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:k.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 Y}from"@vkontakte/videoplayer-shared/evergreen";var X=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(n){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:Y.NETWORK,message:"Unhandled beacon error",thrown:n,data:{method:e,params:i}})}return!1}async sendRequest(e,i,t,o){let r=Se(),n=d=>{if(d instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(d.message)){this.params.error$.next({id:"Network",category:Y.NETWORK,message:"Request failed",thrown:d});return}this.params.error$.next({id:"ThinOneStat:ApiTransport:sendRequest",category:Y.NETWORK,message:"Unhandled request error",thrown:d,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(d=>{let l=Number(d.headers.get("content-length"))===0,u=new Date(d.headers.get("date")??"").getTime(),h=Se()-r;if(isFinite(u)&&this.timeSynchronisation?.addServerTime(u,h),!l)return d.json().then(p=>Object.prototype.hasOwnProperty.call(p,"error_msg")?Promise.reject(p):p,n)},n)}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:Y.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 Jt,now as Zt,safeStorage as F,debounceFn as tt}from"@vkontakte/videoplayer-shared/evergreen";var J="thinonestat_events",ye=s=>e=>e.client_time+s>=Zt(),Z=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=tt(()=>this.safeFlush(),this.params.config.firstFlushTime,{maxWait:this.params.config.firstFlushTime});let i=F.isPersistent()?this.params.config.flushMaxWait:0;this.debouncedFlush=tt(()=>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:Jt.WTF,message:String(e)||"Unknown logger error",thrown:e})}}readFromStorage(){let e=F.get(J);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(J,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(J,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(J,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 _e(){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 ee=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 it}from"@vkontakte/videoplayer-core/evergreen";import{Observable as ei,Subscription as ti,ValueSubject as ii,Subject as Pe,fromEvent as oi,isNullable as ot,merge as Ee,filter as rt,filterChanged as st}from"@vkontakte/videoplayer-shared/evergreen";var nt=(s,e)=>new ei(i=>{let t=new ti,o=new ii(void 0),r;t.add(s.info.isLive$.pipe(st()).subscribe(y=>{r&&(r.unsubscribe(),o.next(void 0)),y?r=s.info.liveTime$.pipe(st()).subscribe(o):r=s.info.position$.subscribe(o),t.add(r)}));let{playing$:n,paused$:d,ended$:l,looped$:u}=s.events,h=s.events.willSeek$.pipe(rt(()=>s.info.playbackState$.getValue()===it.PLAYING)),p=s.events.seeked$.pipe(rt(()=>s.info.playbackState$.getValue()===it.PLAYING)),a=!1,c=new Pe;t.add(h.subscribe(()=>{a||c.next(),a=!0})).add(p.subscribe(()=>a=!1));let m=Ee(oi(window,"beforeunload"),s.events.willDestruct$),f,I=()=>f=o.getValue(),S=()=>{let y=o.getValue();ot(f)||ot(y)||f===y||(i.next({from:f,to:y}),f=void 0)},E=new Pe,A=new Pe,w=Ee(n,c,E),g=Ee(d,p,m,l,u,A);if(t.add(w.subscribe(I)).add(g.subscribe(S)),e.heartbeatInterval&&isFinite(e.heartbeatInterval)){let y=[],_t=e.heartbeatInterval*1e3,Pt=()=>{A.next(),E.next()};t.add(w.subscribe(()=>{let oe=window.setTimeout(Pt,_t);y.push(oe)})).add(g.subscribe(()=>{y.forEach(oe=>{window.clearTimeout(oe)}),y=[]}))}return t});import{Subscription as ri}from"@vkontakte/videoplayer-core/evergreen";import{Observable as si}from"@vkontakte/videoplayer-shared/evergreen";var at=(s,e)=>new si(i=>{let t=new ri,o=1e4,r=0;return t.add(s.info.position$.subscribe(()=>{let n=e.getTotalViewTime()*1e3;n>r&&n%o===0&&(r=n,i.next({target_duration:o,current_tvt:n}))})),t});import{Observable as ni,Subscription as ai,merge as dt}from"@vkontakte/videoplayer-shared/evergreen";var ct=s=>new ni(e=>{let i=new ai,t=0,o=1,r=0,n=!1,d=!1,l=()=>{if(!n)return;let g=Date.now();r+=(g-t)*o,t=g},u=()=>{(!n||d)&&(t=Date.now(),n=!0,d=!1)},h=()=>{n&&(l(),n=!1)},p=()=>{n&&(l(),n=!1,d=!0)},a=g=>{n&&l(),o=g,t=Date.now()},{started$:c,playing$:m,paused$:f,willSeek$:I,ended$:S,willDestruct$:E}=s.events,{currentPlaybackRate$:A}=s.info;i.add(I.subscribe(p)).add(dt(c,m).subscribe(u)).add(dt(f,S,E).subscribe(h)).add(A.subscribe(a));let w=()=>{let g=r;return n&&(g+=(Date.now()-t)*o),Math.floor(g/1e3)};return e.next(w),i});import{assertNever as ut}from"@vkontakte/videoplayer-shared/evergreen";import{Surface as O,VideoFormat as b,VideoQuality as P}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 ut(s)}},x=s=>{if(s!==void 0)switch(s){case P.Q_144P:return"144p";case P.Q_240P:return"240p";case P.Q_360P:return"360p";case P.Q_480P:return"480p";case P.Q_720P:return"720p";case P.Q_1080P:return"1080p";case P.Q_1440P:return"1440p";case P.Q_2160P:return"2160p";case P.INVARIANT:case P.Q_576P:case P.Q_4320P:return"UNKNOWN";default:return ut(s)}},lt=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}},ht=(s,e,i)=>{if(s&&e)switch(s){case b.MPEG:return i&&e[s]&&e[s][i];default:return e[s]?.url}},pt=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"}},ft=s=>{if(s!==void 0)return s===O.INVISIBLE?"background":"foreground"};var gt=()=>Math.floor(Math.random()*4294967296).toString(36).padStart(13,"0"),mt=()=>Math.floor(Math.random()*18446744073709552e3).toString(36).padStart(13,"0");var pi="_thin-one-stat_",St=`${pi}deviceId`,fi=()=>{let s=new we;return{subscription:s,subscribe:(e,i)=>{e&&s.add(e.subscribe(i))}}},ie=class{constructor(e,i){this.debugLogger=new li;this.thinOneStatDebugLog=this.debugLogger.createComponentLog("ThinOneStat");this.eventNumber=1;this.seekAction$=new te("unknown");this.playerSize$=new te({width:0,height:0});this.vsid$=new te(void 0);this.isid$=new te(void 0);this.statContext=e,this.config=et(i.config??{}),this.subscription=new we,this.config.synchronizeTime&&(this.timeSynchronisation=new ee);let t=new hi,o=vt.get(St);this.statContext.deviceId?this.deviceId=this.statContext.deviceId:o?this.deviceId=o:(this.deviceId=_e(),vt.set(St,this.deviceId)),this.resetViewSession(),i.useIsid&&this.isid$.next(i.isid??mt());let r=new X({error$:t,config:this.config,timeSynchronisation:this.timeSynchronisation});this.api=new G({config:this.config,apiTransport:r,error$:t,deviceId:this.deviceId,refreshAuthToken:i.refreshAuthToken}),this.logger=new Z({config:this.config,debugLogger:this.debugLogger,api:this.api,error$:t,userSalt:i.userSalt});let{isEmbed:n,topOrigin:d}=ci();this.isEmbed=n,this.embedHostname=d?new URL(d).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,n)=>i.add(r.subscribe(n));t(ct(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 n=Math.round(r.from*1e3),d=Math.round(r.to*1e3),l={watch_interval:`${n}-${d}`,in_history:!!this.statContext.inHistory,content_type:Ae(e.info.currentFormat$.getValue()),playback_quality:x(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(at(e,{getTotalViewTime:this.getTotalViewTime}),r=>{this.logWatchedN(r)}),t(bt(e.events.willStart$,e.events.looped$),r=>{r&&this.resetViewSession();let n={isid:this.isid$.getValue(),stream_profile:lt(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(n)}),t(e.events.willReady$,()=>{if(this.statContext.preload){let r=e.info.currentFormat$.getValue(),n=e.info.availableSources$.getValue(),d=e.info.currentBuffer$.getValue(),l=e.info.currentQuality$.getValue(),u={target_buffer_time:d?d.end-d.start:void 0,playback_url:ht(r,n,l),playback_quality:x(l)};this.logPreloadStarted(u)}}),t(e.events.ready$,()=>{if(this.statContext.preload){let r=e.info.currentBuffer$.getValue(),n={buffer_time:r?r.end-r.start:void 0};this.logPreloadEnded(n)}}),t(e.events.playing$,()=>{this.logPlay()}),t(e.info.playbackState$,r=>{if(r===It.PLAYING){let n=e.info.currentBuffer$.getValue(),d={buffer_time:n?n.end-n.start:void 0};if(this.logPlaying(d),this.isStarted)this.logResume();else{this.isStarted=!0;let l=e.info.currentQuality$.getValue(),u=e.info.isAutoQualityEnabled$.getValue(),h=e.info.muted$.getValue(),p=e.info.volume$.getValue(),a=e.info.surface$.getValue(),c=e.info.availableTextTracks$.getValue(),m=e.info.currentTextTrack$.getValue(),f=e.info.currentAudioStream$.getValue(),I=e.info.currentPlaybackRate$.getValue(),S={playback_quality:x(l),user_quality:u?"auto":x(l),player_width:this.playerSize$.getValue().width,player_height:this.playerSize$.getValue().height,muted:h,sound_volume:p,buffer_time:n?Math.round(n.end-n.start):void 0,mode:pt(a),visibility:ft(a),subtitles_enabled:!!m,auto_subtitles:!!c.find(({id:E})=>E===m)?.isAuto,audio_track_lang:f?.language,playback_rate:I,recom_info:this.statContext.recomInfo};this.logPlaybackStarted(S)}}else r===It.PAUSED&&this.logPause()}),t(e.events.willSeek$,({to:r})=>{let n={target_position:r,seek_type:this.seekAction$.getValue()};this.logSeeking(n)}),t(e.events.seeked$,()=>{let n={target_position:e.info.position$.getValue(),seek_type:this.seekAction$.getValue()};this.logSeeked(n),this.seekAction$.next("unknown")}),t(bt(e.info.isBuffering$,e.info.isStalled$),r=>{r&&this.logShowLoader()}),t(e.info.currentQuality$,r=>{if(r){let n=e.info.isAutoQualityEnabled$.getValue(),d=e.info.currentVideoStream$.getValue()?.codec,l=e.info.currentAudioStream$.getValue()?.codec,u={user_quality:n?"auto":x(r),playback_quality:x(r),download_quality:x(r),codec_info:d&&l?`${d},${l}`:void 0,manual_switch:!n};this.logQualityChanged(u)}}),this.resubscribeBeforeunload(),this.subscription.add(i),i}attachToUi(e){let{subscribe:i,subscription:t}=fi();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(gt()),this.eventNumber=0}destroy(){this.api.destroy()}createRequiredParams(e){let i=this.vsid$.getValue();di(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:${k}`,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:k,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=ui(window,"beforeunload").subscribe(()=>{}),this.subscription.add(this.beforeunloadSubscription)}};export{R as ApiEnv,ne as ConnectionType,se as ContentType,Te as InteractiveInterfaceClick,ve as OneStat,re as Quality,ae as SeekAction,yt as ThinOneStat,U as VERSION};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vkontakte/videoplayer-statistics",
3
- "version": "1.0.81-dev.5dab7ad1.0",
3
+ "version": "1.0.81-dev.6c99e2bc.0",
4
4
  "author": "vk.com",
5
5
  "description": "Statistics library for vk.com videoplayer",
6
6
  "homepage": "https://vk.com",
@@ -54,9 +54,7 @@
54
54
  "**/*.d.ts"
55
55
  ],
56
56
  "dependencies": {
57
- "@vkontakte/videoplayer-shared": "1.0.63-dev.11bd7182.0"
58
- },
59
- "peerDependencies": {
60
- "@vkontakte/videoplayer-core": "2.0.135-dev.43bd5e6d.0"
57
+ "@vkontakte/videoplayer-core": "2.0.135-dev.ee4a31cc.0",
58
+ "@vkontakte/videoplayer-shared": "1.0.63-dev.2dc353c3.0"
61
59
  }
62
60
  }
package/types/index.d.ts CHANGED
@@ -1,8 +1,2 @@
1
- import { IOneStat, OneStat, IStatContext, IConstructorParams } from './OneStat/OneStat';
2
- import { ApiEnv, ContentType, Quality, ConnectionType, SeekAction, InterfaceClick, InteractiveInterfaceClick } from './OneStat/values';
3
- import { IUIEvents, IAdsEvents, IInteractiveEvents } from './OneStat/uiEvents';
4
- export { OneStat, IOneStat, IStatContext, IConstructorParams, ApiEnv, ContentType, Quality, ConnectionType, SeekAction, IUIEvents, IAdsEvents, IInteractiveEvents, InterfaceClick, InteractiveInterfaceClick, };
5
- export { VERSION } from './OneStat/env';
6
- export { IOptionalConfig } from './OneStat/config';
7
- export * as MediascopePixelTypes from './MediascopePixel/types';
8
- export { MediascopePixel, IMediascopePixel } from './MediascopePixel/MediascopePixel';
1
+ export * from './oneStat';
2
+ export * as ThinOneStat from './thinOneStat';
@@ -0,0 +1,6 @@
1
+ import { IOneStat, OneStat, IStatContext, IConstructorParams } from './OneStat';
2
+ import { ApiEnv, ContentType, Quality, ConnectionType, SeekAction, InterfaceClick, InteractiveInterfaceClick } from './values';
3
+ import { IUIEvents, IAdsEvents, IInteractiveEvents } from './uiEvents';
4
+ export { OneStat, IOneStat, IStatContext, IConstructorParams, ApiEnv, ContentType, Quality, ConnectionType, SeekAction, IUIEvents, IAdsEvents, IInteractiveEvents, InterfaceClick, InteractiveInterfaceClick, };
5
+ export { VERSION } from './env';
6
+ export { IOptionalConfig } from './config';
@@ -0,0 +1,38 @@
1
+ import type { ISubject, IError, IValueObservable } from '@vkontakte/videoplayer-shared';
2
+ import { ValueSubject } from '@vkontakte/videoplayer-shared';
3
+ import type { IApiTransport } from './ApiTransport';
4
+ import type { ILogItem } from './types';
5
+ import type { IConfig } from './config';
6
+ export interface IApi {
7
+ authorized$: IValueObservable<boolean>;
8
+ authorize(authToken?: string): Promise<string | undefined>;
9
+ logBeacon(items: ILogItem[]): void;
10
+ logRequest(items: ILogItem[]): Promise<void>;
11
+ destroy(): void;
12
+ }
13
+ export interface IApiParams {
14
+ config: IConfig;
15
+ deviceId: string;
16
+ apiTransport: IApiTransport;
17
+ error$: ISubject<IError>;
18
+ refreshAuthToken?: () => Promise<string | undefined>;
19
+ }
20
+ export declare class Api implements IApi {
21
+ authorized$: ValueSubject<boolean>;
22
+ private params;
23
+ private authToken?;
24
+ private sessionKey?;
25
+ private authorizePromise?;
26
+ private refreshAuthTokenPromise?;
27
+ private consequentAuthErrors;
28
+ private backoffTimeoutId;
29
+ constructor(params: IApiParams);
30
+ authorize(authToken?: string): Promise<string | undefined>;
31
+ logBeacon(items: ILogItem[]): void;
32
+ logRequest(items: ILogItem[]): Promise<void>;
33
+ destroy(): void;
34
+ private refreshAuthToken;
35
+ private createLogParams;
36
+ private authorizeWithBackoff;
37
+ private doAuthorize;
38
+ }
@@ -0,0 +1,25 @@
1
+ import type { ISubject, IError } from '@vkontakte/videoplayer-shared';
2
+ import type { IConfig } from './config';
3
+ import type { TimeSynchronisation } from './utils/timeSynchronisation';
4
+ export interface IApiTransport {
5
+ sendBeacon(method: string, params: Record<string, unknown>, sessionKey?: string): boolean;
6
+ sendRequest<T = unknown>(method: string, params: Record<string, unknown>, sessionKey?: string, headers?: Record<string, unknown>): Promise<T>;
7
+ }
8
+ export interface IApiTransportParams {
9
+ config: IConfig;
10
+ timeSynchronisation?: TimeSynchronisation;
11
+ error$: ISubject<IError>;
12
+ }
13
+ export declare class ApiTransport implements IApiTransport {
14
+ private params;
15
+ private apiKey;
16
+ private apiBaseUrl;
17
+ private apiEnv;
18
+ private isApiBaseUrlFetched;
19
+ private timeSynchronisation?;
20
+ constructor(params: IApiTransportParams);
21
+ sendBeacon(method: string, params: Record<string, unknown>, sessionKey?: string): boolean;
22
+ sendRequest<T = unknown>(method: string, params: Record<string, unknown>, sessionKey?: string, headers?: Record<string, unknown>): Promise<T>;
23
+ private resolveApiBaseUrl;
24
+ private prepareQueryParams;
25
+ }
@@ -0,0 +1,42 @@
1
+ import { IConfig } from './config';
2
+ import { ILogger as IDebugLogger, IError, ISubject } from '@vkontakte/videoplayer-shared';
3
+ import { IApi } from './Api';
4
+ import { ILogItem } from './types';
5
+ export interface ILoggerParams {
6
+ config: IConfig;
7
+ api: IApi;
8
+ debugLogger: IDebugLogger;
9
+ error$: ISubject<IError>;
10
+ userSalt?: string;
11
+ }
12
+ type FlushParams = {
13
+ wantBeacon?: boolean;
14
+ clearStorage?: boolean;
15
+ };
16
+ export declare class Logger {
17
+ private params;
18
+ private api;
19
+ private error$;
20
+ private subscription;
21
+ private userSalt;
22
+ private unsaltedStorage;
23
+ private lastVsid;
24
+ private isPaused;
25
+ private firstFlush;
26
+ private debouncedFlush;
27
+ private loggerDebugLog;
28
+ constructor(params: ILoggerParams);
29
+ private isUrgent;
30
+ private safeFlush;
31
+ private readFromStorage;
32
+ private addToStorage;
33
+ private getFromStorage;
34
+ private markStorageSent;
35
+ private housekeepStorage;
36
+ log(item: ILogItem): void;
37
+ flush({ wantBeacon, clearStorage }?: FlushParams): void;
38
+ pause(): void;
39
+ resume(): void;
40
+ destroy(): void;
41
+ }
42
+ export {};
@@ -0,0 +1,172 @@
1
+ import type { ISubscription, IValueObservable, Milliseconds, Seconds } from '@vkontakte/videoplayer-shared';
2
+ import { ValueSubject } from '@vkontakte/videoplayer-shared';
3
+ import type { IPlayer } from '@vkontakte/videoplayer-core';
4
+ import type { IOptionalConfig } from './config';
5
+ import { Mode, Quality, SeekType, AutoQuality, Visibility } from './values';
6
+ import type { IUIEvents } from './uiEvents';
7
+ export interface IThinOneStat {
8
+ vsid$: IValueObservable<string | undefined>;
9
+ isid$: IValueObservable<string | undefined>;
10
+ /**
11
+ * Лучше авторизоваться сразу, чтобы избежать ситуации:
12
+ * 1. Накапливаем запросы в очереди через debounce send
13
+ * 2. Пользователь закрывает приложение
14
+ * 3. Запрос пытается уйти через sendBeacon и падает без авторизации
15
+ */
16
+ authorize(authToken?: string): Promise<unknown>;
17
+ /**
18
+ * Обновляет общие параметры событий
19
+ */
20
+ updateContext(context: Partial<IStatContext>): void;
21
+ /**
22
+ * Привязываемся к событиям и разным изменениям состояний плеера
23
+ */
24
+ attachTo(player: IPlayer): ISubscription;
25
+ attachToUi(uiEvents: IUIEvents): ISubscription;
26
+ /**
27
+ * Идентификатор текущего устройства
28
+ */
29
+ getDeviceId(): string;
30
+ /**
31
+ * Деструктор класса
32
+ */
33
+ destroy(): void;
34
+ }
35
+ export interface IStatContext {
36
+ movieId?: number;
37
+ deviceId?: string;
38
+ preload?: boolean;
39
+ inHistory?: boolean;
40
+ recomInfo?: Record<string, unknown>;
41
+ product?: string;
42
+ navigation?: Record<string, unknown>;
43
+ }
44
+ export interface IConstructorParams {
45
+ config: IOptionalConfig;
46
+ userSalt?: string;
47
+ refreshAuthToken?: () => Promise<string | undefined>;
48
+ isid?: string;
49
+ useIsid?: boolean;
50
+ }
51
+ export interface IWatchCoveragePayload {
52
+ watch_interval: string;
53
+ in_history: boolean;
54
+ content_type?: string;
55
+ playback_quality?: string;
56
+ recom_info?: Record<string, unknown>;
57
+ }
58
+ export interface IWatchCoverageLivePayload extends IWatchCoveragePayload {
59
+ live: boolean;
60
+ }
61
+ export interface IWatchedNPayload {
62
+ target_duration: Milliseconds;
63
+ current_tvt: Milliseconds;
64
+ }
65
+ export interface IStartSessionPayload {
66
+ isid?: string;
67
+ stream_profile?: 'live' | 'vod';
68
+ dpi: number;
69
+ web_layout: 'desktop' | 'mobile';
70
+ iframe_host?: string | 'unknown' | null;
71
+ from_downloads?: boolean;
72
+ preloaded?: boolean;
73
+ navigation?: Record<string, unknown>;
74
+ recom_info?: Record<string, unknown>;
75
+ }
76
+ export interface IPreloadStartedPayload {
77
+ target_buffer_time?: Milliseconds;
78
+ playback_url?: string;
79
+ playback_quality?: Quality;
80
+ }
81
+ export interface IPreloadEndedPayload {
82
+ buffer_time?: Milliseconds;
83
+ }
84
+ export interface IPlaybackStartedPayload {
85
+ playback_quality?: Quality;
86
+ user_quality?: Quality | AutoQuality;
87
+ player_width?: number;
88
+ player_height?: number;
89
+ muted?: boolean;
90
+ sound_volume?: number;
91
+ buffer_time?: Milliseconds;
92
+ mode?: Mode;
93
+ visibility?: Visibility;
94
+ subtitles_enabled?: boolean;
95
+ auto_subtitles?: boolean;
96
+ audio_track_lang?: string;
97
+ playback_rate?: number;
98
+ recom_info?: Record<string, unknown>;
99
+ }
100
+ export interface IPlayingPayload {
101
+ buffer_time?: Milliseconds;
102
+ }
103
+ export interface ISeekingPayload {
104
+ target_position?: number;
105
+ seek_type?: SeekType;
106
+ }
107
+ export interface ISeekedPayload {
108
+ target_position?: number;
109
+ seek_type?: SeekType;
110
+ }
111
+ export interface IQualityChangedPayload {
112
+ user_quality?: Quality | AutoQuality;
113
+ playback_quality?: Quality | AutoQuality;
114
+ download_quality?: Quality;
115
+ codec_info?: string;
116
+ manual_switch?: boolean;
117
+ }
118
+ export interface IFailoverPayload {
119
+ cdn_host?: string;
120
+ }
121
+ export declare class ThinOneStat implements IThinOneStat {
122
+ private api;
123
+ private logger;
124
+ private config;
125
+ private subscription;
126
+ private beforeunloadSubscription?;
127
+ private timeSynchronisation?;
128
+ private statContext;
129
+ private deviceId;
130
+ private debugLogger;
131
+ private thinOneStatDebugLog;
132
+ private eventNumber;
133
+ private isStarted?;
134
+ private isLive?;
135
+ private position;
136
+ private cdnHostname?;
137
+ private isEmbed;
138
+ private embedHostname?;
139
+ private seekAction$;
140
+ private playerSize$;
141
+ vsid$: ValueSubject<string | undefined>;
142
+ isid$: ValueSubject<string | undefined>;
143
+ getTotalViewTime: () => Seconds;
144
+ constructor(statContext: IStatContext, params: IConstructorParams);
145
+ authorize(authToken?: string): Promise<unknown>;
146
+ updateContext(newContext: Partial<IStatContext>): void;
147
+ attachTo(player: IPlayer): ISubscription;
148
+ attachToUi(events: IUIEvents): ISubscription;
149
+ getDeviceId(): string;
150
+ resetViewSession(): void;
151
+ destroy(): void;
152
+ private createRequiredParams;
153
+ private createRequiredFatParams;
154
+ private log;
155
+ private logWatchCoverage;
156
+ private logWatchCoverageLive;
157
+ private logWatchedN;
158
+ private logStartSession;
159
+ private logPreloadStarted;
160
+ private logPreloadEnded;
161
+ private logPlaybackStarted;
162
+ private logPlay;
163
+ private logPlaying;
164
+ private logPause;
165
+ private logResume;
166
+ private logSeeking;
167
+ private logSeeked;
168
+ private logShowLoader;
169
+ private logQualityChanged;
170
+ private logFailover;
171
+ private resubscribeBeforeunload;
172
+ }
@@ -0,0 +1,17 @@
1
+ import { Milliseconds, RecursivePartial, Seconds } from '@vkontakte/videoplayer-shared';
2
+ import { ApiEnv } from './values';
3
+ export interface IConfig {
4
+ apiKey: string;
5
+ apiEnv: ApiEnv;
6
+ requestRetryCount: number;
7
+ firstFlushTime: Milliseconds;
8
+ flushDebounceTime: Milliseconds;
9
+ flushMaxWait: Milliseconds;
10
+ storageExpiration: Milliseconds;
11
+ watchCoverageHeartbeatInterval: Seconds;
12
+ synchronizeTime: boolean;
13
+ useBeacon: boolean;
14
+ alwaysSendDesktop: boolean;
15
+ }
16
+ export type IOptionalConfig = RecursivePartial<IConfig>;
17
+ export declare const fillDefault: (partial: IOptionalConfig) => IConfig;
@@ -0,0 +1,7 @@
1
+ import { ApiEnv } from './values';
2
+ export declare const VERSION: string;
3
+ /**
4
+ * Application ID: 512000749287.
5
+ */
6
+ export declare const API_KEY: string;
7
+ export declare const API_BASE_URLS: Record<ApiEnv, string>;
@@ -0,0 +1,4 @@
1
+ export { IThinOneStat, ThinOneStat, IStatContext } from './ThinOneStat';
2
+ export { SeekType } from './values';
3
+ export { IUIEvents } from './uiEvents';
4
+ export { VERSION } from './env';
@@ -0,0 +1,28 @@
1
+ import { EventName } from './values';
2
+ export interface IRequiredParams {
3
+ vsid: string;
4
+ event_name: EventName;
5
+ client_time: number;
6
+ event_number: number;
7
+ current_tvt: number;
8
+ uv_movie_id?: number;
9
+ application?: string;
10
+ platform?: string;
11
+ product?: string;
12
+ playback_position?: number;
13
+ cdn_host?: string;
14
+ }
15
+ export interface IRequiredFatParams {
16
+ stats_version: string;
17
+ browser: string;
18
+ browser_version: string;
19
+ os: string;
20
+ os_version: string;
21
+ device_type: 'desktop' | 'mobile';
22
+ navigation?: Record<string, unknown>;
23
+ }
24
+ export type ILogItem = IRequiredParams & Partial<IRequiredFatParams>;
25
+ export type PlayerSize = {
26
+ width: number;
27
+ height: number;
28
+ };
@@ -0,0 +1,9 @@
1
+ import type { IObservable } from '@vkontakte/videoplayer-shared';
2
+ import { SeekType } from './values';
3
+ export interface IUIEvents {
4
+ actionSeek$?: IObservable<SeekType>;
5
+ playerSize$?: IObservable<{
6
+ width: number;
7
+ height: number;
8
+ }>;
9
+ }
@@ -0,0 +1,5 @@
1
+ import type { Seconds } from '@vkontakte/videoplayer-shared';
2
+ import type { IPlayer, IObservable } from '@vkontakte/videoplayer-core';
3
+ type GetTotalViewTime = () => Seconds;
4
+ export declare const calculateTotalViewTime: (player: IPlayer) => IObservable<GetTotalViewTime>;
5
+ export {};
@@ -0,0 +1,8 @@
1
+ import { ISources, Surface, VideoFormat, VideoQuality } from '@vkontakte/videoplayer-core';
2
+ import { ContentType, Mode, Quality, StreamingProfile, Visibility } from '../values';
3
+ export declare const contentType: (format?: VideoFormat) => ContentType | undefined;
4
+ export declare const quality: (coreQuality?: VideoQuality) => Quality | undefined;
5
+ export declare const streamingProfile: (contentType?: ContentType) => StreamingProfile | undefined;
6
+ 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 visibility: (surface?: Surface) => Visibility | undefined;
@@ -0,0 +1,10 @@
1
+ import { Milliseconds } from '@vkontakte/videoplayer-shared';
2
+ export declare class TimeSynchronisation {
3
+ private offset;
4
+ constructor(initialOffset?: Milliseconds);
5
+ getOffset(): Milliseconds;
6
+ setOffset(offset: Milliseconds): void;
7
+ now(): number;
8
+ date(date?: Date): Date;
9
+ addServerTime(serverTime: Milliseconds, rtt: Milliseconds): void;
10
+ }
@@ -0,0 +1 @@
1
+ export default function uuid(): string;