@vkontakte/videoplayer-statistics 1.0.35 → 1.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es2015.cjs.js +4 -4
- package/es2015.esm.js +4 -4
- package/es2018.cjs.js +4 -4
- package/es2018.esm.js +4 -4
- package/esnext.cjs.js +4 -4
- package/esnext.esm.js +4 -4
- package/evergreen.esm.js +4 -4
- package/index.d.ts +399 -396
- package/package.json +3 -3
package/es2018.cjs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vkontakte/videoplayer-statistics v1.0.
|
|
3
|
-
* Mon,
|
|
4
|
-
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-
|
|
2
|
+
* @vkontakte/videoplayer-statistics v1.0.37
|
|
3
|
+
* Mon, 10 Jul 2023 15:30:39 GMT
|
|
4
|
+
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-37/doc/
|
|
5
5
|
*/
|
|
6
|
-
"use strict";var r=require("@vkontakte/videoplayer-shared/es2018.cjs.js"),C=require("lodash/debounce.js"),c=require("@vkontakte/videoplayer-core/es2018.cjs.js");function V(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,t[o]=e[o===19?i&3|8:i]);return t.join("")}exports.ApiEnv=void 0;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(exports.ApiEnv||(exports.ApiEnv={}));exports.Quality=void 0;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(exports.Quality||(exports.Quality={}));exports.ContentType=void 0;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(exports.ContentType||(exports.ContentType={}));var A;(function(e){e.AUTO="auto",e.MANUAL=""})(A||(A={}));exports.ConnectionType=void 0;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})(exports.ConnectionType||(exports.ConnectionType={}));var m;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(m||(m={}));var E;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(E||(E={}));var S;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(S||(S={}));exports.SeekAction=void 0;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(exports.SeekAction||(exports.SeekAction={}));const T="1.0.35",U="CIOPGQJGDIHBABABA",x={[exports.ApiEnv.PROD]:"https://api.ok.ru",[exports.ApiEnv.VK_ALIAS]:"https://api.mycdn.me",[exports.ApiEnv.VIDEOTEST]:"https://videotestapi.ok.ru/api",[exports.ApiEnv.TEST]:"https://apitest.ok.ru",[exports.ApiEnv.AUTO]:""},B="_one-stat_",N=`${B}uuid`,q={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var b;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(b||(b={}));class H{constructor(t){this.consequentAuthErrors=0,this.authorized$=new r.ValueSubject(!1),this.params=t;const s=r.safeStorage.get(N);s?this.uuid=String(s):(this.uuid=V(),r.safeStorage.set(N,this.uuid))}async authorize(t){return this.authToken=t!=null?t:await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(t)}async logRequest(t){var s;const i="log.externalLog",o=this.createLogParams(t),a=(s=this.sessionKey)!==null&&s!==void 0?s:await this._authorizeWithBackoff();if(!a)return;const u=async(f,h=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,o,a)}catch(d){if(!d||!("error_code"in d)){this.params.error$.next({id:"logRequestUnknown",category:r.ErrorCategory.NETWORK,message:`Unknown ${i} error`,thrown:d});return}const n=d==null?void 0:d.error_code;switch(n){case b.PARAM_SESSION_EXPIRED:case b.PARAM_SESSION_KEY:case b.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),h>0?u(f,h-1):void 0;case b.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),h>0?u(f,h-1):void 0;default:{this.params.error$.next({id:`LogRequest#${n}`,category:r.ErrorCategory.EXTERNAL_API,message:`${i} error`,data:d});return}}}};return u(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${T}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=r.getExponentialDelay(this.consequentAuthErrors,q);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:r.ErrorCategory.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:T.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(t,s).then(i=>{var o;return(!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:r.ErrorCategory.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=(o=i==null?void 0:i.session_key)!==null&&o!==void 0?o:void 0,this.sessionKey}).catch(async i=>{this.sessionKey=void 0;const o=i==null?void 0:i.error_code;switch(o){case b.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:r.ErrorCategory.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:r.ErrorCategory.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class O{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,s,i){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:s,options:i})}removeEventListener(t,s){if(!(t in this.listeners))return;const i=this.listeners[t];for(let o=0,a=i.length;o<a;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const i=this.listeners[t.type].slice();for(let o=0,a=i.length;o<a;o++){const u=i[o];try{u.callback.call(this,t)}catch(f){Promise.resolve().then(()=>{throw f})}u.options&&u.options.once&&this.removeEventListener(t.type,u.callback)}return!t.defaultPrevented}}class I extends O{constructor(){super(),this.listeners||O.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class M{constructor(){Object.defineProperty(this,"signal",{value:new I,writable:!0,configurable:!0})}abort(t){let s;try{s=new Event("abort")}catch(o){typeof document!="undefined"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=t;if(i===void 0)if(typeof document=="undefined")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch(o){i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol!="undefined"&&Symbol.toStringTag&&(M.prototype[Symbol.toStringTag]="AbortController",I.prototype[Symbol.toStringTag]="AbortSignal");function F(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function Q(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:s=t.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!F({fetch:t,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:a};let a=s;(a&&!a.prototype.hasOwnProperty("signal")||o)&&(a=function(d,n){let l;n&&n.signal&&(l=n.signal,delete n.signal);const p=new s(d,n);return l&&Object.defineProperty(p,"signal",{writable:!1,enumerable:!1,configurable:!0,value:l}),p},a.prototype=s.prototype);const u=t;return{fetch:(h,d)=>{const n=a&&a.prototype.isPrototypeOf(h)?h.signal:d?d.signal:void 0;if(n){let l;try{l=new DOMException("Aborted","AbortError")}catch(g){l=new Error("Aborted"),l.name="AbortError"}if(n.aborted)return Promise.reject(l);const p=new Promise((g,y)=>{n.addEventListener("abort",()=>y(l),{once:!0})});return d&&d.signal&&delete d.signal,Promise.race([p,u(h,d)])}return u(h,d)},Request:a}}const P=F({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),D=P?Q({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,R=P?D.fetch:window.fetch;P?D.Request:window.Request;class W{constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.apiEnv,this.apiBaseUrl=t.apiBaseUrl,this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){var t;if(this.apiEnv!==exports.ApiEnv.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const s=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=await(await R(s,{method:"GET",mode:"cors",cache:"no-cache"})).json(),a=(t=o==null?void 0:o.Answer[0])===null||t===void 0?void 0:t.data;if(!a)throw new Error("Wrong DNS response");return a}catch(s){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:r.ErrorCategory.NETWORK,message:"Unhandled resolve api base url error",thrown:s}),x[exports.ApiEnv.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:s,sessionKey:i}),a=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,a)}catch(u){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:r.ErrorCategory.NETWORK,message:"Unhandled beacon error",thrown:u,data:{method:t,params:s}})}return!1}async sendRequest(t,s,i){const o=r.now(),a=u=>{if(u instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(u.message)){this.params.error$.next({id:"Network",category:r.ErrorCategory.NETWORK,message:"Request failed",thrown:u});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:r.ErrorCategory.NETWORK,message:"Unhandled request error",thrown:u,data:{method:t,params:s,sessionKey:i,time:r.now()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),R(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:s,sessionKey:i})}).then(u=>{var f;const h=Number(u.headers.get("content-length"))===0,d=new Date((f=u.headers.get("date"))!==null&&f!==void 0?f:"").getTime(),n=r.now()-o;if(isFinite(d)&&this.timeSynchronisation.addServerTime(d,n),!h)return u.json().then(l=>Object.prototype.hasOwnProperty.call(l,"error_msg")?Promise.reject(l):l,a)},a)}_prepareQueryParams(t){const s=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&s.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const $=5e3,K=1e4,z=6e4,_="onestat_events",j=36*60*60*1e3,v=e=>e.timestamp+j>=r.now();class G{constructor(t){this.unsaltedStorage=[],this.isPaused=!1,this.isUrgent=s=>{const{operation:i,custom:{param:o}}=s;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&o==="0-0"},this.firstFlush=C(()=>this.safeFlush(),$,{maxWait:$}),this.debouncedFlush=C(()=>this.safeFlush(),K,{maxWait:z}),this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){var t;try{this.flush()}catch(s){this.error$.next({id:"LoggerError",category:r.ErrorCategory.WTF,message:(t=String(s))!==null&&t!==void 0?t:"Unknown logger error",thrown:s})}}readFromStorage(){const t=r.safeStorage.get(_);try{return t?JSON.parse(t):{}}catch(s){}return{}}addToStorage(t){var s;if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),a=((s=i[this.userSalt])!==null&&s!==void 0?s:[]).filter(v);r.safeStorage.set(_,JSON.stringify({...i,[this.userSalt]:[...a,t]}))}getFromStorage(){var t;return this.userSalt?((t=this.readFromStorage()[this.userSalt])!==null&&t!==void 0?t:[]).filter(v):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],r.safeStorage.set(_,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[s,i]of Object.entries(t)){const o=i.filter(v);o.length?t[s]=o:delete t[s]}r.safeStorage.set(_,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(t?this.api.logBeacon(s):this.api.logRequest(s),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()}}const Y=()=>{let e,t;try{e=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?e=!0:(e=!1,console.error(i))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!t&&document.referrer&&(t=document.referrer)}catch(i){console.error(i)}const s=t?new URL(t).hostname:void 0;return{isEmbed:e,host:s}},X=e=>e&&{[c.VideoQuality.INVARIANT]:exports.Quality.UNKNOWN,[c.VideoQuality.Q_144P]:exports.Quality.Q144P,[c.VideoQuality.Q_240P]:exports.Quality.Q240P,[c.VideoQuality.Q_360P]:exports.Quality.Q360P,[c.VideoQuality.Q_480P]:exports.Quality.Q480P,[c.VideoQuality.Q_720P]:exports.Quality.Q720P,[c.VideoQuality.Q_1080P]:exports.Quality.Q1080P,[c.VideoQuality.Q_1440P]:exports.Quality.Q1440P,[c.VideoQuality.Q_2160P]:exports.Quality.Q2160P,[c.VideoQuality.Q_4320P]:exports.Quality.UNKNOWN}[e],L=e=>e&&{[c.HttpConnectionType.HTTP1]:exports.ConnectionType.HTTP1,[c.HttpConnectionType.HTTP2]:exports.ConnectionType.HTTP2,[c.HttpConnectionType.QUIC]:exports.ConnectionType.HTTP3}[e],J=e=>{if(e!==void 0)switch(e){case c.VideoFormat.MPEG:return exports.ContentType.MP4;case c.VideoFormat.DASH:case c.VideoFormat.DASH_LIVE:return exports.ContentType.DASH;case c.VideoFormat.DASH_SEP:return exports.ContentType.DASH_SEP;case c.VideoFormat.DASH_ONDEMAND:return exports.ContentType.ONDEMAND_DASH;case c.VideoFormat.DASH_WEBM:case c.VideoFormat.DASH_WEBM_AV1:case c.VideoFormat.DASH_LIVE_WEBM:return exports.ContentType.WEBM;case c.VideoFormat.DASH_LIVE_CMAF:return exports.ContentType.ONDEMAND_DASH_LIVE;case c.VideoFormat.HLS:case c.VideoFormat.HLS_LIVE:return exports.ContentType.HLS;case c.VideoFormat.HLS_ONDEMAND:return exports.ContentType.ONDEMAND_HLS;case c.VideoFormat.HLS_LIVE_CMAF:return exports.ContentType.ONDEMAND_HLS_LIVE;case c.VideoFormat.WEB_RTC_LIVE:return exports.ContentType.WEBRTC;default:return r.assertNever(e)}},w=e=>{if(e!==void 0)switch(e){case c.Surface.NONE:case c.Surface.INLINE:return;case c.Surface.FULLSCREEN:return S.FULLSCREEN;case c.Surface.SECOND_SCREEN:return S.EXTERNAL;case c.Surface.PIP:return S.PIP;default:return r.assertNever(e)}},Z=e=>{switch(e){case"slow-2g":return E.POOR;case"2g":return E.POOR;case"3g":return E.GOOD;case"4g":return E.EXCELLENT}};class tt{constructor(t){this.offset=void 0,this.offset=t}getOffset(){var t;return(t=this.offset)!==null&&t!==void 0?t:0}setOffset(t){this.offset=t}now(){var t;return Date.now()+((t=this.offset)!==null&&t!==void 0?t:0)}date(t=new Date){var s;return t.setTime(t.getTime()+((s=this.offset)!==null&&s!==void 0?s:0)),t}addServerTime(t,s){const i=Date.now(),o=t-i-s/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)}}const k=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),et=e=>new r.Observable(t=>{const s=new r.Subscription,i=r.merge(r.fromEvent(window,"beforeunload"),e.events.willDestruct$),o=new r.ValueSubject(void 0);let a;e.info.isLive$.pipe(r.filterChanged()).subscribe(g=>{a&&(a.unsubscribe(),o.next(void 0)),g?a=e.info.liveTime$.pipe(r.map(y=>y&&y/1e3)).subscribe(o):a=e.info.position$.subscribe(o),s.add(a)});const{playing$:u,paused$:f}=e.events,h=e.events.willSeek$.pipe(r.filter(()=>e.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),d=e.events.seeked$.pipe(r.filter(()=>e.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),n=r.merge(u,d),l=r.merge(f,h,i,e.events.looped$);let p;return s.add(n.subscribe(()=>p=o.getValue())),s.add(l.subscribe(()=>{const g=o.getValue();r.isNullable(p)||p===g||r.isNullable(g)||(t.next({from:p,to:g}),p=void 0)})),s});class st{constructor(t,s){var i,o;this.subscription=new r.Subscription,this.timeSynchronisation=new tt,this.vsid=k(),this.seekAction$=new r.ValueSubject(exports.SeekAction.UNKNOWN),this.statContext=t,this.config={...(i=s.config)!==null&&i!==void 0?i:{},requestRetryCount:1};const a=new r.Subject;this.experimental={error$:a};const u=new W({apiKey:U,apiBaseUrl:x[s.apiEnv],apiEnv:s.apiEnv,error$:a,timeSynchronisation:this.timeSynchronisation});this.api=new H({apiTransport:u,refreshAuthToken:s.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:(o=this.statContext.mobile)!==null&&o!==void 0?o:!1,error$:a}),this.logger=new G({api:this.api,error$:a,userSalt:s.userSalt});const{isEmbed:f,host:h}=Y();this.isEmbed=f,this.embedParent=h,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const s=new r.Subscription,i=(n,l)=>s.add(n.subscribe(l));i(t.events.willStart$,()=>{this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(exports.SeekAction.UNKNOWN)}),i(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),i(t.events.willResume$,()=>{this.logPlay()}),i(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(et(t),n=>{const l=t.info.isLive$.getValue(),p={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};l?this.logWatchCoverageLive(p):this.logWatchCoverageRecord(p)});let o;i(t.info.isStalled$,n=>{n?o=r.now():(r.isNonNullable(o)&&this.logEmptyBuffer({duration:r.now()-o}),o=void 0)});let a=!1;s.add(t.events.fatalError$.pipe(r.once()).subscribe(()=>a=!0)),i(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const l=r.isNonNullable(o)?r.now()-o:void 0;this.logCloseAtEmptyBuffer({duration:l!=null?l:0}),o=void 0}else a||this.logActionStop()}),i(t.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),i(t.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let u,f,h=!1;i(t.events.firstBytes$,n=>{u=r.now(),this.logFirstBytes({time:n})}),i(t.events.willStart$,()=>f=r.now()),i(t.info.currentBuffer$,n=>{!h&&n&&n.end-n.start>0&&r.isNonNullable(u)&&(this.logPlayerReady({duration:r.now()-u}),h=!0)}),i(t.events.firstFrame$,()=>{r.isNonNullable(u)&&!h&&(this.logPlayerReady({duration:r.now()-u}),h=!0),r.isNonNullable(f)&&this.logFirstFrame({time:r.now()-f})}),i(t.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),i(r.combine({muted:t.info.muted$,volume:t.info.volume$}),({muted:n,volume:l})=>this.updateContext({audible:!n&&l>0})),i(t.info.currentQuality$,n=>this.updateContext({quality:X(n)})),i(t.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),i(t.info.currentFormat$,n=>this.updateContext({contentType:J(n)}));let d;return i(t.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),i(t.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),i(t.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:L(n)}),this.updateContext({connectionType:L(n)})}),i(t.info.httpConnectionReused$,n=>{r.isNullable(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),i(t.info.surface$,n=>this.updateContext({mode:w(n)})),i(r.combine({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:n,available:l})=>{const p=l.find(({id:g})=>g===n);this.updateContext({subtitles:p==null?void 0:p.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.subscription.add(s),s}attachToUi(t){this.uiEvents=t;const s=new r.Subscription;return this.player&&(s.add(t.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),s.add(t.actionSeek$.subscribe(this.seekAction$)),s.add(t.inPiP$.subscribe(i=>{var o;const a=i?S.PIP:w((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:a})})),s.add(t.inFullscreen$.subscribe(i=>{var o;const a=i?S.FULLSCREEN:w((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:a})})),s.add(t.actionSetSubtitle$.subscribe(i=>{this.updateContext({subtitles:i})})),this.subscription.add(s)),s}attachToAds(t){const s=new r.Subscription;return s.add(t.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(t.started$.subscribe(i=>this.logAdStarted(i))).add(t.paused$.subscribe(()=>this.logAdPaused())).add(t.resumed$.subscribe(()=>this.logAdResumed())).add(t.ended$.subscribe(()=>this.logAdEnded())).add(t.skipped$.subscribe(()=>this.logAdSkipped())).add(t.clicked$.subscribe(()=>this.logAdClicked())),this.subscription.add(s),s}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=k()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const s=t.start+this.timeSynchronisation.getOffset(),i=t.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${s}-${i}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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"})}subscribe(){this.subscription.add(r.fromEvent(window,"beforeunload").subscribe(()=>this.logger.flush(!0)));const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(r.merge(r.fromEvent(t,"change"),r.observableFrom(["init"])).subscribe(()=>this.updateContext({network:Z(t.effectiveType)})))}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){const s=this.createLogItem(t);this.logger.log(s)}createLogItem({operation:t,param:s,time:i}){const o=this.timeSynchronisation.now(),a=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,u=this.statContext.firstConnectionReused,f={vsid:this.vsid,vid:this.statContext.movieId,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?A.AUTO:this.statContext.autoplay===!1?A.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:a,connection_reused:u===!0?m.YES:u===!1?m.NO:void 0,cached_data:this.statContext.cached===!0?m.YES:this.statContext.cached===!1?m.NO:void 0,live:this.statContext.liveEdge?m.YES:void 0,muted:this.statContext.audible===!1?m.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:m.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:t,type:1,time:i,network:this.statContext.network,timestamp:o,custom:f}}}exports.OneStat=st;exports.VERSION=T;
|
|
6
|
+
"use strict";var r=require("@vkontakte/videoplayer-shared/es2018.cjs.js"),C=require("lodash/debounce.js"),c=require("@vkontakte/videoplayer-core/es2018.cjs.js");function V(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,t[o]=e[o===19?i&3|8:i]);return t.join("")}exports.ApiEnv=void 0;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(exports.ApiEnv||(exports.ApiEnv={}));exports.Quality=void 0;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(exports.Quality||(exports.Quality={}));exports.ContentType=void 0;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(exports.ContentType||(exports.ContentType={}));var A;(function(e){e.AUTO="auto",e.MANUAL=""})(A||(A={}));exports.ConnectionType=void 0;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})(exports.ConnectionType||(exports.ConnectionType={}));var b;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(b||(b={}));var E;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(E||(E={}));var S;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(S||(S={}));exports.SeekAction=void 0;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(exports.SeekAction||(exports.SeekAction={}));const T="1.0.37",B="CIOPGQJGDIHBABABA",x={[exports.ApiEnv.PROD]:"https://api.ok.ru",[exports.ApiEnv.VK_ALIAS]:"https://api.mycdn.me",[exports.ApiEnv.VIDEOTEST]:"https://videotestapi.ok.ru/api",[exports.ApiEnv.TEST]:"https://apitest.ok.ru",[exports.ApiEnv.AUTO]:""},U="_one-stat_",N=`${U}uuid`,q={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var m;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(m||(m={}));class H{constructor(t){this.consequentAuthErrors=0,this.authorized$=new r.ValueSubject(!1),this.params=t;const s=r.safeStorage.get(N);s?this.uuid=String(s):(this.uuid=V(),r.safeStorage.set(N,this.uuid))}async authorize(t){return this.authToken=t!=null?t:await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(t)}async logRequest(t){var s;const i="log.externalLog",o=this.createLogParams(t),a=(s=this.sessionKey)!==null&&s!==void 0?s:await this._authorizeWithBackoff();if(!a)return;const u=async(f,h=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,o,a)}catch(d){if(!d||!("error_code"in d)){this.params.error$.next({id:"logRequestUnknown",category:r.ErrorCategory.NETWORK,message:`Unknown ${i} error`,thrown:d});return}const n=d==null?void 0:d.error_code;switch(n){case m.PARAM_SESSION_EXPIRED:case m.PARAM_SESSION_KEY:case m.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),h>0?u(f,h-1):void 0;case m.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),h>0?u(f,h-1):void 0;default:{this.params.error$.next({id:`LogRequest#${n}`,category:r.ErrorCategory.EXTERNAL_API,message:`${i} error`,data:d});return}}}};return u(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${T}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=r.getExponentialDelay(this.consequentAuthErrors,q);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:r.ErrorCategory.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:T.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(t,s).then(i=>{var o;return(!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:r.ErrorCategory.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=(o=i==null?void 0:i.session_key)!==null&&o!==void 0?o:void 0,this.sessionKey}).catch(async i=>{this.sessionKey=void 0;const o=i==null?void 0:i.error_code;switch(o){case m.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:r.ErrorCategory.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:r.ErrorCategory.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class O{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,s,i){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:s,options:i})}removeEventListener(t,s){if(!(t in this.listeners))return;const i=this.listeners[t];for(let o=0,a=i.length;o<a;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const i=this.listeners[t.type].slice();for(let o=0,a=i.length;o<a;o++){const u=i[o];try{u.callback.call(this,t)}catch(f){Promise.resolve().then(()=>{throw f})}u.options&&u.options.once&&this.removeEventListener(t.type,u.callback)}return!t.defaultPrevented}}class I extends O{constructor(){super(),this.listeners||O.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class M{constructor(){Object.defineProperty(this,"signal",{value:new I,writable:!0,configurable:!0})}abort(t){let s;try{s=new Event("abort")}catch(o){typeof document!="undefined"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=t;if(i===void 0)if(typeof document=="undefined")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch(o){i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol!="undefined"&&Symbol.toStringTag&&(M.prototype[Symbol.toStringTag]="AbortController",I.prototype[Symbol.toStringTag]="AbortSignal");function F(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function Q(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:s=t.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!F({fetch:t,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:a};let a=s;(a&&!a.prototype.hasOwnProperty("signal")||o)&&(a=function(d,n){let l;n&&n.signal&&(l=n.signal,delete n.signal);const p=new s(d,n);return l&&Object.defineProperty(p,"signal",{writable:!1,enumerable:!1,configurable:!0,value:l}),p},a.prototype=s.prototype);const u=t;return{fetch:(h,d)=>{const n=a&&a.prototype.isPrototypeOf(h)?h.signal:d?d.signal:void 0;if(n){let l;try{l=new DOMException("Aborted","AbortError")}catch(g){l=new Error("Aborted"),l.name="AbortError"}if(n.aborted)return Promise.reject(l);const p=new Promise((g,y)=>{n.addEventListener("abort",()=>y(l),{once:!0})});return d&&d.signal&&delete d.signal,Promise.race([p,u(h,d)])}return u(h,d)},Request:a}}const P=F({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),D=P?Q({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,R=P?D.fetch:window.fetch;P?D.Request:window.Request;class W{constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.apiEnv,this.apiBaseUrl=t.apiBaseUrl,this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){var t;if(this.apiEnv!==exports.ApiEnv.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const s=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=await(await R(s,{method:"GET",mode:"cors",cache:"no-cache"})).json(),a=(t=o==null?void 0:o.Answer[0])===null||t===void 0?void 0:t.data;if(!a)throw new Error("Wrong DNS response");return a}catch(s){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:r.ErrorCategory.NETWORK,message:"Unhandled resolve api base url error",thrown:s}),x[exports.ApiEnv.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:s,sessionKey:i}),a=new window.Blob([o.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,a)}catch(u){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:r.ErrorCategory.NETWORK,message:"Unhandled beacon error",thrown:u,data:{method:t,params:s}})}return!1}async sendRequest(t,s,i){const o=r.now(),a=u=>{if(u instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(u.message)){this.params.error$.next({id:"Network",category:r.ErrorCategory.NETWORK,message:"Request failed",thrown:u});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:r.ErrorCategory.NETWORK,message:"Unhandled request error",thrown:u,data:{method:t,params:s,sessionKey:i,time:r.now()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),R(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:s,sessionKey:i})}).then(u=>{var f;const h=Number(u.headers.get("content-length"))===0,d=new Date((f=u.headers.get("date"))!==null&&f!==void 0?f:"").getTime(),n=r.now()-o;if(isFinite(d)&&this.timeSynchronisation.addServerTime(d,n),!h)return u.json().then(l=>Object.prototype.hasOwnProperty.call(l,"error_msg")?Promise.reject(l):l,a)},a)}_prepareQueryParams(t){const s=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&s.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const $=5e3,K=1e4,z=6e4,_="onestat_events",j=36*60*60*1e3,v=e=>e.timestamp+j>=r.now();class G{constructor(t){this.unsaltedStorage=[],this.isPaused=!1,this.flushMaxWait=r.safeStorage.isPersistent()?z:0,this.isUrgent=s=>{const{operation:i,custom:{param:o}}=s;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&o==="0-0"},this.firstFlush=C(()=>this.safeFlush(),$,{maxWait:$}),this.debouncedFlush=C(()=>this.safeFlush(),K,{maxWait:this.flushMaxWait}),this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){var t;try{this.flush()}catch(s){this.error$.next({id:"LoggerError",category:r.ErrorCategory.WTF,message:(t=String(s))!==null&&t!==void 0?t:"Unknown logger error",thrown:s})}}readFromStorage(){const t=r.safeStorage.get(_);try{return t?JSON.parse(t):{}}catch(s){}return{}}addToStorage(t){var s;if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),a=((s=i[this.userSalt])!==null&&s!==void 0?s:[]).filter(v);r.safeStorage.set(_,JSON.stringify({...i,[this.userSalt]:[...a,t]}))}getFromStorage(){var t;return this.userSalt?((t=this.readFromStorage()[this.userSalt])!==null&&t!==void 0?t:[]).filter(v):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],r.safeStorage.set(_,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[s,i]of Object.entries(t)){const o=i.filter(v);o.length?t[s]=o:delete t[s]}r.safeStorage.set(_,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(t?this.api.logBeacon(s):this.api.logRequest(s),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()}}const Y=()=>{let e,t;try{e=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?e=!0:(e=!1,console.error(i))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!t&&document.referrer&&(t=document.referrer)}catch(i){console.error(i)}const s=t?new URL(t).hostname:void 0;return{isEmbed:e,host:s}},X=e=>e&&{[c.VideoQuality.INVARIANT]:exports.Quality.UNKNOWN,[c.VideoQuality.Q_144P]:exports.Quality.Q144P,[c.VideoQuality.Q_240P]:exports.Quality.Q240P,[c.VideoQuality.Q_360P]:exports.Quality.Q360P,[c.VideoQuality.Q_480P]:exports.Quality.Q480P,[c.VideoQuality.Q_720P]:exports.Quality.Q720P,[c.VideoQuality.Q_1080P]:exports.Quality.Q1080P,[c.VideoQuality.Q_1440P]:exports.Quality.Q1440P,[c.VideoQuality.Q_2160P]:exports.Quality.Q2160P,[c.VideoQuality.Q_4320P]:exports.Quality.UNKNOWN}[e],L=e=>e&&{[c.HttpConnectionType.HTTP1]:exports.ConnectionType.HTTP1,[c.HttpConnectionType.HTTP2]:exports.ConnectionType.HTTP2,[c.HttpConnectionType.QUIC]:exports.ConnectionType.HTTP3}[e],J=e=>{if(e!==void 0)switch(e){case c.VideoFormat.MPEG:return exports.ContentType.MP4;case c.VideoFormat.DASH:case c.VideoFormat.DASH_LIVE:return exports.ContentType.DASH;case c.VideoFormat.DASH_SEP:return exports.ContentType.DASH_SEP;case c.VideoFormat.DASH_ONDEMAND:return exports.ContentType.ONDEMAND_DASH;case c.VideoFormat.DASH_WEBM:case c.VideoFormat.DASH_LIVE_WEBM:return exports.ContentType.WEBM;case c.VideoFormat.DASH_WEBM_AV1:return exports.ContentType.AV1;case c.VideoFormat.DASH_LIVE_CMAF:return exports.ContentType.ONDEMAND_DASH_LIVE;case c.VideoFormat.HLS:case c.VideoFormat.HLS_LIVE:return exports.ContentType.HLS;case c.VideoFormat.HLS_ONDEMAND:return exports.ContentType.ONDEMAND_HLS;case c.VideoFormat.HLS_LIVE_CMAF:return exports.ContentType.ONDEMAND_HLS_LIVE;case c.VideoFormat.WEB_RTC_LIVE:return exports.ContentType.WEBRTC;default:return r.assertNever(e)}},w=e=>{if(e!==void 0)switch(e){case c.Surface.NONE:case c.Surface.INLINE:return;case c.Surface.FULLSCREEN:return S.FULLSCREEN;case c.Surface.SECOND_SCREEN:return S.EXTERNAL;case c.Surface.PIP:return S.PIP;default:return r.assertNever(e)}},Z=e=>{switch(e){case"slow-2g":return E.POOR;case"2g":return E.POOR;case"3g":return E.GOOD;case"4g":return E.EXCELLENT}};class tt{constructor(t){this.offset=void 0,this.offset=t}getOffset(){var t;return(t=this.offset)!==null&&t!==void 0?t:0}setOffset(t){this.offset=t}now(){var t;return Date.now()+((t=this.offset)!==null&&t!==void 0?t:0)}date(t=new Date){var s;return t.setTime(t.getTime()+((s=this.offset)!==null&&s!==void 0?s:0)),t}addServerTime(t,s){const i=Date.now(),o=t-i-s/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)}}const k=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),et=e=>new r.Observable(t=>{const s=new r.Subscription,i=r.merge(r.fromEvent(window,"beforeunload"),e.events.willDestruct$),o=new r.ValueSubject(void 0);let a;s.add(e.info.isLive$.pipe(r.filterChanged()).subscribe(g=>{a&&(a.unsubscribe(),o.next(void 0)),g?a=e.info.liveTime$.pipe(r.map(y=>y&&y/1e3)).subscribe(o):a=e.info.position$.subscribe(o),s.add(a)}));const{playing$:u,paused$:f}=e.events,h=e.events.willSeek$.pipe(r.filter(()=>e.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),d=e.events.seeked$.pipe(r.filter(()=>e.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),n=r.merge(u,d),l=r.merge(f,h,i,e.events.looped$);let p;return s.add(n.subscribe(()=>p=o.getValue())),s.add(l.subscribe(()=>{const g=o.getValue();r.isNullable(p)||p===g||r.isNullable(g)||(t.next({from:p,to:g}),p=void 0)})),s});class st{constructor(t,s){var i,o;this.subscription=new r.Subscription,this.timeSynchronisation=new tt,this.vsid=k(),this.seekAction$=new r.ValueSubject(exports.SeekAction.UNKNOWN),this.statContext=t,this.config={...(i=s.config)!==null&&i!==void 0?i:{},requestRetryCount:1};const a=new r.Subject;this.experimental={error$:a};const u=new W({apiKey:B,apiBaseUrl:x[s.apiEnv],apiEnv:s.apiEnv,error$:a,timeSynchronisation:this.timeSynchronisation});this.api=new H({apiTransport:u,refreshAuthToken:s.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:(o=this.statContext.mobile)!==null&&o!==void 0?o:!1,error$:a}),this.logger=new G({api:this.api,error$:a,userSalt:s.userSalt});const{isEmbed:f,host:h}=Y();this.isEmbed=f,this.embedParent=h,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const s=new r.Subscription,i=(n,l)=>s.add(n.subscribe(l));i(t.events.willStart$,()=>{this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(exports.SeekAction.UNKNOWN)}),i(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),i(t.events.willResume$,()=>{this.logPlay()}),i(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(et(t),n=>{const l=t.info.isLive$.getValue(),p={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};l?this.logWatchCoverageLive(p):this.logWatchCoverageRecord(p)});let o;i(t.info.isStalled$,n=>{n?o=r.now():(r.isNonNullable(o)&&this.logEmptyBuffer({duration:r.now()-o}),o=void 0)});let a=!1;s.add(t.events.fatalError$.pipe(r.once()).subscribe(()=>a=!0)),i(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const l=r.isNonNullable(o)?r.now()-o:void 0;this.logCloseAtEmptyBuffer({duration:l!=null?l:0}),o=void 0}else a||this.logActionStop()}),i(t.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),i(t.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let u,f,h=!1;i(t.events.firstBytes$,n=>{u=r.now(),this.logFirstBytes({time:n})}),i(t.events.willStart$,()=>f=r.now()),i(t.info.currentBuffer$,n=>{!h&&n&&n.end-n.start>0&&r.isNonNullable(u)&&(this.logPlayerReady({duration:r.now()-u}),h=!0)}),i(t.events.firstFrame$,()=>{r.isNonNullable(u)&&!h&&(this.logPlayerReady({duration:r.now()-u}),h=!0),r.isNonNullable(f)&&this.logFirstFrame({time:r.now()-f})}),i(t.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),i(r.combine({muted:t.info.muted$,volume:t.info.volume$}),({muted:n,volume:l})=>this.updateContext({audible:!n&&l>0})),i(t.info.currentQuality$,n=>this.updateContext({quality:X(n)})),i(t.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),i(t.info.currentFormat$,n=>this.updateContext({contentType:J(n)}));let d;return i(t.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),i(t.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),i(t.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:L(n)}),this.updateContext({connectionType:L(n)})}),i(t.info.httpConnectionReused$,n=>{r.isNullable(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),i(t.info.surface$,n=>this.updateContext({mode:w(n)})),i(r.combine({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:n,available:l})=>{const p=l.find(({id:g})=>g===n);this.updateContext({subtitles:p==null?void 0:p.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToUi(t){this.uiEvents=t;const s=new r.Subscription;return this.player&&(s.add(t.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),s.add(t.actionSeek$.subscribe(this.seekAction$)),s.add(t.inPiP$.subscribe(i=>{var o;const a=i?S.PIP:w((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:a})})),s.add(t.inFullscreen$.subscribe(i=>{var o;const a=i?S.FULLSCREEN:w((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:a})})),s.add(t.actionSetSubtitle$.subscribe(i=>{this.updateContext({subtitles:i})})),this.resubscribeBeforeunload(),this.subscription.add(s)),s}attachToAds(t){const s=new r.Subscription;return s.add(t.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(t.started$.subscribe(i=>this.logAdStarted(i))).add(t.paused$.subscribe(()=>this.logAdPaused())).add(t.resumed$.subscribe(()=>this.logAdResumed())).add(t.ended$.subscribe(()=>this.logAdEnded())).add(t.skipped$.subscribe(()=>this.logAdSkipped())).add(t.clicked$.subscribe(()=>this.logAdClicked())),this.resubscribeBeforeunload(),this.subscription.add(s),s}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=k()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const s=t.start+this.timeSynchronisation.getOffset(),i=t.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${s}-${i}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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"})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(r.merge(r.fromEvent(t,"change"),r.observableFrom(["init"])).subscribe(()=>this.updateContext({network:Z(t.effectiveType)})))}resubscribeBeforeunload(){var t;(t=this.beforeunloadSubscription)===null||t===void 0||t.unsubscribe(),this.beforeunloadSubscription=r.fromEvent(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){const s=this.createLogItem(t);this.logger.log(s)}createLogItem({operation:t,param:s,time:i}){const o=this.timeSynchronisation.now(),a=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,u=this.statContext.firstConnectionReused,f={vsid:this.vsid,vid:this.statContext.movieId,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?A.AUTO:this.statContext.autoplay===!1?A.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:a,connection_reused:u===!0?b.YES:u===!1?b.NO:void 0,cached_data:this.statContext.cached===!0?b.YES:this.statContext.cached===!1?b.NO:void 0,live:this.statContext.liveEdge?b.YES:void 0,muted:this.statContext.audible===!1?b.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:b.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:t,type:1,time:i,network:this.statContext.network,timestamp:o,custom:f}}}exports.OneStat=st;exports.VERSION=T;
|
package/es2018.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vkontakte/videoplayer-statistics v1.0.
|
|
3
|
-
* Mon,
|
|
4
|
-
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-
|
|
2
|
+
* @vkontakte/videoplayer-statistics v1.0.37
|
|
3
|
+
* Mon, 10 Jul 2023 15:30:39 GMT
|
|
4
|
+
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-37/doc/
|
|
5
5
|
*/
|
|
6
|
-
import{ValueSubject as q,safeStorage as y,getExponentialDelay as ot,ErrorCategory as b,now as m,assertNever as Z,Observable as rt,Subscription as N,merge as C,fromEvent as U,filterChanged as nt,map as at,filter as M,isNullable as B,Subject as ut,once as ct,combine as W,observableFrom as lt,isNonNullable as O}from"@vkontakte/videoplayer-shared/es2018.esm.js";import V from"lodash/debounce.js";import{Surface as R,VideoQuality as S,HttpConnectionType as I,VideoFormat as f,PlaybackState as K}from"@vkontakte/videoplayer-core/es2018.esm.js";function ht(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,t[o]=e[o===19?i&3|8:i]);return t.join("")}var A;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(A||(A={}));var p;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(p||(p={}));var g;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(g||(g={}));var x;(function(e){e.AUTO="auto",e.MANUAL=""})(x||(x={}));var $;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})($||($={}));var _;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(_||(_={}));var P;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(P||(P={}));var w;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(w||(w={}));var k;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(k||(k={}));const z="1.0.35",dt="CIOPGQJGDIHBABABA",tt={[A.PROD]:"https://api.ok.ru",[A.VK_ALIAS]:"https://api.mycdn.me",[A.VIDEOTEST]:"https://videotestapi.ok.ru/api",[A.TEST]:"https://apitest.ok.ru",[A.AUTO]:""},ft="_one-stat_",Q=`${ft}uuid`,pt={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var v;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(v||(v={}));class gt{constructor(t){this.consequentAuthErrors=0,this.authorized$=new q(!1),this.params=t;const s=y.get(Q);s?this.uuid=String(s):(this.uuid=ht(),y.set(Q,this.uuid))}async authorize(t){return this.authToken=t!=null?t:await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(t)}async logRequest(t){var s;const i="log.externalLog",o=this.createLogParams(t),n=(s=this.sessionKey)!==null&&s!==void 0?s:await this._authorizeWithBackoff();if(!n)return;const a=async(h,l=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,o,n)}catch(c){if(!c||!("error_code"in c)){this.params.error$.next({id:"logRequestUnknown",category:b.NETWORK,message:`Unknown ${i} error`,thrown:c});return}const r=c==null?void 0:c.error_code;switch(r){case v.PARAM_SESSION_EXPIRED:case v.PARAM_SESSION_KEY:case v.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?a(h,l-1):void 0;case v.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),l>0?a(h,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${r}`,category:b.EXTERNAL_API,message:`${i} error`,data:c});return}}}};return a(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${z}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=ot(this.consequentAuthErrors,pt);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:b.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:z.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(t,s).then(i=>{var o;return(!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:b.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=(o=i==null?void 0:i.session_key)!==null&&o!==void 0?o:void 0,this.sessionKey}).catch(async i=>{this.sessionKey=void 0;const o=i==null?void 0:i.error_code;switch(o){case v.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:b.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:b.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class j{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,s,i){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:s,options:i})}removeEventListener(t,s){if(!(t in this.listeners))return;const i=this.listeners[t];for(let o=0,n=i.length;o<n;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const i=this.listeners[t.type].slice();for(let o=0,n=i.length;o<n;o++){const a=i[o];try{a.callback.call(this,t)}catch(h){Promise.resolve().then(()=>{throw h})}a.options&&a.options.once&&this.removeEventListener(t.type,a.callback)}return!t.defaultPrevented}}class et extends j{constructor(){super(),this.listeners||j.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class mt{constructor(){Object.defineProperty(this,"signal",{value:new et,writable:!0,configurable:!0})}abort(t){let s;try{s=new Event("abort")}catch(o){typeof document!="undefined"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=t;if(i===void 0)if(typeof document=="undefined")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch(o){i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol!="undefined"&&Symbol.toStringTag&&(mt.prototype[Symbol.toStringTag]="AbortController",et.prototype[Symbol.toStringTag]="AbortSignal");function st(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function bt(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:s=t.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!st({fetch:t,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:n};let n=s;(n&&!n.prototype.hasOwnProperty("signal")||o)&&(n=function(c,r){let u;r&&r.signal&&(u=r.signal,delete r.signal);const d=new s(c,r);return u&&Object.defineProperty(d,"signal",{writable:!1,enumerable:!1,configurable:!0,value:u}),d},n.prototype=s.prototype);const a=t;return{fetch:(l,c)=>{const r=n&&n.prototype.isPrototypeOf(l)?l.signal:c?c.signal:void 0;if(r){let u;try{u=new DOMException("Aborted","AbortError")}catch(E){u=new Error("Aborted"),u.name="AbortError"}if(r.aborted)return Promise.reject(u);const d=new Promise((E,T)=>{r.addEventListener("abort",()=>T(u),{once:!0})});return c&&c.signal&&delete c.signal,Promise.race([d,a(l,c)])}return a(l,c)},Request:n}}const H=st({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),it=H?bt({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,G=H?it.fetch:window.fetch;H?it.Request:window.Request;class St{constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.apiEnv,this.apiBaseUrl=t.apiBaseUrl,this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){var t;if(this.apiEnv!==A.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const s=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=await(await G(s,{method:"GET",mode:"cors",cache:"no-cache"})).json(),n=(t=o==null?void 0:o.Answer[0])===null||t===void 0?void 0:t.data;if(!n)throw new Error("Wrong DNS response");return n}catch(s){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:b.NETWORK,message:"Unhandled resolve api base url error",thrown:s}),tt[A.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:s,sessionKey:i}),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:b.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:t,params:s}})}return!1}async sendRequest(t,s,i){const o=m(),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:b.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:b.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:s,sessionKey:i,time:m()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),G(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:s,sessionKey:i})}).then(a=>{var h;const l=Number(a.headers.get("content-length"))===0,c=new Date((h=a.headers.get("date"))!==null&&h!==void 0?h:"").getTime(),r=m()-o;if(isFinite(c)&&this.timeSynchronisation.addServerTime(c,r),!l)return a.json().then(u=>Object.prototype.hasOwnProperty.call(u,"error_msg")?Promise.reject(u):u,n)},n)}_prepareQueryParams(t){const s=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&s.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const Y=5e3,Et=1e4,_t=6e4,L="onestat_events",At=36*60*60*1e3,D=e=>e.timestamp+At>=m();class vt{constructor(t){this.unsaltedStorage=[],this.isPaused=!1,this.isUrgent=s=>{const{operation:i,custom:{param:o}}=s;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&o==="0-0"},this.firstFlush=V(()=>this.safeFlush(),Y,{maxWait:Y}),this.debouncedFlush=V(()=>this.safeFlush(),Et,{maxWait:_t}),this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){var t;try{this.flush()}catch(s){this.error$.next({id:"LoggerError",category:b.WTF,message:(t=String(s))!==null&&t!==void 0?t:"Unknown logger error",thrown:s})}}readFromStorage(){const t=y.get(L);try{return t?JSON.parse(t):{}}catch(s){}return{}}addToStorage(t){var s;if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),n=((s=i[this.userSalt])!==null&&s!==void 0?s:[]).filter(D);y.set(L,JSON.stringify({...i,[this.userSalt]:[...n,t]}))}getFromStorage(){var t;return this.userSalt?((t=this.readFromStorage()[this.userSalt])!==null&&t!==void 0?t:[]).filter(D):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],y.set(L,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[s,i]of Object.entries(t)){const o=i.filter(D);o.length?t[s]=o:delete t[s]}y.set(L,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(t?this.api.logBeacon(s):this.api.logRequest(s),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()}}const wt=()=>{let e,t;try{e=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?e=!0:(e=!1,console.error(i))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!t&&document.referrer&&(t=document.referrer)}catch(i){console.error(i)}const s=t?new URL(t).hostname:void 0;return{isEmbed:e,host:s}},yt=e=>e&&{[S.INVARIANT]:p.UNKNOWN,[S.Q_144P]:p.Q144P,[S.Q_240P]:p.Q240P,[S.Q_360P]:p.Q360P,[S.Q_480P]:p.Q480P,[S.Q_720P]:p.Q720P,[S.Q_1080P]:p.Q1080P,[S.Q_1440P]:p.Q1440P,[S.Q_2160P]:p.Q2160P,[S.Q_4320P]:p.UNKNOWN}[e],X=e=>e&&{[I.HTTP1]:$.HTTP1,[I.HTTP2]:$.HTTP2,[I.QUIC]:$.HTTP3}[e],Pt=e=>{if(e!==void 0)switch(e){case f.MPEG:return g.MP4;case f.DASH:case f.DASH_LIVE:return g.DASH;case f.DASH_SEP:return g.DASH_SEP;case f.DASH_ONDEMAND:return g.ONDEMAND_DASH;case f.DASH_WEBM:case f.DASH_WEBM_AV1:case f.DASH_LIVE_WEBM:return g.WEBM;case f.DASH_LIVE_CMAF:return g.ONDEMAND_DASH_LIVE;case f.HLS:case f.HLS_LIVE:return g.HLS;case f.HLS_ONDEMAND:return g.ONDEMAND_HLS;case f.HLS_LIVE_CMAF:return g.ONDEMAND_HLS_LIVE;case f.WEB_RTC_LIVE:return g.WEBRTC;default:return Z(e)}},F=e=>{if(e!==void 0)switch(e){case R.NONE:case R.INLINE:return;case R.FULLSCREEN:return w.FULLSCREEN;case R.SECOND_SCREEN:return w.EXTERNAL;case R.PIP:return w.PIP;default:return Z(e)}},Tt=e=>{switch(e){case"slow-2g":return P.POOR;case"2g":return P.POOR;case"3g":return P.GOOD;case"4g":return P.EXCELLENT}};class Ot{constructor(t){this.offset=void 0,this.offset=t}getOffset(){var t;return(t=this.offset)!==null&&t!==void 0?t:0}setOffset(t){this.offset=t}now(){var t;return Date.now()+((t=this.offset)!==null&&t!==void 0?t:0)}date(t=new Date){var s;return t.setTime(t.getTime()+((s=this.offset)!==null&&s!==void 0?s:0)),t}addServerTime(t,s){const i=Date.now(),o=t-i-s/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)}}const J=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Rt=e=>new rt(t=>{const s=new N,i=C(U(window,"beforeunload"),e.events.willDestruct$),o=new q(void 0);let n;e.info.isLive$.pipe(nt()).subscribe(E=>{n&&(n.unsubscribe(),o.next(void 0)),E?n=e.info.liveTime$.pipe(at(T=>T&&T/1e3)).subscribe(o):n=e.info.position$.subscribe(o),s.add(n)});const{playing$:a,paused$:h}=e.events,l=e.events.willSeek$.pipe(M(()=>e.info.playbackState$.getValue()===K.PLAYING)),c=e.events.seeked$.pipe(M(()=>e.info.playbackState$.getValue()===K.PLAYING)),r=C(a,c),u=C(h,l,i,e.events.looped$);let d;return s.add(r.subscribe(()=>d=o.getValue())),s.add(u.subscribe(()=>{const E=o.getValue();B(d)||d===E||B(E)||(t.next({from:d,to:E}),d=void 0)})),s});class Ct{constructor(t,s){var i,o;this.subscription=new N,this.timeSynchronisation=new Ot,this.vsid=J(),this.seekAction$=new q(k.UNKNOWN),this.statContext=t,this.config={...(i=s.config)!==null&&i!==void 0?i:{},requestRetryCount:1};const n=new ut;this.experimental={error$:n};const a=new St({apiKey:dt,apiBaseUrl:tt[s.apiEnv],apiEnv:s.apiEnv,error$:n,timeSynchronisation:this.timeSynchronisation});this.api=new gt({apiTransport:a,refreshAuthToken:s.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:(o=this.statContext.mobile)!==null&&o!==void 0?o:!1,error$:n}),this.logger=new vt({api:this.api,error$:n,userSalt:s.userSalt});const{isEmbed:h,host:l}=wt();this.isEmbed=h,this.embedParent=l,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const s=new N,i=(r,u)=>s.add(r.subscribe(u));i(t.events.willStart$,()=>{this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(k.UNKNOWN)}),i(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),i(t.events.willResume$,()=>{this.logPlay()}),i(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(Rt(t),r=>{const u=t.info.isLive$.getValue(),d={start:parseFloat(r.from.toFixed(3)),end:parseFloat(r.to.toFixed(3))};u?this.logWatchCoverageLive(d):this.logWatchCoverageRecord(d)});let o;i(t.info.isStalled$,r=>{r?o=m():(O(o)&&this.logEmptyBuffer({duration:m()-o}),o=void 0)});let n=!1;s.add(t.events.fatalError$.pipe(ct()).subscribe(()=>n=!0)),i(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const u=O(o)?m()-o:void 0;this.logCloseAtEmptyBuffer({duration:u!=null?u:0}),o=void 0}else n||this.logActionStop()}),i(t.events.managedError$,({id:r})=>{this.logError({fatal:!1,errorType:r})}),i(t.events.fatalError$,({id:r})=>{this.logError({fatal:!0,errorType:r})});let a,h,l=!1;i(t.events.firstBytes$,r=>{a=m(),this.logFirstBytes({time:r})}),i(t.events.willStart$,()=>h=m()),i(t.info.currentBuffer$,r=>{!l&&r&&r.end-r.start>0&&O(a)&&(this.logPlayerReady({duration:m()-a}),l=!0)}),i(t.events.firstFrame$,()=>{O(a)&&!l&&(this.logPlayerReady({duration:m()-a}),l=!0),O(h)&&this.logFirstFrame({time:m()-h})}),i(t.info.atLiveEdge$,r=>this.updateContext({liveEdge:r})),i(W({muted:t.info.muted$,volume:t.info.volume$}),({muted:r,volume:u})=>this.updateContext({audible:!r&&u>0})),i(t.info.currentQuality$,r=>this.updateContext({quality:yt(r)})),i(t.info.isAutoQualityEnabled$,r=>this.updateContext({autoQuality:r})),i(t.info.currentFormat$,r=>this.updateContext({contentType:Pt(r)}));let c;return i(t.info.hostname$,r=>{this.updateContext({cdnHostname:r,failover:c!==void 0&&c!==r}),c=r}),i(t.info.throughputEstimation$,r=>this.updateContext({downloadSpeed:r})),i(t.info.httpConnectionType$,r=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:X(r)}),this.updateContext({connectionType:X(r)})}),i(t.info.httpConnectionReused$,r=>{B(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:r}),this.updateContext({connectionReused:r})}),i(t.info.surface$,r=>this.updateContext({mode:F(r)})),i(W({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:r,available:u})=>{const d=u.find(({id:E})=>E===r);this.updateContext({subtitles:d==null?void 0:d.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.subscription.add(s),s}attachToUi(t){this.uiEvents=t;const s=new N;return this.player&&(s.add(t.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),s.add(t.actionSeek$.subscribe(this.seekAction$)),s.add(t.inPiP$.subscribe(i=>{var o;const n=i?w.PIP:F((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:n})})),s.add(t.inFullscreen$.subscribe(i=>{var o;const n=i?w.FULLSCREEN:F((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:n})})),s.add(t.actionSetSubtitle$.subscribe(i=>{this.updateContext({subtitles:i})})),this.subscription.add(s)),s}attachToAds(t){const s=new N;return s.add(t.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(t.started$.subscribe(i=>this.logAdStarted(i))).add(t.paused$.subscribe(()=>this.logAdPaused())).add(t.resumed$.subscribe(()=>this.logAdResumed())).add(t.ended$.subscribe(()=>this.logAdEnded())).add(t.skipped$.subscribe(()=>this.logAdSkipped())).add(t.clicked$.subscribe(()=>this.logAdClicked())),this.subscription.add(s),s}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=J()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const s=t.start+this.timeSynchronisation.getOffset(),i=t.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${s}-${i}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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"})}subscribe(){this.subscription.add(U(window,"beforeunload").subscribe(()=>this.logger.flush(!0)));const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(C(U(t,"change"),lt(["init"])).subscribe(()=>this.updateContext({network:Tt(t.effectiveType)})))}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){const s=this.createLogItem(t);this.logger.log(s)}createLogItem({operation:t,param:s,time:i}){const o=this.timeSynchronisation.now(),n=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,h={vsid:this.vsid,vid:this.statContext.movieId,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?x.AUTO:this.statContext.autoplay===!1?x.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:n,connection_reused:a===!0?_.YES:a===!1?_.NO:void 0,cached_data:this.statContext.cached===!0?_.YES:this.statContext.cached===!1?_.NO:void 0,live:this.statContext.liveEdge?_.YES:void 0,muted:this.statContext.audible===!1?_.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:_.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:t,type:1,time:i,network:this.statContext.network,timestamp:o,custom:h}}}export{A as ApiEnv,$ as ConnectionType,g as ContentType,Ct as OneStat,p as Quality,k as SeekAction,z as VERSION};
|
|
6
|
+
import{ValueSubject as M,safeStorage as v,getExponentialDelay as ot,ErrorCategory as m,now as b,assertNever as Z,Observable as rt,Subscription as N,merge as x,fromEvent as F,filterChanged as nt,map as at,filter as H,isNullable as U,Subject as ut,once as ct,combine as W,observableFrom as lt,isNonNullable as O}from"@vkontakte/videoplayer-shared/es2018.esm.js";import V from"lodash/debounce.js";import{Surface as R,VideoQuality as S,HttpConnectionType as I,VideoFormat as f,PlaybackState as K}from"@vkontakte/videoplayer-core/es2018.esm.js";function ht(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,t[o]=e[o===19?i&3|8:i]);return t.join("")}var A;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(A||(A={}));var g;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(g||(g={}));var p;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(p||(p={}));var C;(function(e){e.AUTO="auto",e.MANUAL=""})(C||(C={}));var $;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})($||($={}));var _;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(_||(_={}));var P;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(P||(P={}));var y;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(y||(y={}));var k;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(k||(k={}));const z="1.0.37",dt="CIOPGQJGDIHBABABA",tt={[A.PROD]:"https://api.ok.ru",[A.VK_ALIAS]:"https://api.mycdn.me",[A.VIDEOTEST]:"https://videotestapi.ok.ru/api",[A.TEST]:"https://apitest.ok.ru",[A.AUTO]:""},ft="_one-stat_",Q=`${ft}uuid`,pt={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var w;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(w||(w={}));class gt{constructor(t){this.consequentAuthErrors=0,this.authorized$=new M(!1),this.params=t;const s=v.get(Q);s?this.uuid=String(s):(this.uuid=ht(),v.set(Q,this.uuid))}async authorize(t){return this.authToken=t!=null?t:await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(t)}async logRequest(t){var s;const i="log.externalLog",o=this.createLogParams(t),n=(s=this.sessionKey)!==null&&s!==void 0?s:await this._authorizeWithBackoff();if(!n)return;const a=async(h,l=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,o,n)}catch(c){if(!c||!("error_code"in c)){this.params.error$.next({id:"logRequestUnknown",category:m.NETWORK,message:`Unknown ${i} error`,thrown:c});return}const r=c==null?void 0:c.error_code;switch(r){case w.PARAM_SESSION_EXPIRED:case w.PARAM_SESSION_KEY:case w.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?a(h,l-1):void 0;case w.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),l>0?a(h,l-1):void 0;default:{this.params.error$.next({id:`LogRequest#${r}`,category:m.EXTERNAL_API,message:`${i} error`,data:c});return}}}};return a(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${z}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=ot(this.consequentAuthErrors,pt);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:m.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:z.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(t,s).then(i=>{var o;return(!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:m.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=(o=i==null?void 0:i.session_key)!==null&&o!==void 0?o:void 0,this.sessionKey}).catch(async i=>{this.sessionKey=void 0;const o=i==null?void 0:i.error_code;switch(o){case w.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:m.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:m.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class j{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,s,i){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:s,options:i})}removeEventListener(t,s){if(!(t in this.listeners))return;const i=this.listeners[t];for(let o=0,n=i.length;o<n;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const i=this.listeners[t.type].slice();for(let o=0,n=i.length;o<n;o++){const a=i[o];try{a.callback.call(this,t)}catch(h){Promise.resolve().then(()=>{throw h})}a.options&&a.options.once&&this.removeEventListener(t.type,a.callback)}return!t.defaultPrevented}}class et extends j{constructor(){super(),this.listeners||j.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class bt{constructor(){Object.defineProperty(this,"signal",{value:new et,writable:!0,configurable:!0})}abort(t){let s;try{s=new Event("abort")}catch(o){typeof document!="undefined"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=t;if(i===void 0)if(typeof document=="undefined")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch(o){i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol!="undefined"&&Symbol.toStringTag&&(bt.prototype[Symbol.toStringTag]="AbortController",et.prototype[Symbol.toStringTag]="AbortSignal");function st(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function mt(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:s=t.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!st({fetch:t,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:n};let n=s;(n&&!n.prototype.hasOwnProperty("signal")||o)&&(n=function(c,r){let u;r&&r.signal&&(u=r.signal,delete r.signal);const d=new s(c,r);return u&&Object.defineProperty(d,"signal",{writable:!1,enumerable:!1,configurable:!0,value:u}),d},n.prototype=s.prototype);const a=t;return{fetch:(l,c)=>{const r=n&&n.prototype.isPrototypeOf(l)?l.signal:c?c.signal:void 0;if(r){let u;try{u=new DOMException("Aborted","AbortError")}catch(E){u=new Error("Aborted"),u.name="AbortError"}if(r.aborted)return Promise.reject(u);const d=new Promise((E,T)=>{r.addEventListener("abort",()=>T(u),{once:!0})});return c&&c.signal&&delete c.signal,Promise.race([d,a(l,c)])}return a(l,c)},Request:n}}const q=st({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),it=q?mt({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,G=q?it.fetch:window.fetch;q?it.Request:window.Request;class St{constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.apiEnv,this.apiBaseUrl=t.apiBaseUrl,this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){var t;if(this.apiEnv!==A.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const s=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=await(await G(s,{method:"GET",mode:"cors",cache:"no-cache"})).json(),n=(t=o==null?void 0:o.Answer[0])===null||t===void 0?void 0:t.data;if(!n)throw new Error("Wrong DNS response");return n}catch(s){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:m.NETWORK,message:"Unhandled resolve api base url error",thrown:s}),tt[A.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:s,sessionKey:i}),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:m.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:t,params:s}})}return!1}async sendRequest(t,s,i){const o=b(),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:m.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:m.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:s,sessionKey:i,time:b()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),G(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:s,sessionKey:i})}).then(a=>{var h;const l=Number(a.headers.get("content-length"))===0,c=new Date((h=a.headers.get("date"))!==null&&h!==void 0?h:"").getTime(),r=b()-o;if(isFinite(c)&&this.timeSynchronisation.addServerTime(c,r),!l)return a.json().then(u=>Object.prototype.hasOwnProperty.call(u,"error_msg")?Promise.reject(u):u,n)},n)}_prepareQueryParams(t){const s=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&s.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const Y=5e3,Et=1e4,_t=6e4,L="onestat_events",At=36*60*60*1e3,D=e=>e.timestamp+At>=b();class vt{constructor(t){this.unsaltedStorage=[],this.isPaused=!1,this.flushMaxWait=v.isPersistent()?_t:0,this.isUrgent=s=>{const{operation:i,custom:{param:o}}=s;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&o==="0-0"},this.firstFlush=V(()=>this.safeFlush(),Y,{maxWait:Y}),this.debouncedFlush=V(()=>this.safeFlush(),Et,{maxWait:this.flushMaxWait}),this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}safeFlush(){var t;try{this.flush()}catch(s){this.error$.next({id:"LoggerError",category:m.WTF,message:(t=String(s))!==null&&t!==void 0?t:"Unknown logger error",thrown:s})}}readFromStorage(){const t=v.get(L);try{return t?JSON.parse(t):{}}catch(s){}return{}}addToStorage(t){var s;if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),n=((s=i[this.userSalt])!==null&&s!==void 0?s:[]).filter(D);v.set(L,JSON.stringify({...i,[this.userSalt]:[...n,t]}))}getFromStorage(){var t;return this.userSalt?((t=this.readFromStorage()[this.userSalt])!==null&&t!==void 0?t:[]).filter(D):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],v.set(L,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[s,i]of Object.entries(t)){const o=i.filter(D);o.length?t[s]=o:delete t[s]}v.set(L,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(t?this.api.logBeacon(s):this.api.logRequest(s),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()}}const wt=()=>{let e,t;try{e=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?e=!0:(e=!1,console.error(i))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!t&&document.referrer&&(t=document.referrer)}catch(i){console.error(i)}const s=t?new URL(t).hostname:void 0;return{isEmbed:e,host:s}},yt=e=>e&&{[S.INVARIANT]:g.UNKNOWN,[S.Q_144P]:g.Q144P,[S.Q_240P]:g.Q240P,[S.Q_360P]:g.Q360P,[S.Q_480P]:g.Q480P,[S.Q_720P]:g.Q720P,[S.Q_1080P]:g.Q1080P,[S.Q_1440P]:g.Q1440P,[S.Q_2160P]:g.Q2160P,[S.Q_4320P]:g.UNKNOWN}[e],X=e=>e&&{[I.HTTP1]:$.HTTP1,[I.HTTP2]:$.HTTP2,[I.QUIC]:$.HTTP3}[e],Pt=e=>{if(e!==void 0)switch(e){case f.MPEG:return p.MP4;case f.DASH:case f.DASH_LIVE:return p.DASH;case f.DASH_SEP:return p.DASH_SEP;case f.DASH_ONDEMAND:return p.ONDEMAND_DASH;case f.DASH_WEBM:case f.DASH_LIVE_WEBM:return p.WEBM;case f.DASH_WEBM_AV1:return p.AV1;case f.DASH_LIVE_CMAF:return p.ONDEMAND_DASH_LIVE;case f.HLS:case f.HLS_LIVE:return p.HLS;case f.HLS_ONDEMAND:return p.ONDEMAND_HLS;case f.HLS_LIVE_CMAF:return p.ONDEMAND_HLS_LIVE;case f.WEB_RTC_LIVE:return p.WEBRTC;default:return Z(e)}},B=e=>{if(e!==void 0)switch(e){case R.NONE:case R.INLINE:return;case R.FULLSCREEN:return y.FULLSCREEN;case R.SECOND_SCREEN:return y.EXTERNAL;case R.PIP:return y.PIP;default:return Z(e)}},Tt=e=>{switch(e){case"slow-2g":return P.POOR;case"2g":return P.POOR;case"3g":return P.GOOD;case"4g":return P.EXCELLENT}};class Ot{constructor(t){this.offset=void 0,this.offset=t}getOffset(){var t;return(t=this.offset)!==null&&t!==void 0?t:0}setOffset(t){this.offset=t}now(){var t;return Date.now()+((t=this.offset)!==null&&t!==void 0?t:0)}date(t=new Date){var s;return t.setTime(t.getTime()+((s=this.offset)!==null&&s!==void 0?s:0)),t}addServerTime(t,s){const i=Date.now(),o=t-i-s/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)}}const J=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Rt=e=>new rt(t=>{const s=new N,i=x(F(window,"beforeunload"),e.events.willDestruct$),o=new M(void 0);let n;s.add(e.info.isLive$.pipe(nt()).subscribe(E=>{n&&(n.unsubscribe(),o.next(void 0)),E?n=e.info.liveTime$.pipe(at(T=>T&&T/1e3)).subscribe(o):n=e.info.position$.subscribe(o),s.add(n)}));const{playing$:a,paused$:h}=e.events,l=e.events.willSeek$.pipe(H(()=>e.info.playbackState$.getValue()===K.PLAYING)),c=e.events.seeked$.pipe(H(()=>e.info.playbackState$.getValue()===K.PLAYING)),r=x(a,c),u=x(h,l,i,e.events.looped$);let d;return s.add(r.subscribe(()=>d=o.getValue())),s.add(u.subscribe(()=>{const E=o.getValue();U(d)||d===E||U(E)||(t.next({from:d,to:E}),d=void 0)})),s});class xt{constructor(t,s){var i,o;this.subscription=new N,this.timeSynchronisation=new Ot,this.vsid=J(),this.seekAction$=new M(k.UNKNOWN),this.statContext=t,this.config={...(i=s.config)!==null&&i!==void 0?i:{},requestRetryCount:1};const n=new ut;this.experimental={error$:n};const a=new St({apiKey:dt,apiBaseUrl:tt[s.apiEnv],apiEnv:s.apiEnv,error$:n,timeSynchronisation:this.timeSynchronisation});this.api=new gt({apiTransport:a,refreshAuthToken:s.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:(o=this.statContext.mobile)!==null&&o!==void 0?o:!1,error$:n}),this.logger=new vt({api:this.api,error$:n,userSalt:s.userSalt});const{isEmbed:h,host:l}=wt();this.isEmbed=h,this.embedParent=l,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const s=new N,i=(r,u)=>s.add(r.subscribe(u));i(t.events.willStart$,()=>{this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(k.UNKNOWN)}),i(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),i(t.events.willResume$,()=>{this.logPlay()}),i(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(Rt(t),r=>{const u=t.info.isLive$.getValue(),d={start:parseFloat(r.from.toFixed(3)),end:parseFloat(r.to.toFixed(3))};u?this.logWatchCoverageLive(d):this.logWatchCoverageRecord(d)});let o;i(t.info.isStalled$,r=>{r?o=b():(O(o)&&this.logEmptyBuffer({duration:b()-o}),o=void 0)});let n=!1;s.add(t.events.fatalError$.pipe(ct()).subscribe(()=>n=!0)),i(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const u=O(o)?b()-o:void 0;this.logCloseAtEmptyBuffer({duration:u!=null?u:0}),o=void 0}else n||this.logActionStop()}),i(t.events.managedError$,({id:r})=>{this.logError({fatal:!1,errorType:r})}),i(t.events.fatalError$,({id:r})=>{this.logError({fatal:!0,errorType:r})});let a,h,l=!1;i(t.events.firstBytes$,r=>{a=b(),this.logFirstBytes({time:r})}),i(t.events.willStart$,()=>h=b()),i(t.info.currentBuffer$,r=>{!l&&r&&r.end-r.start>0&&O(a)&&(this.logPlayerReady({duration:b()-a}),l=!0)}),i(t.events.firstFrame$,()=>{O(a)&&!l&&(this.logPlayerReady({duration:b()-a}),l=!0),O(h)&&this.logFirstFrame({time:b()-h})}),i(t.info.atLiveEdge$,r=>this.updateContext({liveEdge:r})),i(W({muted:t.info.muted$,volume:t.info.volume$}),({muted:r,volume:u})=>this.updateContext({audible:!r&&u>0})),i(t.info.currentQuality$,r=>this.updateContext({quality:yt(r)})),i(t.info.isAutoQualityEnabled$,r=>this.updateContext({autoQuality:r})),i(t.info.currentFormat$,r=>this.updateContext({contentType:Pt(r)}));let c;return i(t.info.hostname$,r=>{this.updateContext({cdnHostname:r,failover:c!==void 0&&c!==r}),c=r}),i(t.info.throughputEstimation$,r=>this.updateContext({downloadSpeed:r})),i(t.info.httpConnectionType$,r=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:X(r)}),this.updateContext({connectionType:X(r)})}),i(t.info.httpConnectionReused$,r=>{U(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:r}),this.updateContext({connectionReused:r})}),i(t.info.surface$,r=>this.updateContext({mode:B(r)})),i(W({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:r,available:u})=>{const d=u.find(({id:E})=>E===r);this.updateContext({subtitles:d==null?void 0:d.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToUi(t){this.uiEvents=t;const s=new N;return this.player&&(s.add(t.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),s.add(t.actionSeek$.subscribe(this.seekAction$)),s.add(t.inPiP$.subscribe(i=>{var o;const n=i?y.PIP:B((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:n})})),s.add(t.inFullscreen$.subscribe(i=>{var o;const n=i?y.FULLSCREEN:B((o=this.player)===null||o===void 0?void 0:o.info.surface$.getValue());this.updateContext({mode:n})})),s.add(t.actionSetSubtitle$.subscribe(i=>{this.updateContext({subtitles:i})})),this.resubscribeBeforeunload(),this.subscription.add(s)),s}attachToAds(t){const s=new N;return s.add(t.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(t.started$.subscribe(i=>this.logAdStarted(i))).add(t.paused$.subscribe(()=>this.logAdPaused())).add(t.resumed$.subscribe(()=>this.logAdResumed())).add(t.ended$.subscribe(()=>this.logAdEnded())).add(t.skipped$.subscribe(()=>this.logAdSkipped())).add(t.clicked$.subscribe(()=>this.logAdClicked())),this.resubscribeBeforeunload(),this.subscription.add(s),s}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=J()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const s=t.start+this.timeSynchronisation.getOffset(),i=t.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${s}-${i}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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"})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(x(F(t,"change"),lt(["init"])).subscribe(()=>this.updateContext({network:Tt(t.effectiveType)})))}resubscribeBeforeunload(){var t;(t=this.beforeunloadSubscription)===null||t===void 0||t.unsubscribe(),this.beforeunloadSubscription=F(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){const s=this.createLogItem(t);this.logger.log(s)}createLogItem({operation:t,param:s,time:i}){const o=this.timeSynchronisation.now(),n=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,h={vsid:this.vsid,vid:this.statContext.movieId,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?C.AUTO:this.statContext.autoplay===!1?C.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:n,connection_reused:a===!0?_.YES:a===!1?_.NO:void 0,cached_data:this.statContext.cached===!0?_.YES:this.statContext.cached===!1?_.NO:void 0,live:this.statContext.liveEdge?_.YES:void 0,muted:this.statContext.audible===!1?_.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:_.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:t,type:1,time:i,network:this.statContext.network,timestamp:o,custom:h}}}export{A as ApiEnv,$ as ConnectionType,p as ContentType,xt as OneStat,g as Quality,k as SeekAction,z as VERSION};
|
package/esnext.cjs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vkontakte/videoplayer-statistics v1.0.
|
|
3
|
-
* Mon,
|
|
4
|
-
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-
|
|
2
|
+
* @vkontakte/videoplayer-statistics v1.0.37
|
|
3
|
+
* Mon, 10 Jul 2023 15:30:39 GMT
|
|
4
|
+
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-37/doc/
|
|
5
5
|
*/
|
|
6
|
-
"use strict";var r=require("@vkontakte/videoplayer-shared/esnext.cjs.js"),C=require("lodash/debounce.js"),c=require("@vkontakte/videoplayer-core/esnext.cjs.js");function V(){const t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36);let o=0,s,i;for(i=0;i<36;i++)i===8||i===13||i===18||i===23?e[i]="-":i===14?e[i]="4":(o<=2&&(o=33554432+Math.random()*16777216|0),s=o&15,o=o>>4,e[i]=t[i===19?s&3|8:s]);return e.join("")}exports.ApiEnv=void 0;(function(t){t.PROD="prod",t.VK_ALIAS="vk_alias",t.VIDEOTEST="videotest",t.TEST="test",t.AUTO="auto"})(exports.ApiEnv||(exports.ApiEnv={}));exports.Quality=void 0;(function(t){t.Q144P="mobile",t.Q240P="lowest",t.Q360P="low",t.Q480P="medium",t.Q720P="high",t.Q1080P="fullhd",t.Q1440P="quadhd",t.Q2160P="ultrahd",t.UNKNOWN="unknown"})(exports.Quality||(exports.Quality={}));exports.ContentType=void 0;(function(t){t.MP4="mp4",t.DASH="dash",t.DASH_SEP="dash_sep",t.ONDEMAND_DASH="ondemand_dash",t.HLS="hls",t.ONDEMAND_HLS="ondemand_hls",t.WEBM="webm",t.ONDEMAND_DASH_LIVE="ondemand_dash_live",t.ONDEMAND_HLS_LIVE="ondemand_hls_live",t.WEBRTC="webrtc",t.UNKNOWN="unknown",t.RTMP="rtmp"})(exports.ContentType||(exports.ContentType={}));var _;(function(t){t.AUTO="auto",t.MANUAL=""})(_||(_={}));exports.ConnectionType=void 0;(function(t){t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3"})(exports.ConnectionType||(exports.ConnectionType={}));var m;(function(t){t[t.YES=1]="YES",t[t.NO=0]="NO"})(m||(m={}));var E;(function(t){t.EXCELLENT="excellent",t.GOOD="good",t.POOR="poor"})(E||(E={}));var S;(function(t){t.PIP="pip",t.FULLSCREEN="fullscreen",t.EXTERNAL="external",t.PREFETCH="prefetch"})(S||(S={}));exports.SeekAction=void 0;(function(t){t.SLIDER="slider",t.DOUBLE_TAP="double_tap",t.TIME_CODE="time_code",t.EPISODE="episode",t.REWIND="rewind",t.LIVE="live",t.UNKNOWN="unknown"})(exports.SeekAction||(exports.SeekAction={}));const P="1.0.35",U="CIOPGQJGDIHBABABA",x={[exports.ApiEnv.PROD]:"https://api.ok.ru",[exports.ApiEnv.VK_ALIAS]:"https://api.mycdn.me",[exports.ApiEnv.VIDEOTEST]:"https://videotestapi.ok.ru/api",[exports.ApiEnv.TEST]:"https://apitest.ok.ru",[exports.ApiEnv.AUTO]:""},B="_one-stat_",N=`${B}uuid`,q={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var b;(function(t){t[t.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",t[t.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",t[t.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",t[t.AUTH_LOGIN=401]="AUTH_LOGIN"})(b||(b={}));class H{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new r.ValueSubject(!1);backoffTimeoutId;constructor(e){this.params=e;const o=r.safeStorage.get(N);o?this.uuid=String(o):(this.uuid=V(),r.safeStorage.set(N,this.uuid))}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){const o="log.externalLog",s=this.createLogParams(e),i=this.sessionKey;if(!i)return;this.params.apiTransport.sendBeacon(o,s,i)||this.logRequest(e)}async logRequest(e){const o="log.externalLog",s=this.createLogParams(e),i=this.sessionKey??await this._authorizeWithBackoff();if(!i)return;const a=async(u,f=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(o,s,i)}catch(l){if(!l||!("error_code"in l)){this.params.error$.next({id:"logRequestUnknown",category:r.ErrorCategory.NETWORK,message:`Unknown ${o} error`,thrown:l});return}const d=l?.error_code;switch(d){case b.PARAM_SESSION_EXPIRED:case b.PARAM_SESSION_KEY:case b.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(u,f-1):void 0;case b.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(u,f-1):void 0;default:{this.params.error$.next({id:`LogRequest#${d}`,category:r.ErrorCategory.EXTERNAL_API,message:`${o} error`,data:l});return}}}};return a(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${P}`,platform:this.params.mobile?"M_WEB":"WEB",items:e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const e=r.getExponentialDelay(this.consequentAuthErrors,q);return new Promise(o=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(o).catch(s=>this.params.error$.next({id:"AuthorizeBackoff",category:r.ErrorCategory.NETWORK,message:"Otherwise unhandled error in authorization",thrown:s})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const e="auth.anonymLogin",o={session_data:{version:2,device_id:this.uuid,client_version:P.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(o.session_data.auth_token=this.authToken,o.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,o).then(s=>((!s||!s.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:r.ErrorCategory.EXTERNAL_API,message:"No session key",data:s}),this.sessionKey=s?.session_key??void 0,this.sessionKey)).catch(async s=>{this.sessionKey=void 0;const i=s?.error_code;switch(i){case b.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}i?this.params.error$.next({id:`Authorize#${i}`,category:r.ErrorCategory.EXTERNAL_API,message:"authorize error",data:s}):this.params.error$.next({id:"AuthorizeUnknown",category:r.ErrorCategory.NETWORK,message:"authorize error",thrown:s})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class O{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(e,o,s){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push({callback:o,options:s})}removeEventListener(e,o){if(!(e in this.listeners))return;const s=this.listeners[e];for(let i=0,a=s.length;i<a;i++)if(s[i].callback===o){s.splice(i,1);return}}dispatchEvent(e){if(!(e.type in this.listeners))return;const s=this.listeners[e.type].slice();for(let i=0,a=s.length;i<a;i++){const u=s[i];try{u.callback.call(this,e)}catch(f){Promise.resolve().then(()=>{throw f})}u.options&&u.options.once&&this.removeEventListener(e.type,u.callback)}return!e.defaultPrevented}}class I extends O{constructor(){super(),this.listeners||O.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(e){e.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,e)),super.dispatchEvent(e)}}class M{constructor(){Object.defineProperty(this,"signal",{value:new I,writable:!0,configurable:!0})}abort(e){let o;try{o=new Event("abort")}catch{typeof document<"u"?document.createEvent?(o=document.createEvent("Event"),o.initEvent("abort",!1,!1)):(o=document.createEventObject(),o.type="abort"):o={type:"abort",bubbles:!1,cancelable:!1}}let s=e;if(s===void 0)if(typeof document>"u")s=new Error("This operation was aborted"),s.name="AbortError";else try{s=new DOMException("signal is aborted without reason")}catch{s=new Error("This operation was aborted"),s.name="AbortError"}this.signal.reason=s,this.signal.dispatchEvent(o)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(M.prototype[Symbol.toStringTag]="AbortController",I.prototype[Symbol.toStringTag]="AbortSignal");function F(t){return t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof t.Request=="function"&&!t.Request.prototype.hasOwnProperty("signal")||!t.AbortController}function Q(t){typeof t=="function"&&(t={fetch:t});const{fetch:e,Request:o=e.Request,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:i=!1}=t;if(!F({fetch:e,Request:o,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:i}))return{fetch:e,Request:a};let a=o;(a&&!a.prototype.hasOwnProperty("signal")||i)&&(a=function(d,n){let h;n&&n.signal&&(h=n.signal,delete n.signal);const p=new o(d,n);return h&&Object.defineProperty(p,"signal",{writable:!1,enumerable:!1,configurable:!0,value:h}),p},a.prototype=o.prototype);const u=e;return{fetch:(l,d)=>{const n=a&&a.prototype.isPrototypeOf(l)?l.signal:d?d.signal:void 0;if(n){let h;try{h=new DOMException("Aborted","AbortError")}catch{h=new Error("Aborted"),h.name="AbortError"}if(n.aborted)return Promise.reject(h);const p=new Promise((g,y)=>{n.addEventListener("abort",()=>y(h),{once:!0})});return d&&d.signal&&delete d.signal,Promise.race([p,u(l,d)])}return u(l,d)},Request:a}}const v=F({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),D=v?Q({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,R=v?D.fetch:window.fetch;v?D.Request:window.Request;class W{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(e){this.params=e,this.apiKey=e.apiKey,this.apiEnv=e.apiEnv,this.apiBaseUrl=e.apiBaseUrl,this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==exports.ApiEnv.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),i=(await(await R(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!i)throw new Error("Wrong DNS response");return i}catch(e){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:r.ErrorCategory.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),x[exports.ApiEnv.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,o,s){if(!window.Blob||!window.navigator.sendBeacon)return!1;const i=this._prepareQueryParams({method:e,queryParams:o,sessionKey:s}),a=new window.Blob([i.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,a)}catch(u){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:r.ErrorCategory.NETWORK,message:"Unhandled beacon error",thrown:u,data:{method:e,params:o}})}return!1}async sendRequest(e,o,s){const i=r.now(),a=u=>{if(u instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(u.message)){this.params.error$.next({id:"Network",category:r.ErrorCategory.NETWORK,message:"Request failed",thrown:u});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:r.ErrorCategory.NETWORK,message:"Unhandled request error",thrown:u,data:{method:e,params:o,sessionKey:s,time:r.now()-i}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),R(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:o,sessionKey:s})}).then(u=>{const f=Number(u.headers.get("content-length"))===0,l=new Date(u.headers.get("date")??"").getTime(),d=r.now()-i;if(isFinite(l)&&this.timeSynchronisation.addServerTime(l,d),!f)return u.json().then(n=>Object.prototype.hasOwnProperty.call(n,"error_msg")?Promise.reject(n):n,a)},a)}_prepareQueryParams(e){const o=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&o.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([s,i])=>o.append(s,typeof i=="string"?i:JSON.stringify(i))),o}}const k=5e3,K=1e4,z=6e4,A="onestat_events",j=36*60*60*1e3,w=t=>t.timestamp+j>=r.now();class G{api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;constructor(e){this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.subscription=this.api.authorized$.subscribe(o=>{o&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=e=>{const{operation:o,custom:{param:s}}=e;return["action_stop","close_at_empty_buffer"].includes(o)||o==="watch_coverage_record"&&s==="0-0"};safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:r.ErrorCategory.WTF,message:String(e)??"Unknown logger error",thrown:e})}}firstFlush=C(()=>this.safeFlush(),k,{maxWait:k});debouncedFlush=C(()=>this.safeFlush(),K,{maxWait:z});readFromStorage(){const e=r.safeStorage.get(A);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}const o=this.readFromStorage(),i=(o[this.userSalt]??[]).filter(w);r.safeStorage.set(A,JSON.stringify({...o,[this.userSalt]:[...i,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(w):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const e=this.readFromStorage();delete e[this.userSalt],r.safeStorage.set(A,JSON.stringify(e))}housekeepStorage(){const e=this.readFromStorage();for(const[o,s]of Object.entries(e)){const i=s.filter(w);i.length?e[o]=i:delete e[o]}r.safeStorage.set(A,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(e=!1){const o=this.getFromStorage();o.length!==0&&(this.api.authorized$.getValue()?(e?this.api.logBeacon(o):this.api.logRequest(o),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()}}const Y=()=>{let t,e;try{t=window.self!==window.top}catch(s){s instanceof DOMException&&s.name==="SecurityError"?t=!0:(t=!1,console.error(s))}try{window.location.ancestorOrigins&&(e=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(s){console.error(s)}try{!e&&document.referrer&&(e=document.referrer)}catch(s){console.error(s)}const o=e?new URL(e).hostname:void 0;return{isEmbed:t,host:o}},X=t=>t&&{[c.VideoQuality.INVARIANT]:exports.Quality.UNKNOWN,[c.VideoQuality.Q_144P]:exports.Quality.Q144P,[c.VideoQuality.Q_240P]:exports.Quality.Q240P,[c.VideoQuality.Q_360P]:exports.Quality.Q360P,[c.VideoQuality.Q_480P]:exports.Quality.Q480P,[c.VideoQuality.Q_720P]:exports.Quality.Q720P,[c.VideoQuality.Q_1080P]:exports.Quality.Q1080P,[c.VideoQuality.Q_1440P]:exports.Quality.Q1440P,[c.VideoQuality.Q_2160P]:exports.Quality.Q2160P,[c.VideoQuality.Q_4320P]:exports.Quality.UNKNOWN}[t],$=t=>t&&{[c.HttpConnectionType.HTTP1]:exports.ConnectionType.HTTP1,[c.HttpConnectionType.HTTP2]:exports.ConnectionType.HTTP2,[c.HttpConnectionType.QUIC]:exports.ConnectionType.HTTP3}[t],J=t=>{if(t!==void 0)switch(t){case c.VideoFormat.MPEG:return exports.ContentType.MP4;case c.VideoFormat.DASH:case c.VideoFormat.DASH_LIVE:return exports.ContentType.DASH;case c.VideoFormat.DASH_SEP:return exports.ContentType.DASH_SEP;case c.VideoFormat.DASH_ONDEMAND:return exports.ContentType.ONDEMAND_DASH;case c.VideoFormat.DASH_WEBM:case c.VideoFormat.DASH_WEBM_AV1:case c.VideoFormat.DASH_LIVE_WEBM:return exports.ContentType.WEBM;case c.VideoFormat.DASH_LIVE_CMAF:return exports.ContentType.ONDEMAND_DASH_LIVE;case c.VideoFormat.HLS:case c.VideoFormat.HLS_LIVE:return exports.ContentType.HLS;case c.VideoFormat.HLS_ONDEMAND:return exports.ContentType.ONDEMAND_HLS;case c.VideoFormat.HLS_LIVE_CMAF:return exports.ContentType.ONDEMAND_HLS_LIVE;case c.VideoFormat.WEB_RTC_LIVE:return exports.ContentType.WEBRTC;default:return r.assertNever(t)}},T=t=>{if(t!==void 0)switch(t){case c.Surface.NONE:case c.Surface.INLINE:return;case c.Surface.FULLSCREEN:return S.FULLSCREEN;case c.Surface.SECOND_SCREEN:return S.EXTERNAL;case c.Surface.PIP:return S.PIP;default:return r.assertNever(t)}},Z=t=>{switch(t){case"slow-2g":return E.POOR;case"2g":return E.POOR;case"3g":return E.GOOD;case"4g":return E.EXCELLENT}};class ee{offset=void 0;constructor(e){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,o){const s=Date.now(),i=e-s-o/2;if(Math.abs(i)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(i):this.offset=Math.round(.2*i+(1-.2)*this.offset)}}const L=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),te=t=>new r.Observable(e=>{const o=new r.Subscription,s=r.merge(r.fromEvent(window,"beforeunload"),t.events.willDestruct$),i=new r.ValueSubject(void 0);let a;t.info.isLive$.pipe(r.filterChanged()).subscribe(g=>{a&&(a.unsubscribe(),i.next(void 0)),g?a=t.info.liveTime$.pipe(r.map(y=>y&&y/1e3)).subscribe(i):a=t.info.position$.subscribe(i),o.add(a)});const{playing$:u,paused$:f}=t.events,l=t.events.willSeek$.pipe(r.filter(()=>t.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),d=t.events.seeked$.pipe(r.filter(()=>t.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),n=r.merge(u,d),h=r.merge(f,l,s,t.events.looped$);let p;return o.add(n.subscribe(()=>p=i.getValue())),o.add(h.subscribe(()=>{const g=i.getValue();r.isNullable(p)||p===g||r.isNullable(g)||(e.next({from:p,to:g}),p=void 0)})),o});class se{api;logger;config;subscription=new r.Subscription;timeSynchronisation=new ee;experimental;statContext;vsid=L();isEmbed;embedParent;uiEvents;player;seekAction$=new r.ValueSubject(exports.SeekAction.UNKNOWN);constructor(e,o){this.statContext=e,this.config={...o.config??{},requestRetryCount:1};const s=new r.Subject;this.experimental={error$:s};const i=new W({apiKey:U,apiBaseUrl:x[o.apiEnv],apiEnv:o.apiEnv,error$:s,timeSynchronisation:this.timeSynchronisation});this.api=new H({apiTransport:i,refreshAuthToken:o.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:this.statContext.mobile??!1,error$:s}),this.logger=new G({api:this.api,error$:s,userSalt:o.userSalt});const{isEmbed:a,host:u}=Y();this.isEmbed=a,this.embedParent=u,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){const o=new r.Subscription,s=(n,h)=>o.add(n.subscribe(h));s(e.events.willStart$,()=>{this.logActionPlay({position:e.info.position$.getValue()})}),s(e.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:e.info.position$.getValue()})}),s(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next(exports.SeekAction.UNKNOWN)}),s(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),s(e.events.willResume$,()=>{this.logPlay()}),s(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),s(te(e),n=>{const h=e.info.isLive$.getValue(),p={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};h?this.logWatchCoverageLive(p):this.logWatchCoverageRecord(p)});let i;s(e.info.isStalled$,n=>{n?i=r.now():(r.isNonNullable(i)&&this.logEmptyBuffer({duration:r.now()-i}),i=void 0)});let a=!1;o.add(e.events.fatalError$.pipe(r.once()).subscribe(()=>a=!0)),s(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){const h=r.isNonNullable(i)?r.now()-i:void 0;this.logCloseAtEmptyBuffer({duration:h??0}),i=void 0}else a||this.logActionStop()}),s(e.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),s(e.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let u,f,l=!1;s(e.events.firstBytes$,n=>{u=r.now(),this.logFirstBytes({time:n})}),s(e.events.willStart$,()=>f=r.now()),s(e.info.currentBuffer$,n=>{!l&&n&&n.end-n.start>0&&r.isNonNullable(u)&&(this.logPlayerReady({duration:r.now()-u}),l=!0)}),s(e.events.firstFrame$,()=>{r.isNonNullable(u)&&!l&&(this.logPlayerReady({duration:r.now()-u}),l=!0),r.isNonNullable(f)&&this.logFirstFrame({time:r.now()-f})}),s(e.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),s(r.combine({muted:e.info.muted$,volume:e.info.volume$}),({muted:n,volume:h})=>this.updateContext({audible:!n&&h>0})),s(e.info.currentQuality$,n=>this.updateContext({quality:X(n)})),s(e.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),s(e.info.currentFormat$,n=>this.updateContext({contentType:J(n)}));let d;return s(e.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),s(e.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),s(e.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:$(n)}),this.updateContext({connectionType:$(n)})}),s(e.info.httpConnectionReused$,n=>{r.isNullable(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),s(e.info.surface$,n=>this.updateContext({mode:T(n)})),s(r.combine({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:n,available:h})=>{const p=h.find(({id:g})=>g===n);this.updateContext({subtitles:p?.language})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.subscription.add(o),o}attachToUi(e){this.uiEvents=e;const o=new r.Subscription;return this.player&&(o.add(e.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),o.add(e.actionSeek$.subscribe(this.seekAction$)),o.add(e.inPiP$.subscribe(s=>{const i=s?S.PIP:T(this.player?.info.surface$.getValue());this.updateContext({mode:i})})),o.add(e.inFullscreen$.subscribe(s=>{const i=s?S.FULLSCREEN:T(this.player?.info.surface$.getValue());this.updateContext({mode:i})})),o.add(e.actionSetSubtitle$.subscribe(s=>{this.updateContext({subtitles:s})})),this.subscription.add(o)),o}attachToAds(e){const o=new r.Subscription;return o.add(e.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(e.started$.subscribe(s=>this.logAdStarted(s))).add(e.paused$.subscribe(()=>this.logAdPaused())).add(e.resumed$.subscribe(()=>this.logAdResumed())).add(e.ended$.subscribe(()=>this.logAdEnded())).add(e.skipped$.subscribe(()=>this.logAdSkipped())).add(e.clicked$.subscribe(()=>this.logAdClicked())),this.subscription.add(o),o}authorize(e){return this.api.authorize(e)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=L()}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}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}`})}logWatchCoverageLive(e){const o=e.start+this.timeSynchronisation.getOffset(),s=e.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${o}-${s}`})}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"})}subscribe(){this.subscription.add(r.fromEvent(window,"beforeunload").subscribe(()=>this.logger.flush(!0)));const e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(r.merge(r.fromEvent(e,"change"),r.observableFrom(["init"])).subscribe(()=>this.updateContext({network:Z(e.effectiveType)})))}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))})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(e){const o=this.createLogItem(e);this.logger.log(o)}createLogItem({operation:e,param:o,time:s}){const i=this.timeSynchronisation.now(),a=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,u=this.statContext.firstConnectionReused,f={vsid:this.vsid,vid:this.statContext.movieId,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?_.MANUAL:void 0,param:o,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:a,connection_reused:u===!0?m.YES:u===!1?m.NO:void 0,cached_data:this.statContext.cached===!0?m.YES:this.statContext.cached===!1?m.NO:void 0,live:this.statContext.liveEdge?m.YES:void 0,muted:this.statContext.audible===!1?m.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:m.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:e,type:1,time:s,network:this.statContext.network,timestamp:i,custom:f}}}exports.OneStat=se;exports.VERSION=P;
|
|
6
|
+
"use strict";var r=require("@vkontakte/videoplayer-shared/esnext.cjs.js"),C=require("lodash/debounce.js"),c=require("@vkontakte/videoplayer-core/esnext.cjs.js");function V(){const t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),e=new Array(36);let s=0,o,i;for(i=0;i<36;i++)i===8||i===13||i===18||i===23?e[i]="-":i===14?e[i]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),o=s&15,s=s>>4,e[i]=t[i===19?o&3|8:o]);return e.join("")}exports.ApiEnv=void 0;(function(t){t.PROD="prod",t.VK_ALIAS="vk_alias",t.VIDEOTEST="videotest",t.TEST="test",t.AUTO="auto"})(exports.ApiEnv||(exports.ApiEnv={}));exports.Quality=void 0;(function(t){t.Q144P="mobile",t.Q240P="lowest",t.Q360P="low",t.Q480P="medium",t.Q720P="high",t.Q1080P="fullhd",t.Q1440P="quadhd",t.Q2160P="ultrahd",t.UNKNOWN="unknown"})(exports.Quality||(exports.Quality={}));exports.ContentType=void 0;(function(t){t.MP4="mp4",t.DASH="dash",t.DASH_SEP="dash_sep",t.ONDEMAND_DASH="ondemand_dash",t.HLS="hls",t.ONDEMAND_HLS="ondemand_hls",t.WEBM="webm",t.AV1="av1",t.ONDEMAND_DASH_LIVE="ondemand_dash_live",t.ONDEMAND_HLS_LIVE="ondemand_hls_live",t.WEBRTC="webrtc",t.UNKNOWN="unknown",t.RTMP="rtmp"})(exports.ContentType||(exports.ContentType={}));var _;(function(t){t.AUTO="auto",t.MANUAL=""})(_||(_={}));exports.ConnectionType=void 0;(function(t){t.HTTP1="http1",t.HTTP2="http2",t.HTTP3="http3"})(exports.ConnectionType||(exports.ConnectionType={}));var b;(function(t){t[t.YES=1]="YES",t[t.NO=0]="NO"})(b||(b={}));var E;(function(t){t.EXCELLENT="excellent",t.GOOD="good",t.POOR="poor"})(E||(E={}));var S;(function(t){t.PIP="pip",t.FULLSCREEN="fullscreen",t.EXTERNAL="external",t.PREFETCH="prefetch"})(S||(S={}));exports.SeekAction=void 0;(function(t){t.SLIDER="slider",t.DOUBLE_TAP="double_tap",t.TIME_CODE="time_code",t.EPISODE="episode",t.REWIND="rewind",t.LIVE="live",t.UNKNOWN="unknown"})(exports.SeekAction||(exports.SeekAction={}));const P="1.0.37",B="CIOPGQJGDIHBABABA",L={[exports.ApiEnv.PROD]:"https://api.ok.ru",[exports.ApiEnv.VK_ALIAS]:"https://api.mycdn.me",[exports.ApiEnv.VIDEOTEST]:"https://videotestapi.ok.ru/api",[exports.ApiEnv.TEST]:"https://apitest.ok.ru",[exports.ApiEnv.AUTO]:""},U="_one-stat_",N=`${U}uuid`,q={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var m;(function(t){t[t.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",t[t.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",t[t.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",t[t.AUTH_LOGIN=401]="AUTH_LOGIN"})(m||(m={}));class H{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new r.ValueSubject(!1);backoffTimeoutId;constructor(e){this.params=e;const s=r.safeStorage.get(N);s?this.uuid=String(s):(this.uuid=V(),r.safeStorage.set(N,this.uuid))}async authorize(e){return this.authToken=e??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(e){const s="log.externalLog",o=this.createLogParams(e),i=this.sessionKey;if(!i)return;this.params.apiTransport.sendBeacon(s,o,i)||this.logRequest(e)}async logRequest(e){const s="log.externalLog",o=this.createLogParams(e),i=this.sessionKey??await this._authorizeWithBackoff();if(!i)return;const a=async(u,f=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(s,o,i)}catch(l){if(!l||!("error_code"in l)){this.params.error$.next({id:"logRequestUnknown",category:r.ErrorCategory.NETWORK,message:`Unknown ${s} error`,thrown:l});return}const d=l?.error_code;switch(d){case m.PARAM_SESSION_EXPIRED:case m.PARAM_SESSION_KEY:case m.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(u,f-1):void 0;case m.AUTH_LOGIN:return this.authorized$.next(!1),this.authToken=await this.refreshAuthToken(),this.sessionKey=await this._authorizeWithBackoff(),f>0?a(u,f-1):void 0;default:{this.params.error$.next({id:`LogRequest#${d}`,category:r.ErrorCategory.EXTERNAL_API,message:`${s} error`,data:l});return}}}};return a(e)}destroy(){window.clearTimeout(this.backoffTimeoutId),this.backoffTimeoutId=0}async refreshAuthToken(){if(this.params.refreshAuthToken)return this.refreshAuthTokenPromise||(this.refreshAuthTokenPromise=this.params.refreshAuthToken().finally(()=>{this.refreshAuthTokenPromise=void 0})),this.refreshAuthTokenPromise}createLogParams(e){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${P}`,platform:this.params.mobile?"M_WEB":"WEB",items:e})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const e=r.getExponentialDelay(this.consequentAuthErrors,q);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(o=>this.params.error$.next({id:"AuthorizeBackoff",category:r.ErrorCategory.NETWORK,message:"Otherwise unhandled error in authorization",thrown:o})).finally(()=>this.backoffTimeoutId=0)},e))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const e="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:P.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(e,s).then(o=>((!o||!o.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:r.ErrorCategory.EXTERNAL_API,message:"No session key",data:o}),this.sessionKey=o?.session_key??void 0,this.sessionKey)).catch(async o=>{this.sessionKey=void 0;const i=o?.error_code;switch(i){case m.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}i?this.params.error$.next({id:`Authorize#${i}`,category:r.ErrorCategory.EXTERNAL_API,message:"authorize error",data:o}):this.params.error$.next({id:"AuthorizeUnknown",category:r.ErrorCategory.NETWORK,message:"authorize error",thrown:o})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class O{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(e,s,o){e in this.listeners||(this.listeners[e]=[]),this.listeners[e].push({callback:s,options:o})}removeEventListener(e,s){if(!(e in this.listeners))return;const o=this.listeners[e];for(let i=0,a=o.length;i<a;i++)if(o[i].callback===s){o.splice(i,1);return}}dispatchEvent(e){if(!(e.type in this.listeners))return;const o=this.listeners[e.type].slice();for(let i=0,a=o.length;i<a;i++){const u=o[i];try{u.callback.call(this,e)}catch(f){Promise.resolve().then(()=>{throw f})}u.options&&u.options.once&&this.removeEventListener(e.type,u.callback)}return!e.defaultPrevented}}class I extends O{constructor(){super(),this.listeners||O.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(e){e.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,e)),super.dispatchEvent(e)}}class M{constructor(){Object.defineProperty(this,"signal",{value:new I,writable:!0,configurable:!0})}abort(e){let s;try{s=new Event("abort")}catch{typeof document<"u"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let o=e;if(o===void 0)if(typeof document>"u")o=new Error("This operation was aborted"),o.name="AbortError";else try{o=new DOMException("signal is aborted without reason")}catch{o=new Error("This operation was aborted"),o.name="AbortError"}this.signal.reason=o,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(M.prototype[Symbol.toStringTag]="AbortController",I.prototype[Symbol.toStringTag]="AbortSignal");function F(t){return t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof t.Request=="function"&&!t.Request.prototype.hasOwnProperty("signal")||!t.AbortController}function Q(t){typeof t=="function"&&(t={fetch:t});const{fetch:e,Request:s=e.Request,AbortController:o,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:i=!1}=t;if(!F({fetch:e,Request:s,AbortController:o,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:i}))return{fetch:e,Request:a};let a=s;(a&&!a.prototype.hasOwnProperty("signal")||i)&&(a=function(d,n){let h;n&&n.signal&&(h=n.signal,delete n.signal);const p=new s(d,n);return h&&Object.defineProperty(p,"signal",{writable:!1,enumerable:!1,configurable:!0,value:h}),p},a.prototype=s.prototype);const u=e;return{fetch:(l,d)=>{const n=a&&a.prototype.isPrototypeOf(l)?l.signal:d?d.signal:void 0;if(n){let h;try{h=new DOMException("Aborted","AbortError")}catch{h=new Error("Aborted"),h.name="AbortError"}if(n.aborted)return Promise.reject(h);const p=new Promise((g,y)=>{n.addEventListener("abort",()=>y(h),{once:!0})});return d&&d.signal&&delete d.signal,Promise.race([p,u(l,d)])}return u(l,d)},Request:a}}const v=F({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),D=v?Q({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,R=v?D.fetch:window.fetch;v?D.Request:window.Request;class W{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(e){this.params=e,this.apiKey=e.apiKey,this.apiEnv=e.apiEnv,this.apiBaseUrl=e.apiBaseUrl,this.timeSynchronisation=e.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==exports.ApiEnv.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const e=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),i=(await(await R(e,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!i)throw new Error("Wrong DNS response");return i}catch(e){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:r.ErrorCategory.NETWORK,message:"Unhandled resolve api base url error",thrown:e}),L[exports.ApiEnv.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(e,s,o){if(!window.Blob||!window.navigator.sendBeacon)return!1;const i=this._prepareQueryParams({method:e,queryParams:s,sessionKey:o}),a=new window.Blob([i.toString()],{type:"application/x-www-form-urlencoded"});try{return window.navigator.sendBeacon(`${this.apiBaseUrl}/fb.do`,a)}catch(u){this.params.error$.next({id:"OneStat:ApiTransport:sendBeacon",category:r.ErrorCategory.NETWORK,message:"Unhandled beacon error",thrown:u,data:{method:e,params:s}})}return!1}async sendRequest(e,s,o){const i=r.now(),a=u=>{if(u instanceof TypeError&&["Failed to fetch","NetworkError when attempting to fetch resource."].includes(u.message)){this.params.error$.next({id:"Network",category:r.ErrorCategory.NETWORK,message:"Request failed",thrown:u});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:r.ErrorCategory.NETWORK,message:"Unhandled request error",thrown:u,data:{method:e,params:s,sessionKey:o,time:r.now()-i}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),R(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:e,queryParams:s,sessionKey:o})}).then(u=>{const f=Number(u.headers.get("content-length"))===0,l=new Date(u.headers.get("date")??"").getTime(),d=r.now()-i;if(isFinite(l)&&this.timeSynchronisation.addServerTime(l,d),!f)return u.json().then(n=>Object.prototype.hasOwnProperty.call(n,"error_msg")?Promise.reject(n):n,a)},a)}_prepareQueryParams(e){const s=new URLSearchParams({format:"JSON",method:e.method,application_key:this.apiKey});return e.sessionKey!==void 0&&s.append("session_key",e.sessionKey),Object.entries(e.queryParams).forEach(([o,i])=>s.append(o,typeof i=="string"?i:JSON.stringify(i))),s}}const k=5e3,K=1e4,z=6e4,A="onestat_events",j=36*60*60*1e3,w=t=>t.timestamp+j>=r.now();class G{api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;flushMaxWait=r.safeStorage.isPersistent()?z:0;constructor(e){this.api=e.api,this.error$=e.error$,this.userSalt=e.userSalt,this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=e=>{const{operation:s,custom:{param:o}}=e;return["action_stop","close_at_empty_buffer"].includes(s)||s==="watch_coverage_record"&&o==="0-0"};safeFlush(){try{this.flush()}catch(e){this.error$.next({id:"LoggerError",category:r.ErrorCategory.WTF,message:String(e)??"Unknown logger error",thrown:e})}}firstFlush=C(()=>this.safeFlush(),k,{maxWait:k});debouncedFlush=C(()=>this.safeFlush(),K,{maxWait:this.flushMaxWait});readFromStorage(){const e=r.safeStorage.get(A);try{return e?JSON.parse(e):{}}catch{}return{}}addToStorage(e){if(!this.userSalt){this.unsaltedStorage.push(e);return}const s=this.readFromStorage(),i=(s[this.userSalt]??[]).filter(w);r.safeStorage.set(A,JSON.stringify({...s,[this.userSalt]:[...i,e]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(w):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const e=this.readFromStorage();delete e[this.userSalt],r.safeStorage.set(A,JSON.stringify(e))}housekeepStorage(){const e=this.readFromStorage();for(const[s,o]of Object.entries(e)){const i=o.filter(w);i.length?e[s]=i:delete e[s]}r.safeStorage.set(A,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(e=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(e?this.api.logBeacon(s):this.api.logRequest(s),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()}}const Y=()=>{let t,e;try{t=window.self!==window.top}catch(o){o instanceof DOMException&&o.name==="SecurityError"?t=!0:(t=!1,console.error(o))}try{window.location.ancestorOrigins&&(e=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(o){console.error(o)}try{!e&&document.referrer&&(e=document.referrer)}catch(o){console.error(o)}const s=e?new URL(e).hostname:void 0;return{isEmbed:t,host:s}},X=t=>t&&{[c.VideoQuality.INVARIANT]:exports.Quality.UNKNOWN,[c.VideoQuality.Q_144P]:exports.Quality.Q144P,[c.VideoQuality.Q_240P]:exports.Quality.Q240P,[c.VideoQuality.Q_360P]:exports.Quality.Q360P,[c.VideoQuality.Q_480P]:exports.Quality.Q480P,[c.VideoQuality.Q_720P]:exports.Quality.Q720P,[c.VideoQuality.Q_1080P]:exports.Quality.Q1080P,[c.VideoQuality.Q_1440P]:exports.Quality.Q1440P,[c.VideoQuality.Q_2160P]:exports.Quality.Q2160P,[c.VideoQuality.Q_4320P]:exports.Quality.UNKNOWN}[t],$=t=>t&&{[c.HttpConnectionType.HTTP1]:exports.ConnectionType.HTTP1,[c.HttpConnectionType.HTTP2]:exports.ConnectionType.HTTP2,[c.HttpConnectionType.QUIC]:exports.ConnectionType.HTTP3}[t],J=t=>{if(t!==void 0)switch(t){case c.VideoFormat.MPEG:return exports.ContentType.MP4;case c.VideoFormat.DASH:case c.VideoFormat.DASH_LIVE:return exports.ContentType.DASH;case c.VideoFormat.DASH_SEP:return exports.ContentType.DASH_SEP;case c.VideoFormat.DASH_ONDEMAND:return exports.ContentType.ONDEMAND_DASH;case c.VideoFormat.DASH_WEBM:case c.VideoFormat.DASH_LIVE_WEBM:return exports.ContentType.WEBM;case c.VideoFormat.DASH_WEBM_AV1:return exports.ContentType.AV1;case c.VideoFormat.DASH_LIVE_CMAF:return exports.ContentType.ONDEMAND_DASH_LIVE;case c.VideoFormat.HLS:case c.VideoFormat.HLS_LIVE:return exports.ContentType.HLS;case c.VideoFormat.HLS_ONDEMAND:return exports.ContentType.ONDEMAND_HLS;case c.VideoFormat.HLS_LIVE_CMAF:return exports.ContentType.ONDEMAND_HLS_LIVE;case c.VideoFormat.WEB_RTC_LIVE:return exports.ContentType.WEBRTC;default:return r.assertNever(t)}},T=t=>{if(t!==void 0)switch(t){case c.Surface.NONE:case c.Surface.INLINE:return;case c.Surface.FULLSCREEN:return S.FULLSCREEN;case c.Surface.SECOND_SCREEN:return S.EXTERNAL;case c.Surface.PIP:return S.PIP;default:return r.assertNever(t)}},Z=t=>{switch(t){case"slow-2g":return E.POOR;case"2g":return E.POOR;case"3g":return E.GOOD;case"4g":return E.EXCELLENT}};class ee{offset=void 0;constructor(e){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,s){const o=Date.now(),i=e-o-s/2;if(Math.abs(i)<1e3){this.offset=0;return}this.offset===void 0?this.offset=Math.round(i):this.offset=Math.round(.2*i+(1-.2)*this.offset)}}const x=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),te=t=>new r.Observable(e=>{const s=new r.Subscription,o=r.merge(r.fromEvent(window,"beforeunload"),t.events.willDestruct$),i=new r.ValueSubject(void 0);let a;s.add(t.info.isLive$.pipe(r.filterChanged()).subscribe(g=>{a&&(a.unsubscribe(),i.next(void 0)),g?a=t.info.liveTime$.pipe(r.map(y=>y&&y/1e3)).subscribe(i):a=t.info.position$.subscribe(i),s.add(a)}));const{playing$:u,paused$:f}=t.events,l=t.events.willSeek$.pipe(r.filter(()=>t.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),d=t.events.seeked$.pipe(r.filter(()=>t.info.playbackState$.getValue()===c.PlaybackState.PLAYING)),n=r.merge(u,d),h=r.merge(f,l,o,t.events.looped$);let p;return s.add(n.subscribe(()=>p=i.getValue())),s.add(h.subscribe(()=>{const g=i.getValue();r.isNullable(p)||p===g||r.isNullable(g)||(e.next({from:p,to:g}),p=void 0)})),s});class se{api;logger;config;subscription=new r.Subscription;beforeunloadSubscription;timeSynchronisation=new ee;experimental;statContext;vsid=x();isEmbed;embedParent;uiEvents;player;seekAction$=new r.ValueSubject(exports.SeekAction.UNKNOWN);constructor(e,s){this.statContext=e,this.config={...s.config??{},requestRetryCount:1};const o=new r.Subject;this.experimental={error$:o};const i=new W({apiKey:B,apiBaseUrl:L[s.apiEnv],apiEnv:s.apiEnv,error$:o,timeSynchronisation:this.timeSynchronisation});this.api=new H({apiTransport:i,refreshAuthToken:s.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:this.statContext.mobile??!1,error$:o}),this.logger=new G({api:this.api,error$:o,userSalt:s.userSalt});const{isEmbed:a,host:u}=Y();this.isEmbed=a,this.embedParent=u,this.subscribe()}updateContext(e){this.statContext={...this.statContext,...e}}attachTo(e){const s=new r.Subscription,o=(n,h)=>s.add(n.subscribe(h));o(e.events.willStart$,()=>{this.logActionPlay({position:e.info.position$.getValue()})}),o(e.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:e.info.position$.getValue()})}),o(e.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:e.info.position$.getValue()}),this.seekAction$.next(exports.SeekAction.UNKNOWN)}),o(e.events.paused$,()=>{this.logPause({position:e.info.position$.getValue()})}),o(e.events.willResume$,()=>{this.logPlay()}),o(e.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),o(te(e),n=>{const h=e.info.isLive$.getValue(),p={start:parseFloat(n.from.toFixed(3)),end:parseFloat(n.to.toFixed(3))};h?this.logWatchCoverageLive(p):this.logWatchCoverageRecord(p)});let i;o(e.info.isStalled$,n=>{n?i=r.now():(r.isNonNullable(i)&&this.logEmptyBuffer({duration:r.now()-i}),i=void 0)});let a=!1;s.add(e.events.fatalError$.pipe(r.once()).subscribe(()=>a=!0)),o(e.events.willStop$,()=>{if(e.info.isStalled$.getValue()){const h=r.isNonNullable(i)?r.now()-i:void 0;this.logCloseAtEmptyBuffer({duration:h??0}),i=void 0}else a||this.logActionStop()}),o(e.events.managedError$,({id:n})=>{this.logError({fatal:!1,errorType:n})}),o(e.events.fatalError$,({id:n})=>{this.logError({fatal:!0,errorType:n})});let u,f,l=!1;o(e.events.firstBytes$,n=>{u=r.now(),this.logFirstBytes({time:n})}),o(e.events.willStart$,()=>f=r.now()),o(e.info.currentBuffer$,n=>{!l&&n&&n.end-n.start>0&&r.isNonNullable(u)&&(this.logPlayerReady({duration:r.now()-u}),l=!0)}),o(e.events.firstFrame$,()=>{r.isNonNullable(u)&&!l&&(this.logPlayerReady({duration:r.now()-u}),l=!0),r.isNonNullable(f)&&this.logFirstFrame({time:r.now()-f})}),o(e.info.atLiveEdge$,n=>this.updateContext({liveEdge:n})),o(r.combine({muted:e.info.muted$,volume:e.info.volume$}),({muted:n,volume:h})=>this.updateContext({audible:!n&&h>0})),o(e.info.currentQuality$,n=>this.updateContext({quality:X(n)})),o(e.info.isAutoQualityEnabled$,n=>this.updateContext({autoQuality:n})),o(e.info.currentFormat$,n=>this.updateContext({contentType:J(n)}));let d;return o(e.info.hostname$,n=>{this.updateContext({cdnHostname:n,failover:d!==void 0&&d!==n}),d=n}),o(e.info.throughputEstimation$,n=>this.updateContext({downloadSpeed:n})),o(e.info.httpConnectionType$,n=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:$(n)}),this.updateContext({connectionType:$(n)})}),o(e.info.httpConnectionReused$,n=>{r.isNullable(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:n}),this.updateContext({connectionReused:n})}),o(e.info.surface$,n=>this.updateContext({mode:T(n)})),o(r.combine({current:e.info.currentTextTrack$,available:e.info.availableTextTracks$}),({current:n,available:h})=>{const p=h.find(({id:g})=>g===n);this.updateContext({subtitles:p?.language})}),this.player=e,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToUi(e){this.uiEvents=e;const s=new r.Subscription;return this.player&&(s.add(e.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),s.add(e.actionSeek$.subscribe(this.seekAction$)),s.add(e.inPiP$.subscribe(o=>{const i=o?S.PIP:T(this.player?.info.surface$.getValue());this.updateContext({mode:i})})),s.add(e.inFullscreen$.subscribe(o=>{const i=o?S.FULLSCREEN:T(this.player?.info.surface$.getValue());this.updateContext({mode:i})})),s.add(e.actionSetSubtitle$.subscribe(o=>{this.updateContext({subtitles:o})})),this.resubscribeBeforeunload(),this.subscription.add(s)),s}attachToAds(e){const s=new r.Subscription;return s.add(e.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(e.started$.subscribe(o=>this.logAdStarted(o))).add(e.paused$.subscribe(()=>this.logAdPaused())).add(e.resumed$.subscribe(()=>this.logAdResumed())).add(e.ended$.subscribe(()=>this.logAdEnded())).add(e.skipped$.subscribe(()=>this.logAdSkipped())).add(e.clicked$.subscribe(()=>this.logAdClicked())),this.resubscribeBeforeunload(),this.subscription.add(s),s}authorize(e){return this.api.authorize(e)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=x()}setFieldBlacklist(){}logInited(){}logReady(e){this.log({operation:"player_ready",param:String(e.time)})}logStarted(...e){this.logActionPlay(...e)}logPlay(){this.log({operation:"play_toggle"})}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}`})}logWatchCoverageLive(e){const s=e.start+this.timeSynchronisation.getOffset(),o=e.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${s}-${o}`})}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"})}subscribe(){this.resubscribeBeforeunload();const e=window.navigator.connection;e&&"onchange"in e&&"effectiveType"in e&&this.subscription.add(r.merge(r.fromEvent(e,"change"),r.observableFrom(["init"])).subscribe(()=>this.updateContext({network:Z(e.effectiveType)})))}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=r.fromEvent(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),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))})}logCloseAtEmptyBuffer(e){this.log({operation:"close_at_empty_buffer",param:String(Math.round(e.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(e){const s=this.createLogItem(e);this.logger.log(s)}createLogItem({operation:e,param:s,time:o}){const i=this.timeSynchronisation.now(),a=e==="empty_buffer"||e==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,u=this.statContext.firstConnectionReused,f={vsid:this.vsid,vid:this.statContext.movieId,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?_.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:a,connection_reused:u===!0?b.YES:u===!1?b.NO:void 0,cached_data:this.statContext.cached===!0?b.YES:this.statContext.cached===!1?b.NO:void 0,live:this.statContext.liveEdge?b.YES:void 0,muted:this.statContext.audible===!1?b.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:b.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:e,type:1,time:o,network:this.statContext.network,timestamp:i,custom:f}}}exports.OneStat=se;exports.VERSION=P;
|
package/esnext.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @vkontakte/videoplayer-statistics v1.0.
|
|
3
|
-
* Mon,
|
|
4
|
-
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-
|
|
2
|
+
* @vkontakte/videoplayer-statistics v1.0.37
|
|
3
|
+
* Mon, 10 Jul 2023 15:30:39 GMT
|
|
4
|
+
* https://st.mycdn.me/static/vkontakte-videoplayer/1-0-37/doc/
|
|
5
5
|
*/
|
|
6
|
-
import{ValueSubject as q,safeStorage as P,getExponentialDelay as ot,ErrorCategory as b,now as m,assertNever as Z,Observable as rt,Subscription as N,merge as k,fromEvent as U,filterChanged as nt,map as at,filter as M,isNullable as B,Subject as ct,once as ut,combine as W,observableFrom as ht,isNonNullable as O}from"@vkontakte/videoplayer-shared/esnext.esm.js";import V from"lodash/debounce.js";import{Surface as R,VideoQuality as S,HttpConnectionType as I,VideoFormat as f,PlaybackState as K}from"@vkontakte/videoplayer-core/esnext.esm.js";function lt(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let i=0,s,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(i<=2&&(i=33554432+Math.random()*16777216|0),s=i&15,i=i>>4,t[o]=e[o===19?s&3|8:s]);return t.join("")}var _;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(_||(_={}));var p;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(p||(p={}));var g;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(g||(g={}));var x;(function(e){e.AUTO="auto",e.MANUAL=""})(x||(x={}));var $;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})($||($={}));var A;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(A||(A={}));var T;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(T||(T={}));var y;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(y||(y={}));var C;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(C||(C={}));const z="1.0.35",dt="CIOPGQJGDIHBABABA",tt={[_.PROD]:"https://api.ok.ru",[_.VK_ALIAS]:"https://api.mycdn.me",[_.VIDEOTEST]:"https://videotestapi.ok.ru/api",[_.TEST]:"https://apitest.ok.ru",[_.AUTO]:""},ft="_one-stat_",Q=`${ft}uuid`,pt={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var w;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(w||(w={}));class gt{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new q(!1);backoffTimeoutId;constructor(t){this.params=t;const i=P.get(Q);i?this.uuid=String(i):(this.uuid=lt(),P.set(Q,this.uuid))}async authorize(t){return this.authToken=t??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(i,s,o)||this.logRequest(t)}async logRequest(t){const i="log.externalLog",s=this.createLogParams(t),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const n=async(a,l=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(i,s,o)}catch(c){if(!c||!("error_code"in c)){this.params.error$.next({id:"logRequestUnknown",category:b.NETWORK,message:`Unknown ${i} error`,thrown:c});return}const h=c?.error_code;switch(h){case w.PARAM_SESSION_EXPIRED:case w.PARAM_SESSION_KEY:case w.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;case w.AUTH_LOGIN: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#${h}`,category:b.EXTERNAL_API,message:`${i} error`,data:c});return}}}};return n(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${z}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=ot(this.consequentAuthErrors,pt);return new Promise(i=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(i).catch(s=>this.params.error$.next({id:"AuthorizeBackoff",category:b.NETWORK,message:"Otherwise unhandled error in authorization",thrown:s})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",i={session_data:{version:2,device_id:this.uuid,client_version:z.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(t,i).then(s=>((!s||!s.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:b.EXTERNAL_API,message:"No session key",data:s}),this.sessionKey=s?.session_key??void 0,this.sessionKey)).catch(async s=>{this.sessionKey=void 0;const o=s?.error_code;switch(o){case w.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:b.EXTERNAL_API,message:"authorize error",data:s}):this.params.error$.next({id:"AuthorizeUnknown",category:b.NETWORK,message:"authorize error",thrown:s})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class j{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,i,s){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:i,options:s})}removeEventListener(t,i){if(!(t in this.listeners))return;const s=this.listeners[t];for(let o=0,n=s.length;o<n;o++)if(s[o].callback===i){s.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const s=this.listeners[t.type].slice();for(let o=0,n=s.length;o<n;o++){const a=s[o];try{a.callback.call(this,t)}catch(l){Promise.resolve().then(()=>{throw l})}a.options&&a.options.once&&this.removeEventListener(t.type,a.callback)}return!t.defaultPrevented}}class et extends j{constructor(){super(),this.listeners||j.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class mt{constructor(){Object.defineProperty(this,"signal",{value:new et,writable:!0,configurable:!0})}abort(t){let i;try{i=new Event("abort")}catch{typeof document<"u"?document.createEvent?(i=document.createEvent("Event"),i.initEvent("abort",!1,!1)):(i=document.createEventObject(),i.type="abort"):i={type:"abort",bubbles:!1,cancelable:!1}}let s=t;if(s===void 0)if(typeof document>"u")s=new Error("This operation was aborted"),s.name="AbortError";else try{s=new DOMException("signal is aborted without reason")}catch{s=new Error("This operation was aborted"),s.name="AbortError"}this.signal.reason=s,this.signal.dispatchEvent(i)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(mt.prototype[Symbol.toStringTag]="AbortController",et.prototype[Symbol.toStringTag]="AbortSignal");function st(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function bt(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:i=t.Request,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!st({fetch:t,Request:i,AbortController:s,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:n};let n=i;(n&&!n.prototype.hasOwnProperty("signal")||o)&&(n=function(h,r){let u;r&&r.signal&&(u=r.signal,delete r.signal);const d=new i(h,r);return u&&Object.defineProperty(d,"signal",{writable:!1,enumerable:!1,configurable:!0,value:u}),d},n.prototype=i.prototype);const a=t;return{fetch:(c,h)=>{const r=n&&n.prototype.isPrototypeOf(c)?c.signal:h?h.signal:void 0;if(r){let u;try{u=new DOMException("Aborted","AbortError")}catch{u=new Error("Aborted"),u.name="AbortError"}if(r.aborted)return Promise.reject(u);const d=new Promise((E,v)=>{r.addEventListener("abort",()=>v(u),{once:!0})});return h&&h.signal&&delete h.signal,Promise.race([d,a(c,h)])}return a(c,h)},Request:n}}const H=st({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),it=H?bt({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,G=H?it.fetch:window.fetch;H?it.Request:window.Request;class St{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.apiEnv,this.apiBaseUrl=t.apiBaseUrl,this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==_.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const t=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await G(t,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(t){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:b.NETWORK,message:"Unhandled resolve api base url error",thrown:t}),tt[_.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,i,s){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:i,sessionKey:s}),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:b.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:t,params:i}})}return!1}async sendRequest(t,i,s){const o=m(),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:b.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:b.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:i,sessionKey:s,time:m()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),G(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:i,sessionKey:s})}).then(a=>{const l=Number(a.headers.get("content-length"))===0,c=new Date(a.headers.get("date")??"").getTime(),h=m()-o;if(isFinite(c)&&this.timeSynchronisation.addServerTime(c,h),!l)return a.json().then(r=>Object.prototype.hasOwnProperty.call(r,"error_msg")?Promise.reject(r):r,n)},n)}_prepareQueryParams(t){const i=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&i.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([s,o])=>i.append(s,typeof o=="string"?o:JSON.stringify(o))),i}}const Y=5e3,Et=1e4,At=6e4,L="onestat_events",_t=36*60*60*1e3,D=e=>e.timestamp+_t>=m();class wt{api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;constructor(t){this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.subscription=this.api.authorized$.subscribe(i=>{i&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=t=>{const{operation:i,custom:{param:s}}=t;return["action_stop","close_at_empty_buffer"].includes(i)||i==="watch_coverage_record"&&s==="0-0"};safeFlush(){try{this.flush()}catch(t){this.error$.next({id:"LoggerError",category:b.WTF,message:String(t)??"Unknown logger error",thrown:t})}}firstFlush=V(()=>this.safeFlush(),Y,{maxWait:Y});debouncedFlush=V(()=>this.safeFlush(),Et,{maxWait:At});readFromStorage(){const t=P.get(L);try{return t?JSON.parse(t):{}}catch{}return{}}addToStorage(t){if(!this.userSalt){this.unsaltedStorage.push(t);return}const i=this.readFromStorage(),o=(i[this.userSalt]??[]).filter(D);P.set(L,JSON.stringify({...i,[this.userSalt]:[...o,t]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(D):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],P.set(L,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[i,s]of Object.entries(t)){const o=s.filter(D);o.length?t[i]=o:delete t[i]}P.set(L,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const i=this.getFromStorage();i.length!==0&&(this.api.authorized$.getValue()?(t?this.api.logBeacon(i):this.api.logRequest(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()}}const yt=()=>{let e,t;try{e=window.self!==window.top}catch(s){s instanceof DOMException&&s.name==="SecurityError"?e=!0:(e=!1,console.error(s))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(s){console.error(s)}try{!t&&document.referrer&&(t=document.referrer)}catch(s){console.error(s)}const i=t?new URL(t).hostname:void 0;return{isEmbed:e,host:i}},Pt=e=>e&&{[S.INVARIANT]:p.UNKNOWN,[S.Q_144P]:p.Q144P,[S.Q_240P]:p.Q240P,[S.Q_360P]:p.Q360P,[S.Q_480P]:p.Q480P,[S.Q_720P]:p.Q720P,[S.Q_1080P]:p.Q1080P,[S.Q_1440P]:p.Q1440P,[S.Q_2160P]:p.Q2160P,[S.Q_4320P]:p.UNKNOWN}[e],X=e=>e&&{[I.HTTP1]:$.HTTP1,[I.HTTP2]:$.HTTP2,[I.QUIC]:$.HTTP3}[e],Tt=e=>{if(e!==void 0)switch(e){case f.MPEG:return g.MP4;case f.DASH:case f.DASH_LIVE:return g.DASH;case f.DASH_SEP:return g.DASH_SEP;case f.DASH_ONDEMAND:return g.ONDEMAND_DASH;case f.DASH_WEBM:case f.DASH_WEBM_AV1:case f.DASH_LIVE_WEBM:return g.WEBM;case f.DASH_LIVE_CMAF:return g.ONDEMAND_DASH_LIVE;case f.HLS:case f.HLS_LIVE:return g.HLS;case f.HLS_ONDEMAND:return g.ONDEMAND_HLS;case f.HLS_LIVE_CMAF:return g.ONDEMAND_HLS_LIVE;case f.WEB_RTC_LIVE:return g.WEBRTC;default:return Z(e)}},F=e=>{if(e!==void 0)switch(e){case R.NONE:case R.INLINE:return;case R.FULLSCREEN:return y.FULLSCREEN;case R.SECOND_SCREEN:return y.EXTERNAL;case R.PIP:return y.PIP;default:return Z(e)}},vt=e=>{switch(e){case"slow-2g":return T.POOR;case"2g":return T.POOR;case"3g":return T.GOOD;case"4g":return T.EXCELLENT}};class Ot{offset=void 0;constructor(t){this.offset=t}getOffset(){return this.offset??0}setOffset(t){this.offset=t}now(){return Date.now()+(this.offset??0)}date(t=new Date){return t.setTime(t.getTime()+(this.offset??0)),t}addServerTime(t,i){const s=Date.now(),o=t-s-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)}}const J=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Rt=e=>new rt(t=>{const i=new N,s=k(U(window,"beforeunload"),e.events.willDestruct$),o=new q(void 0);let n;e.info.isLive$.pipe(nt()).subscribe(E=>{n&&(n.unsubscribe(),o.next(void 0)),E?n=e.info.liveTime$.pipe(at(v=>v&&v/1e3)).subscribe(o):n=e.info.position$.subscribe(o),i.add(n)});const{playing$:a,paused$:l}=e.events,c=e.events.willSeek$.pipe(M(()=>e.info.playbackState$.getValue()===K.PLAYING)),h=e.events.seeked$.pipe(M(()=>e.info.playbackState$.getValue()===K.PLAYING)),r=k(a,h),u=k(l,c,s,e.events.looped$);let d;return i.add(r.subscribe(()=>d=o.getValue())),i.add(u.subscribe(()=>{const E=o.getValue();B(d)||d===E||B(E)||(t.next({from:d,to:E}),d=void 0)})),i});class kt{api;logger;config;subscription=new N;timeSynchronisation=new Ot;experimental;statContext;vsid=J();isEmbed;embedParent;uiEvents;player;seekAction$=new q(C.UNKNOWN);constructor(t,i){this.statContext=t,this.config={...i.config??{},requestRetryCount:1};const s=new ct;this.experimental={error$:s};const o=new St({apiKey:dt,apiBaseUrl:tt[i.apiEnv],apiEnv:i.apiEnv,error$:s,timeSynchronisation:this.timeSynchronisation});this.api=new gt({apiTransport:o,refreshAuthToken:i.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:this.statContext.mobile??!1,error$:s}),this.logger=new wt({api:this.api,error$:s,userSalt:i.userSalt});const{isEmbed:n,host:a}=yt();this.isEmbed=n,this.embedParent=a,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const i=new N,s=(r,u)=>i.add(r.subscribe(u));s(t.events.willStart$,()=>{this.logActionPlay({position:t.info.position$.getValue()})}),s(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),s(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(C.UNKNOWN)}),s(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),s(t.events.willResume$,()=>{this.logPlay()}),s(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),s(Rt(t),r=>{const u=t.info.isLive$.getValue(),d={start:parseFloat(r.from.toFixed(3)),end:parseFloat(r.to.toFixed(3))};u?this.logWatchCoverageLive(d):this.logWatchCoverageRecord(d)});let o;s(t.info.isStalled$,r=>{r?o=m():(O(o)&&this.logEmptyBuffer({duration:m()-o}),o=void 0)});let n=!1;i.add(t.events.fatalError$.pipe(ut()).subscribe(()=>n=!0)),s(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const u=O(o)?m()-o:void 0;this.logCloseAtEmptyBuffer({duration:u??0}),o=void 0}else n||this.logActionStop()}),s(t.events.managedError$,({id:r})=>{this.logError({fatal:!1,errorType:r})}),s(t.events.fatalError$,({id:r})=>{this.logError({fatal:!0,errorType:r})});let a,l,c=!1;s(t.events.firstBytes$,r=>{a=m(),this.logFirstBytes({time:r})}),s(t.events.willStart$,()=>l=m()),s(t.info.currentBuffer$,r=>{!c&&r&&r.end-r.start>0&&O(a)&&(this.logPlayerReady({duration:m()-a}),c=!0)}),s(t.events.firstFrame$,()=>{O(a)&&!c&&(this.logPlayerReady({duration:m()-a}),c=!0),O(l)&&this.logFirstFrame({time:m()-l})}),s(t.info.atLiveEdge$,r=>this.updateContext({liveEdge:r})),s(W({muted:t.info.muted$,volume:t.info.volume$}),({muted:r,volume:u})=>this.updateContext({audible:!r&&u>0})),s(t.info.currentQuality$,r=>this.updateContext({quality:Pt(r)})),s(t.info.isAutoQualityEnabled$,r=>this.updateContext({autoQuality:r})),s(t.info.currentFormat$,r=>this.updateContext({contentType:Tt(r)}));let h;return s(t.info.hostname$,r=>{this.updateContext({cdnHostname:r,failover:h!==void 0&&h!==r}),h=r}),s(t.info.throughputEstimation$,r=>this.updateContext({downloadSpeed:r})),s(t.info.httpConnectionType$,r=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:X(r)}),this.updateContext({connectionType:X(r)})}),s(t.info.httpConnectionReused$,r=>{B(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:r}),this.updateContext({connectionReused:r})}),s(t.info.surface$,r=>this.updateContext({mode:F(r)})),s(W({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:r,available:u})=>{const d=u.find(({id:E})=>E===r);this.updateContext({subtitles:d?.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.subscription.add(i),i}attachToUi(t){this.uiEvents=t;const i=new N;return this.player&&(i.add(t.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),i.add(t.actionSeek$.subscribe(this.seekAction$)),i.add(t.inPiP$.subscribe(s=>{const o=s?y.PIP:F(this.player?.info.surface$.getValue());this.updateContext({mode:o})})),i.add(t.inFullscreen$.subscribe(s=>{const o=s?y.FULLSCREEN:F(this.player?.info.surface$.getValue());this.updateContext({mode:o})})),i.add(t.actionSetSubtitle$.subscribe(s=>{this.updateContext({subtitles:s})})),this.subscription.add(i)),i}attachToAds(t){const i=new N;return i.add(t.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(t.started$.subscribe(s=>this.logAdStarted(s))).add(t.paused$.subscribe(()=>this.logAdPaused())).add(t.resumed$.subscribe(()=>this.logAdResumed())).add(t.ended$.subscribe(()=>this.logAdEnded())).add(t.skipped$.subscribe(()=>this.logAdSkipped())).add(t.clicked$.subscribe(()=>this.logAdClicked())),this.subscription.add(i),i}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=J()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const i=t.start+this.timeSynchronisation.getOffset(),s=t.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${i}-${s}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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"})}subscribe(){this.subscription.add(U(window,"beforeunload").subscribe(()=>this.logger.flush(!0)));const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(k(U(t,"change"),ht(["init"])).subscribe(()=>this.updateContext({network:vt(t.effectiveType)})))}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){const i=this.createLogItem(t);this.logger.log(i)}createLogItem({operation:t,param:i,time:s}){const o=this.timeSynchronisation.now(),n=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,l={vsid:this.vsid,vid:this.statContext.movieId,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?x.AUTO:this.statContext.autoplay===!1?x.MANUAL:void 0,param:i,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:n,connection_reused:a===!0?A.YES:a===!1?A.NO:void 0,cached_data:this.statContext.cached===!0?A.YES:this.statContext.cached===!1?A.NO:void 0,live:this.statContext.liveEdge?A.YES:void 0,muted:this.statContext.audible===!1?A.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:A.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:t,type:1,time:s,network:this.statContext.network,timestamp:o,custom:l}}}export{_ as ApiEnv,$ as ConnectionType,g as ContentType,kt as OneStat,p as Quality,C as SeekAction,z as VERSION};
|
|
6
|
+
import{ValueSubject as M,safeStorage as w,getExponentialDelay as ot,ErrorCategory as m,now as b,assertNever as Z,Observable as rt,Subscription as N,merge as L,fromEvent as F,filterChanged as nt,map as at,filter as H,isNullable as U,Subject as ut,once as ct,combine as W,observableFrom as ht,isNonNullable as O}from"@vkontakte/videoplayer-shared/esnext.esm.js";import V from"lodash/debounce.js";import{Surface as R,VideoQuality as S,HttpConnectionType as I,VideoFormat as f,PlaybackState as K}from"@vkontakte/videoplayer-core/esnext.esm.js";function lt(){const e="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split(""),t=new Array(36);let s=0,i,o;for(o=0;o<36;o++)o===8||o===13||o===18||o===23?t[o]="-":o===14?t[o]="4":(s<=2&&(s=33554432+Math.random()*16777216|0),i=s&15,s=s>>4,t[o]=e[o===19?i&3|8:i]);return t.join("")}var _;(function(e){e.PROD="prod",e.VK_ALIAS="vk_alias",e.VIDEOTEST="videotest",e.TEST="test",e.AUTO="auto"})(_||(_={}));var g;(function(e){e.Q144P="mobile",e.Q240P="lowest",e.Q360P="low",e.Q480P="medium",e.Q720P="high",e.Q1080P="fullhd",e.Q1440P="quadhd",e.Q2160P="ultrahd",e.UNKNOWN="unknown"})(g||(g={}));var p;(function(e){e.MP4="mp4",e.DASH="dash",e.DASH_SEP="dash_sep",e.ONDEMAND_DASH="ondemand_dash",e.HLS="hls",e.ONDEMAND_HLS="ondemand_hls",e.WEBM="webm",e.AV1="av1",e.ONDEMAND_DASH_LIVE="ondemand_dash_live",e.ONDEMAND_HLS_LIVE="ondemand_hls_live",e.WEBRTC="webrtc",e.UNKNOWN="unknown",e.RTMP="rtmp"})(p||(p={}));var k;(function(e){e.AUTO="auto",e.MANUAL=""})(k||(k={}));var $;(function(e){e.HTTP1="http1",e.HTTP2="http2",e.HTTP3="http3"})($||($={}));var A;(function(e){e[e.YES=1]="YES",e[e.NO=0]="NO"})(A||(A={}));var T;(function(e){e.EXCELLENT="excellent",e.GOOD="good",e.POOR="poor"})(T||(T={}));var P;(function(e){e.PIP="pip",e.FULLSCREEN="fullscreen",e.EXTERNAL="external",e.PREFETCH="prefetch"})(P||(P={}));var C;(function(e){e.SLIDER="slider",e.DOUBLE_TAP="double_tap",e.TIME_CODE="time_code",e.EPISODE="episode",e.REWIND="rewind",e.LIVE="live",e.UNKNOWN="unknown"})(C||(C={}));const z="1.0.37",dt="CIOPGQJGDIHBABABA",tt={[_.PROD]:"https://api.ok.ru",[_.VK_ALIAS]:"https://api.mycdn.me",[_.VIDEOTEST]:"https://videotestapi.ok.ru/api",[_.TEST]:"https://apitest.ok.ru",[_.AUTO]:""},ft="_one-stat_",Q=`${ft}uuid`,pt={start:1e3,factor:1.5,max:5*60*1e3,random:.1};var y;(function(e){e[e.PARAM_SESSION_EXPIRED=102]="PARAM_SESSION_EXPIRED",e[e.PARAM_SESSION_KEY=103]="PARAM_SESSION_KEY",e[e.PARAM_SIGNATURE=104]="PARAM_SIGNATURE",e[e.AUTH_LOGIN=401]="AUTH_LOGIN"})(y||(y={}));class gt{params;uuid;authToken;sessionKey;authorizePromise;refreshAuthTokenPromise;consequentAuthErrors=0;authorized$=new M(!1);backoffTimeoutId;constructor(t){this.params=t;const s=w.get(Q);s?this.uuid=String(s):(this.uuid=lt(),w.set(Q,this.uuid))}async authorize(t){return this.authToken=t??await this.refreshAuthToken(),this._authorizeWithBackoff()}logBeacon(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey;if(!o)return;this.params.apiTransport.sendBeacon(s,i,o)||this.logRequest(t)}async logRequest(t){const s="log.externalLog",i=this.createLogParams(t),o=this.sessionKey??await this._authorizeWithBackoff();if(!o)return;const n=async(a,l=this.params.requestRetryCount)=>{try{return await this.params.apiTransport.sendRequest(s,i,o)}catch(u){if(!u||!("error_code"in u)){this.params.error$.next({id:"logRequestUnknown",category:m.NETWORK,message:`Unknown ${s} error`,thrown:u});return}const h=u?.error_code;switch(h){case y.PARAM_SESSION_EXPIRED:case y.PARAM_SESSION_KEY:case y.PARAM_SIGNATURE:return this.authorized$.next(!1),this.sessionKey=await this._authorizeWithBackoff(),l>0?n(a,l-1):void 0;case y.AUTH_LOGIN: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#${h}`,category:m.EXTERNAL_API,message:`${s} error`,data:u});return}}}};return n(t)}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(t){return{collector:"ok.mobile.apps.video",data:JSON.stringify({application:`@vkontakte/videoplayer-statistics:${z}`,platform:this.params.mobile?"M_WEB":"WEB",items:t})}}_authorizeWithBackoff(){if(!this.consequentAuthErrors)return this._authorize();const t=ot(this.consequentAuthErrors,pt);return new Promise(s=>{this.backoffTimeoutId||(this.backoffTimeoutId=window.setTimeout(()=>{this._authorize().then(s).catch(i=>this.params.error$.next({id:"AuthorizeBackoff",category:m.NETWORK,message:"Otherwise unhandled error in authorization",thrown:i})).finally(()=>this.backoffTimeoutId=0)},t))})}async _authorize(){if(this.authorizePromise)return this.authorizePromise;this.sessionKey=void 0,this.authorized$.next(!1);const t="auth.anonymLogin",s={session_data:{version:2,device_id:this.uuid,client_version:z.split("-")[0],client_type:"SDK_JS"}};return this.authToken!==void 0&&(s.session_data.auth_token=this.authToken,s.session_data.version=3),this.authorizePromise=this.params.apiTransport.sendRequest(t,s).then(i=>((!i||!i.session_key)&&this.params.error$.next({id:"AuthorizeFailed",category:m.EXTERNAL_API,message:"No session key",data:i}),this.sessionKey=i?.session_key??void 0,this.sessionKey)).catch(async i=>{this.sessionKey=void 0;const o=i?.error_code;switch(o){case y.AUTH_LOGIN:return this.authToken=await this.refreshAuthToken(),this._authorizeWithBackoff()}o?this.params.error$.next({id:`Authorize#${o}`,category:m.EXTERNAL_API,message:"authorize error",data:i}):this.params.error$.next({id:"AuthorizeUnknown",category:m.NETWORK,message:"authorize error",thrown:i})}).finally(()=>{this.authorizePromise=void 0,this.consequentAuthErrors=this.sessionKey?0:this.consequentAuthErrors+1,this.authorized$.next(this.sessionKey!==void 0)}),this.authorizePromise}}class j{constructor(){Object.defineProperty(this,"listeners",{value:{},writable:!0,configurable:!0})}addEventListener(t,s,i){t in this.listeners||(this.listeners[t]=[]),this.listeners[t].push({callback:s,options:i})}removeEventListener(t,s){if(!(t in this.listeners))return;const i=this.listeners[t];for(let o=0,n=i.length;o<n;o++)if(i[o].callback===s){i.splice(o,1);return}}dispatchEvent(t){if(!(t.type in this.listeners))return;const i=this.listeners[t.type].slice();for(let o=0,n=i.length;o<n;o++){const a=i[o];try{a.callback.call(this,t)}catch(l){Promise.resolve().then(()=>{throw l})}a.options&&a.options.once&&this.removeEventListener(t.type,a.callback)}return!t.defaultPrevented}}class et extends j{constructor(){super(),this.listeners||j.call(this),Object.defineProperty(this,"aborted",{value:!1,writable:!0,configurable:!0}),Object.defineProperty(this,"onabort",{value:null,writable:!0,configurable:!0}),Object.defineProperty(this,"reason",{value:void 0,writable:!0,configurable:!0})}toString(){return"[object AbortSignal]"}dispatchEvent(t){t.type==="abort"&&(this.aborted=!0,typeof this.onabort=="function"&&this.onabort.call(this,t)),super.dispatchEvent(t)}}class bt{constructor(){Object.defineProperty(this,"signal",{value:new et,writable:!0,configurable:!0})}abort(t){let s;try{s=new Event("abort")}catch{typeof document<"u"?document.createEvent?(s=document.createEvent("Event"),s.initEvent("abort",!1,!1)):(s=document.createEventObject(),s.type="abort"):s={type:"abort",bubbles:!1,cancelable:!1}}let i=t;if(i===void 0)if(typeof document>"u")i=new Error("This operation was aborted"),i.name="AbortError";else try{i=new DOMException("signal is aborted without reason")}catch{i=new Error("This operation was aborted"),i.name="AbortError"}this.signal.reason=i,this.signal.dispatchEvent(s)}toString(){return"[object AbortController]"}}typeof Symbol<"u"&&Symbol.toStringTag&&(bt.prototype[Symbol.toStringTag]="AbortController",et.prototype[Symbol.toStringTag]="AbortSignal");function st(e){return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL?(console.log("__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"),!0):typeof e.Request=="function"&&!e.Request.prototype.hasOwnProperty("signal")||!e.AbortController}function mt(e){typeof e=="function"&&(e={fetch:e});const{fetch:t,Request:s=t.Request,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o=!1}=e;if(!st({fetch:t,Request:s,AbortController:i,__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL:o}))return{fetch:t,Request:n};let n=s;(n&&!n.prototype.hasOwnProperty("signal")||o)&&(n=function(h,r){let c;r&&r.signal&&(c=r.signal,delete r.signal);const d=new s(h,r);return c&&Object.defineProperty(d,"signal",{writable:!1,enumerable:!1,configurable:!0,value:c}),d},n.prototype=s.prototype);const a=t;return{fetch:(u,h)=>{const r=n&&n.prototype.isPrototypeOf(u)?u.signal:h?h.signal:void 0;if(r){let c;try{c=new DOMException("Aborted","AbortError")}catch{c=new Error("Aborted"),c.name="AbortError"}if(r.aborted)return Promise.reject(c);const d=new Promise((E,v)=>{r.addEventListener("abort",()=>v(c),{once:!0})});return h&&h.signal&&delete h.signal,Promise.race([d,a(u,h)])}return a(u,h)},Request:n}}const q=st({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}),it=q?mt({fetch:window.fetch,Request:window.Request,AbortController:window.AbortController}):void 0,G=q?it.fetch:window.fetch;q?it.Request:window.Request;class St{apiKey;apiBaseUrl;apiEnv;timeSynchronisation;isApiBaseUrlFetched;params;constructor(t){this.params=t,this.apiKey=t.apiKey,this.apiEnv=t.apiEnv,this.apiBaseUrl=t.apiBaseUrl,this.timeSynchronisation=t.timeSynchronisation,this.isApiBaseUrlFetched=!1}async resolveApiBaseUrl(){if(this.apiEnv!==_.AUTO||this.isApiBaseUrlFetched)return this.apiBaseUrl;try{const t=atob("aHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT12aWRlby5fZW5kcG9pbnQub2sucnUmdHlwZT1UWFQ="),o=(await(await G(t,{method:"GET",mode:"cors",cache:"no-cache"})).json())?.Answer[0]?.data;if(!o)throw new Error("Wrong DNS response");return o}catch(t){return this.params.error$.next({id:"OneStat:ApiTransport:resolveApiBaseUrl",category:m.NETWORK,message:"Unhandled resolve api base url error",thrown:t}),tt[_.VK_ALIAS]}finally{this.isApiBaseUrlFetched=!0}}sendBeacon(t,s,i){if(!window.Blob||!window.navigator.sendBeacon)return!1;const o=this._prepareQueryParams({method:t,queryParams:s,sessionKey:i}),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:m.NETWORK,message:"Unhandled beacon error",thrown:a,data:{method:t,params:s}})}return!1}async sendRequest(t,s,i){const o=b(),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:m.NETWORK,message:"Request failed",thrown:a});return}this.params.error$.next({id:"OneStat:ApiTransport:sendRequest",category:m.NETWORK,message:"Unhandled request error",thrown:a,data:{method:t,params:s,sessionKey:i,time:b()-o}})};return this.apiBaseUrl=await this.resolveApiBaseUrl(),G(`${this.apiBaseUrl}/fb.do`,{method:"post",headers:{"Content-type":"application/x-www-form-urlencoded"},body:this._prepareQueryParams({method:t,queryParams:s,sessionKey:i})}).then(a=>{const l=Number(a.headers.get("content-length"))===0,u=new Date(a.headers.get("date")??"").getTime(),h=b()-o;if(isFinite(u)&&this.timeSynchronisation.addServerTime(u,h),!l)return a.json().then(r=>Object.prototype.hasOwnProperty.call(r,"error_msg")?Promise.reject(r):r,n)},n)}_prepareQueryParams(t){const s=new URLSearchParams({format:"JSON",method:t.method,application_key:this.apiKey});return t.sessionKey!==void 0&&s.append("session_key",t.sessionKey),Object.entries(t.queryParams).forEach(([i,o])=>s.append(i,typeof o=="string"?o:JSON.stringify(o))),s}}const Y=5e3,Et=1e4,At=6e4,x="onestat_events",_t=36*60*60*1e3,D=e=>e.timestamp+_t>=b();class wt{api;error$;subscription;userSalt;unsaltedStorage=[];lastVsid;isPaused=!1;flushMaxWait=w.isPersistent()?At:0;constructor(t){this.api=t.api,this.error$=t.error$,this.userSalt=t.userSalt,this.subscription=this.api.authorized$.subscribe(s=>{s&&this.debouncedFlush()}),this.housekeepStorage()}isUrgent=t=>{const{operation:s,custom:{param:i}}=t;return["action_stop","close_at_empty_buffer"].includes(s)||s==="watch_coverage_record"&&i==="0-0"};safeFlush(){try{this.flush()}catch(t){this.error$.next({id:"LoggerError",category:m.WTF,message:String(t)??"Unknown logger error",thrown:t})}}firstFlush=V(()=>this.safeFlush(),Y,{maxWait:Y});debouncedFlush=V(()=>this.safeFlush(),Et,{maxWait:this.flushMaxWait});readFromStorage(){const t=w.get(x);try{return t?JSON.parse(t):{}}catch{}return{}}addToStorage(t){if(!this.userSalt){this.unsaltedStorage.push(t);return}const s=this.readFromStorage(),o=(s[this.userSalt]??[]).filter(D);w.set(x,JSON.stringify({...s,[this.userSalt]:[...o,t]}))}getFromStorage(){return this.userSalt?(this.readFromStorage()[this.userSalt]??[]).filter(D):this.unsaltedStorage}markStorageSent(){if(!this.userSalt){this.unsaltedStorage=[];return}const t=this.readFromStorage();delete t[this.userSalt],w.set(x,JSON.stringify(t))}housekeepStorage(){const t=this.readFromStorage();for(const[s,i]of Object.entries(t)){const o=i.filter(D);o.length?t[s]=o:delete t[s]}w.set(x,JSON.stringify(t))}log(t){this.addToStorage(t),!this.isPaused&&(this.isUrgent(t)?this.flush():this.lastVsid!==t.custom.vsid?this.firstFlush():this.debouncedFlush(),this.lastVsid=t.custom.vsid)}flush(t=!1){const s=this.getFromStorage();s.length!==0&&(this.api.authorized$.getValue()?(t?this.api.logBeacon(s):this.api.logRequest(s),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()}}const yt=()=>{let e,t;try{e=window.self!==window.top}catch(i){i instanceof DOMException&&i.name==="SecurityError"?e=!0:(e=!1,console.error(i))}try{window.location.ancestorOrigins&&(t=window.location.ancestorOrigins[window.location.ancestorOrigins.length-1])}catch(i){console.error(i)}try{!t&&document.referrer&&(t=document.referrer)}catch(i){console.error(i)}const s=t?new URL(t).hostname:void 0;return{isEmbed:e,host:s}},Pt=e=>e&&{[S.INVARIANT]:g.UNKNOWN,[S.Q_144P]:g.Q144P,[S.Q_240P]:g.Q240P,[S.Q_360P]:g.Q360P,[S.Q_480P]:g.Q480P,[S.Q_720P]:g.Q720P,[S.Q_1080P]:g.Q1080P,[S.Q_1440P]:g.Q1440P,[S.Q_2160P]:g.Q2160P,[S.Q_4320P]:g.UNKNOWN}[e],X=e=>e&&{[I.HTTP1]:$.HTTP1,[I.HTTP2]:$.HTTP2,[I.QUIC]:$.HTTP3}[e],Tt=e=>{if(e!==void 0)switch(e){case f.MPEG:return p.MP4;case f.DASH:case f.DASH_LIVE:return p.DASH;case f.DASH_SEP:return p.DASH_SEP;case f.DASH_ONDEMAND:return p.ONDEMAND_DASH;case f.DASH_WEBM:case f.DASH_LIVE_WEBM:return p.WEBM;case f.DASH_WEBM_AV1:return p.AV1;case f.DASH_LIVE_CMAF:return p.ONDEMAND_DASH_LIVE;case f.HLS:case f.HLS_LIVE:return p.HLS;case f.HLS_ONDEMAND:return p.ONDEMAND_HLS;case f.HLS_LIVE_CMAF:return p.ONDEMAND_HLS_LIVE;case f.WEB_RTC_LIVE:return p.WEBRTC;default:return Z(e)}},B=e=>{if(e!==void 0)switch(e){case R.NONE:case R.INLINE:return;case R.FULLSCREEN:return P.FULLSCREEN;case R.SECOND_SCREEN:return P.EXTERNAL;case R.PIP:return P.PIP;default:return Z(e)}},vt=e=>{switch(e){case"slow-2g":return T.POOR;case"2g":return T.POOR;case"3g":return T.GOOD;case"4g":return T.EXCELLENT}};class Ot{offset=void 0;constructor(t){this.offset=t}getOffset(){return this.offset??0}setOffset(t){this.offset=t}now(){return Date.now()+(this.offset??0)}date(t=new Date){return t.setTime(t.getTime()+(this.offset??0)),t}addServerTime(t,s){const i=Date.now(),o=t-i-s/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)}}const J=()=>Math.floor(Math.random()*2**32).toString(36).padStart(8,"0"),Rt=e=>new rt(t=>{const s=new N,i=L(F(window,"beforeunload"),e.events.willDestruct$),o=new M(void 0);let n;s.add(e.info.isLive$.pipe(nt()).subscribe(E=>{n&&(n.unsubscribe(),o.next(void 0)),E?n=e.info.liveTime$.pipe(at(v=>v&&v/1e3)).subscribe(o):n=e.info.position$.subscribe(o),s.add(n)}));const{playing$:a,paused$:l}=e.events,u=e.events.willSeek$.pipe(H(()=>e.info.playbackState$.getValue()===K.PLAYING)),h=e.events.seeked$.pipe(H(()=>e.info.playbackState$.getValue()===K.PLAYING)),r=L(a,h),c=L(l,u,i,e.events.looped$);let d;return s.add(r.subscribe(()=>d=o.getValue())),s.add(c.subscribe(()=>{const E=o.getValue();U(d)||d===E||U(E)||(t.next({from:d,to:E}),d=void 0)})),s});class Lt{api;logger;config;subscription=new N;beforeunloadSubscription;timeSynchronisation=new Ot;experimental;statContext;vsid=J();isEmbed;embedParent;uiEvents;player;seekAction$=new M(C.UNKNOWN);constructor(t,s){this.statContext=t,this.config={...s.config??{},requestRetryCount:1};const i=new ut;this.experimental={error$:i};const o=new St({apiKey:dt,apiBaseUrl:tt[s.apiEnv],apiEnv:s.apiEnv,error$:i,timeSynchronisation:this.timeSynchronisation});this.api=new gt({apiTransport:o,refreshAuthToken:s.refreshAuthToken,requestRetryCount:this.config.requestRetryCount,mobile:this.statContext.mobile??!1,error$:i}),this.logger=new wt({api:this.api,error$:i,userSalt:s.userSalt});const{isEmbed:n,host:a}=yt();this.isEmbed=n,this.embedParent=a,this.subscribe()}updateContext(t){this.statContext={...this.statContext,...t}}attachTo(t){const s=new N,i=(r,c)=>s.add(r.subscribe(c));i(t.events.willStart$,()=>{this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.looped$,()=>{this.resetViewSession(),this.logActionPlay({position:t.info.position$.getValue()})}),i(t.events.seeked$,()=>{this.logSeek({action:this.seekAction$.getValue(),time:t.info.position$.getValue()}),this.seekAction$.next(C.UNKNOWN)}),i(t.events.paused$,()=>{this.logPause({position:t.info.position$.getValue()})}),i(t.events.willResume$,()=>{this.logPlay()}),i(t.events.started$,()=>{this.statContext.clip&&this.logWatchCoverageRecord({start:0,end:0})}),i(Rt(t),r=>{const c=t.info.isLive$.getValue(),d={start:parseFloat(r.from.toFixed(3)),end:parseFloat(r.to.toFixed(3))};c?this.logWatchCoverageLive(d):this.logWatchCoverageRecord(d)});let o;i(t.info.isStalled$,r=>{r?o=b():(O(o)&&this.logEmptyBuffer({duration:b()-o}),o=void 0)});let n=!1;s.add(t.events.fatalError$.pipe(ct()).subscribe(()=>n=!0)),i(t.events.willStop$,()=>{if(t.info.isStalled$.getValue()){const c=O(o)?b()-o:void 0;this.logCloseAtEmptyBuffer({duration:c??0}),o=void 0}else n||this.logActionStop()}),i(t.events.managedError$,({id:r})=>{this.logError({fatal:!1,errorType:r})}),i(t.events.fatalError$,({id:r})=>{this.logError({fatal:!0,errorType:r})});let a,l,u=!1;i(t.events.firstBytes$,r=>{a=b(),this.logFirstBytes({time:r})}),i(t.events.willStart$,()=>l=b()),i(t.info.currentBuffer$,r=>{!u&&r&&r.end-r.start>0&&O(a)&&(this.logPlayerReady({duration:b()-a}),u=!0)}),i(t.events.firstFrame$,()=>{O(a)&&!u&&(this.logPlayerReady({duration:b()-a}),u=!0),O(l)&&this.logFirstFrame({time:b()-l})}),i(t.info.atLiveEdge$,r=>this.updateContext({liveEdge:r})),i(W({muted:t.info.muted$,volume:t.info.volume$}),({muted:r,volume:c})=>this.updateContext({audible:!r&&c>0})),i(t.info.currentQuality$,r=>this.updateContext({quality:Pt(r)})),i(t.info.isAutoQualityEnabled$,r=>this.updateContext({autoQuality:r})),i(t.info.currentFormat$,r=>this.updateContext({contentType:Tt(r)}));let h;return i(t.info.hostname$,r=>{this.updateContext({cdnHostname:r,failover:h!==void 0&&h!==r}),h=r}),i(t.info.throughputEstimation$,r=>this.updateContext({downloadSpeed:r})),i(t.info.httpConnectionType$,r=>{this.statContext.firstConnectionType||this.updateContext({firstConnectionType:X(r)}),this.updateContext({connectionType:X(r)})}),i(t.info.httpConnectionReused$,r=>{U(this.statContext.firstConnectionReused)&&this.updateContext({firstConnectionReused:r}),this.updateContext({connectionReused:r})}),i(t.info.surface$,r=>this.updateContext({mode:B(r)})),i(W({current:t.info.currentTextTrack$,available:t.info.availableTextTracks$}),({current:r,available:c})=>{const d=c.find(({id:E})=>E===r);this.updateContext({subtitles:d?.language})}),this.player=t,this.uiEvents&&this.attachToUi(this.uiEvents),this.resubscribeBeforeunload(),this.subscription.add(s),s}attachToUi(t){this.uiEvents=t;const s=new N;return this.player&&(s.add(t.actionRewind$.subscribe(()=>{this.player&&(this.resetViewSession(),this.logActionPlay({position:this.player.info.position$.getValue()}))})),s.add(t.actionSeek$.subscribe(this.seekAction$)),s.add(t.inPiP$.subscribe(i=>{const o=i?P.PIP:B(this.player?.info.surface$.getValue());this.updateContext({mode:o})})),s.add(t.inFullscreen$.subscribe(i=>{const o=i?P.FULLSCREEN:B(this.player?.info.surface$.getValue());this.updateContext({mode:o})})),s.add(t.actionSetSubtitle$.subscribe(i=>{this.updateContext({subtitles:i})})),this.resubscribeBeforeunload(),this.subscription.add(s)),s}attachToAds(t){const s=new N;return s.add(t.slotRequested$.subscribe(()=>this.logAdSlotRequest())).add(t.started$.subscribe(i=>this.logAdStarted(i))).add(t.paused$.subscribe(()=>this.logAdPaused())).add(t.resumed$.subscribe(()=>this.logAdResumed())).add(t.ended$.subscribe(()=>this.logAdEnded())).add(t.skipped$.subscribe(()=>this.logAdSkipped())).add(t.clicked$.subscribe(()=>this.logAdClicked())),this.resubscribeBeforeunload(),this.subscription.add(s),s}authorize(t){return this.api.authorize(t)}pause(){this.logger.pause()}resume(){this.logger.resume()}destroy(){this.logger.flush(),this.subscription.unsubscribe(),this.api.destroy(),this.logger.destroy()}resetViewSession(){this.vsid=J()}setFieldBlacklist(){}logInited(){}logReady(t){this.log({operation:"player_ready",param:String(t.time)})}logStarted(...t){this.logActionPlay(...t)}logPlay(){this.log({operation:"play_toggle"})}logPause(t){this.log({operation:"pause",param:String(Math.round(t.position))})}logSeek(t){this.log({operation:"seek",param:t.action,time:t.time})}logFirstBytes(t){this.log({operation:"first_bytes",param:String(t.time)})}logFirstFrame(t){this.log({operation:"first_frame",param:String(t.time)})}logError(t){this.log({operation:"content_error",param:`${t.fatal?"fatal":"recoverable"}_${t.errorType}`})}logWatchCoverageRecord(t){this.log({operation:"watch_coverage_record",param:`${t.start}-${t.end}`})}logWatchCoverageLive(t){const s=t.start+this.timeSynchronisation.getOffset(),i=t.end+this.timeSynchronisation.getOffset();this.log({operation:"watch_coverage_live",param:`${s}-${i}`})}logEmptyBuffer(t){this.log({operation:"empty_buffer",param:String(t.duration)})}logDownloadSpeed(){}logAdSlotRequest(){this.log({operation:"adv",param:"slot_request"})}logAdStarted(t){this.log({operation:"adv",param:t})}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"})}subscribe(){this.resubscribeBeforeunload();const t=window.navigator.connection;t&&"onchange"in t&&"effectiveType"in t&&this.subscription.add(L(F(t,"change"),ht(["init"])).subscribe(()=>this.updateContext({network:vt(t.effectiveType)})))}resubscribeBeforeunload(){this.beforeunloadSubscription?.unsubscribe(),this.beforeunloadSubscription=F(window,"beforeunload").subscribe(()=>this.logger.flush(!0)),this.subscription.add(this.beforeunloadSubscription)}logPlayerReady(t){this.log({operation:"player_ready",param:String(Math.round(t.duration))})}logActionPlay(t){this.log({operation:"action_play",param:String(Math.round(t.position))})}logCloseAtEmptyBuffer(t){this.log({operation:"close_at_empty_buffer",param:String(Math.round(t.duration))})}logActionStop(){this.log({operation:"action_stop"})}log(t){const s=this.createLogItem(t);this.logger.log(s)}createLogItem({operation:t,param:s,time:i}){const o=this.timeSynchronisation.now(),n=t==="empty_buffer"||t==="close_at_empty_buffer"?this.statContext.connectionType:this.statContext.firstConnectionType,a=this.statContext.firstConnectionReused,l={vsid:this.vsid,vid:this.statContext.movieId,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?k.AUTO:this.statContext.autoplay===!1?k.MANUAL:void 0,param:s,vk_app_id:this.statContext.vkAppId,track_code:this.statContext.trackCode,connection_type:n,connection_reused:a===!0?A.YES:a===!1?A.NO:void 0,cached_data:this.statContext.cached===!0?A.YES:this.statContext.cached===!1?A.NO:void 0,live:this.statContext.liveEdge?A.YES:void 0,muted:this.statContext.audible===!1?A.YES:void 0,mode:this.statContext.mode,subtitles:this.statContext.subtitles,download_speed:this.statContext.downloadSpeed,manual_quality:this.statContext.autoQuality?void 0:A.YES,ref_domain:this.embedParent,aid:this.statContext.albumId,vk_playlist_id:this.statContext.vkPlaylistId};return{operation:t,type:1,time:i,network:this.statContext.network,timestamp:o,custom:l}}}export{_ as ApiEnv,$ as ConnectionType,p as ContentType,Lt as OneStat,g as Quality,C as SeekAction,z as VERSION};
|