YouTube JS Engine Tamer

To enhance YouTube performance by modifying YouTube JS Engine

目前為 2024-05-12 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name YouTube JS Engine Tamer
  3. // @namespace UserScripts
  4. // @match https://www.youtube.com/*
  5. // @version 0.16.5
  6. // @license MIT
  7. // @author CY Fung
  8. // @icon https://raw.githubusercontent.com/cyfung1031/userscript-supports/main/icons/yt-engine.png
  9. // @description To enhance YouTube performance by modifying YouTube JS Engine
  10. // @grant none
  11. // @require https://cdn.jsdelivr.net/gh/cyfung1031/userscript-supports@7221a4efffd49d852de0074ec503d4febb99f28b/library/nextBrowserTick.min.js
  12. // @run-at document-start
  13. // @unwrap
  14. // @inject-into page
  15. // @allFrames true
  16. // ==/UserScript==
  17.  
  18. (() => {
  19.  
  20. const NATIVE_CANVAS_ANIMATION = false; // for #cinematics
  21. const FIX_schedulerInstanceInstance = 2 | 4;
  22. const FIX_yt_player = true; // DONT CHANGE
  23. const FIX_Animation_n_timeline = true;
  24. const NO_PRELOAD_GENERATE_204 = false;
  25. const ENABLE_COMPUTEDSTYLE_CACHE = true;
  26. const NO_SCHEDULING_DUE_TO_COMPUTEDSTYLE = true;
  27. const CHANGE_appendChild = true; // discussions#236759
  28.  
  29. const FIX_error_many_stack = true; // should be a bug caused by uBlock Origin
  30. // const FIX_error_many_stack_keepAliveDuration = 200; // ms
  31. // const FIX_error_many_stack_keepAliveDuration_check_if_n_larger_than = 8;
  32.  
  33. const FIX_Iframe_NULL_SRC = true;
  34.  
  35. const IGNORE_bindAnimationForCustomEffect = true; // prevent `v.bindAnimationForCustomEffect(this);` being executed
  36.  
  37. const FIX_ytdExpander_childrenChanged = true;
  38. const FIX_paper_ripple_animate = true;
  39. const FIX_avoid_incorrect_video_meta = true; // omit the incorrect yt-animated-rolling-number
  40. const FIX_avoid_incorrect_video_meta_emitterBehavior = true;
  41.  
  42. const FIX_doIdomRender = true;
  43.  
  44. const FIX_Shady = true;
  45.  
  46. // [[ 2024.04.24 ]]
  47. const MODIFY_ShadyDOM_OBJ = true;
  48. // << if MODIFY_ShadyDOM_OBJ >>
  49. const WEAKREF_ShadyDOM = true;
  50. const OMIT_ShadyDOM_EXPERIMENTAL = 1 | 0; // 1 => enable; 2 => composedPath
  51. const OMIT_ShadyDOM_settings = 0 | 0 | 0; // 1: inUse; 2: handlesDynamicScoping; 4: force // {{ PRELIM TESTING PURPOSE }}
  52. // << end >>
  53.  
  54. const WEAK_REF_BINDING_CONTROL = 1 | 2; // 2 - conflict control with ShadyDOM weakref
  55.  
  56. const FIX_ytAction_ = true; // ytd-app
  57. const FIX_onVideoDataChange = false;
  58. // const FIX_onClick = true;
  59. const FIX_onStateChange = true;
  60. const FIX_onLoopRangeChange = true;
  61. // const FIX_maybeUpdateFlexibleMenu = true; // ytd-menu-renderer
  62. const FIX_VideoEVENTS_v2 = true; // true might cause bug in switching page
  63.  
  64. const SCRIPTLET_NOFIX_setTimeout = true;
  65. const ENABLE_discreteTasking = true;
  66. // << if ENABLE_discreteTasking >>
  67. const FIX_stampDomArray_stableList = true;
  68. const ENABLE_weakenStampReferences = true; // disabled in old browsers
  69. // << end >>
  70.  
  71. const FIX_perfNow = true; // history state issue; see https://bugzilla.mozilla.org/show_bug.cgi?id=1756970
  72. const ENABLE_ASYNC_DISPATCHEVENT = false; // problematic
  73.  
  74. const UNLOAD_DETACHED_POLYMER = false; // unstable
  75. const FIX_Polymer_dom = true;
  76.  
  77. const WEAK_REF_BINDING = true; // false if your browser is slow
  78. // << if WEAK_REF_BINDING >>
  79. const WEAK_REF_PROXY_DOLLAR = true; // false if your browser is slow
  80. // << end >>
  81.  
  82. const SCRIPTLET_REMOVE_PRUNE_propNeedles = true; // brave scriptlet related
  83. const DEBUG_removePrune = false; // true for DEBUG
  84.  
  85. const FIX_XHR_REQUESTING = true;
  86. const FIX_VIDEO_BLOCKING = true; // usually it is a ads block issue
  87.  
  88. const LOG_FETCHMETA_UPDATE = false; // for DEBUG
  89.  
  90. const IGNORE_bufferhealth_CHECK = false; // experimental; true will make "Stats for nerds" no info.
  91.  
  92. const DENY_requestStorageAccess = true; // remove document.requestStorageAccess
  93. const DISABLE_IFRAME_requestStorageAccess = true; // no effect if DENY_requestStorageAccess is true
  94.  
  95. const DISABLE_COOLDOWN_SCROLLING = true; // YT cause scroll hang in MacOS
  96.  
  97. const FIX_removeChild = true;
  98.  
  99. // ----------------------------- Shortkey Keyboard Control -----------------------------
  100. // dependency: FIX_yt_player
  101.  
  102. const FIX_SHORTCUTKEYS = 2; // 0 - no fix; 1 - basic fix; 2 - advanced fix
  103. // [0] no fix - not recommended
  104. // [1] basic fix - just fix the global focus detection variable
  105. // [2] advanced fix - call the shortcut actions directly, auto foucs change, direct control of spacebar behavior, etc
  106. // (note) 0 or 1 if you find conflict with other userscripts/plugin
  107.  
  108. const CHANGE_SPEEDMASTER_SPACEBAR_CONTROL = 0; // 0 - disable; 1 - force true; 2 - force false
  109. const USE_IMPROVED_PAUSERESUME_UNDER_NO_SPEEDMASTER = true; // only for SPEEDMASTER = false & FIX_SHORTCUTKEYS = 2
  110.  
  111. const PROP_OverReInclusion_AVOID = true;
  112. const PROP_OverReInclusion_DEBUGLOG = false;
  113. const PROP_OverReInclusion_LIST = new Set([
  114. 'hostElement72',
  115. 'parentComponent72',
  116. 'localVisibilityObserver_72',
  117. 'cachedProviderNode_72',
  118. '__template72',
  119. '__templatizeOwner72',
  120. '__templateInfo72',
  121. '__dataHost72',
  122. '__CE_shadowRoot72',
  123. 'elements_72',
  124.  
  125. 'ky36',
  126. 'kz62',
  127. 'm822',
  128.  
  129.  
  130.  
  131. // To be reviewed.
  132.  
  133. // chat messages
  134. 'disabled', 'allowedProps',
  135. 'filledButtonOverrides', 'openPopupConfig', 'supportsInlineActionButtons', 'allowedProps',
  136.  
  137. 'dimension', 'loadTime', 'pendingPaint',
  138.  
  139. 'countdownDurationMs', 'countdownMs', 'lastCountdownTimeMs', 'rafId', 'playerProgressSec', 'detlaSincePausedSecs', 'behaviorActionMap', 'selected', 'maxLikeCount', 'maxReplyCount', 'isMouseOver',
  140.  
  141. 'respectLangDir', 'noEndpoints',
  142.  
  143.  
  144. 'objectURL',
  145. 'buttonOverrides', 'queuedMessages',
  146. 'STEP', 'BLOCK_ON', 'MIN_PROGESS', 'MAX_PROGESS',
  147. 'DISMISSED_CONTENT_KEYSPACE', 'followUpDialogPromise', 'followUpDialogPromiseResolve', 'followUpDialogPromiseReject',
  148. 'hoverJobId', 'JSC$14573_touched',
  149.  
  150.  
  151. // tbc
  152. 'toggleable', 'isConnected',
  153. 'scrollDistance', 'dragging', 'dragMouseStart', 'dragOffsetStart', 'containerWidthDiff',
  154. 'disableDeselectEvent',
  155. 'emojiSize',
  156.  
  157. 'buttonOverride',
  158. 'shouldUseStickyPreferences', 'longPressTimeoutId',
  159.  
  160. // others
  161. 'observeVisibleOption', 'observeHiddenOption', 'observePrescanOption', 'visibilityMonitorKeys',
  162. // 'filledButtonOverrides', 'openPopupConfig', 'supportsInlineActionButtons',
  163. 'observeVisibleOption', 'observeHiddenOption', 'observePrescanOption', 'visibilityMonitorKeys',
  164. // 'dimension', 'loadTime', 'pendingPaint',
  165. // 'disabled', 'allowedProps',
  166.  
  167.  
  168. // 'enableMssLazyLoad', 'popupContainerConfig', 'actionRouterNode', 'actionRouterIsRoot', 'actionMap', 'dynamicActionMap',
  169. // 'actionMap',
  170.  
  171. // 'sharedTooltipPosition', 'sharedTooltipAnimationDelay', 'disableEmojiPickerIncrementalLoading', 'useResolveCommand', 'activeRequest', 'popoutWindowCheckIntervalId', 'supportedTooltipTargets', 'closeActionPanelTimerId', 'delayCloseActionPanelTimerId', 'tooltipTimerIds', 'queuedTooltips', 'isPopupConfigReady', 'popoutWindow', 'actionMap',
  172.  
  173. 'clearTimeout',
  174. 'switchTemplateAtRegistration', 'hasUnmounted',
  175. 'switchTemplateAtRegistration', 'stopKeyboardEventPropagation',
  176. 'tangoConfiguration',
  177. 'itemIdToDockDurationMap',
  178. 'actionMap',
  179.  
  180. 'emojiManager', 'inputMethodEditorActive', 'suggestionIndex', 'JSC$10745_lastSuggestionRange',
  181. 'actionMap', 'asyncHandle', 'shouldAnimateIn', 'lastFrameTimestamp', 'scrollClampRaf',
  182. 'scrollRatePixelsPerSecond', 'scrollStartTime', 'scrollStopHandle'
  183.  
  184. // 'buttonOverrides', 'queuedMessages', 'clearTimeout', 'actionMap',
  185. // 'stopKeyboardEventPropagation', 'emojiSize',
  186. // 'switchTemplateAtRegistration', 'hasUnmounted',
  187. // 'buttonOverrides', 'queuedMessages', 'clearTimeout', 'actionMap',
  188. // 'isReusable', 'tangoConfiguration',
  189. // 'itemIdToDockDurationMap', 'bottomAlignMessages', 'actionMap',
  190. // */
  191.  
  192. ]);
  193.  
  194.  
  195. // const CAN_TUNE_VOLUMN_AFTER_RESUME_OR_PAUSE = false; // NO USE; TO BE REVIEWED
  196.  
  197. // ----------------------------- Shortkey Keyboard Control -----------------------------
  198.  
  199. /*
  200. window.addEventListener('edm',()=>{
  201. let p = [...this.onerror.errorTokens][0].token; (()=>{ console.log(p); throw new Error(p);console.log(334,p) })()
  202. });
  203.  
  204. window.addEventListener('edn',()=>{
  205. let p = [...this.onerror.errorTokens][0].token+"X"; (()=>{ console.log(p); throw new Error(p);console.log(334,p) })()
  206. });
  207. window.addEventListener('edr',()=>{
  208. let p = '123'; (()=>{ console.log(p); throw new Error(p);console.log(334,p) })()
  209. });
  210. */
  211.  
  212. // only for macOS with Chrome/Firefox 100+
  213. const advanceLogging = typeof AbortSignal !== 'undefined' && typeof (AbortSignal || 0).timeout === 'function' && typeof navigator !== 'undefined' && /\b(Macintosh|Mac\s*OS)\b/i.test((navigator || 0).userAgent || '');
  214.  
  215. const win = this instanceof Window ? this : window;
  216.  
  217. // Create a unique key for the script and check if it is already running
  218. const hkey_script = 'jswylcojvzts';
  219. if (win[hkey_script]) throw new Error('Duplicated Userscript Calling'); // avoid duplicated scripting
  220. win[hkey_script] = true;
  221.  
  222.  
  223.  
  224. let BY_PASS_KEYBOARD_CONTROL = false;
  225.  
  226.  
  227. // const setImmediate = ((self || 0).jmt || 0).setImmediate;
  228. /** @type {(f: ()=>{})=>{}} */
  229. const nextBrowserTick = (self || 0).nextBrowserTick || 0;
  230. const nextBrowserTick_ = nextBrowserTick || (f => f());
  231.  
  232. let p59 = 0;
  233.  
  234. const Promise = (async () => { })().constructor;
  235.  
  236. const PromiseExternal = ((resolve_, reject_) => {
  237. const h = (resolve, reject) => { resolve_ = resolve; reject_ = reject };
  238. return class PromiseExternal extends Promise {
  239. constructor(cb = h) {
  240. super(cb);
  241. if (cb === h) {
  242. /** @type {(value: any) => void} */
  243. this.resolve = resolve_;
  244. /** @type {(reason?: any) => void} */
  245. this.reject = reject_;
  246. }
  247. }
  248. };
  249. })();
  250.  
  251. /**
  252. @param {number} x
  253. @param {number} d */
  254. const toFixed2 = (x, d) => {
  255. let t = x.toFixed(d);
  256. let y = `${+t}`;
  257. return y.length > t.length ? t : y;
  258. }
  259.  
  260.  
  261. let pf31 = new PromiseExternal();
  262.  
  263. // native RAF
  264. let __requestAnimationFrame__ = typeof webkitRequestAnimationFrame === 'function' ? window.webkitRequestAnimationFrame.bind(window) : window.requestAnimationFrame.bind(window);
  265.  
  266. // 1st wrapped RAF
  267. const baseRAF = (callback) => {
  268. return p59 ? __requestAnimationFrame__(callback) : __requestAnimationFrame__((hRes) => {
  269. pf31.then(() => {
  270. callback(hRes);
  271. });
  272. });
  273. };
  274.  
  275. // 2nd wrapped RAF
  276. window.requestAnimationFrame = baseRAF;
  277.  
  278. const insp = o => o ? (o.polymerController || o.inst || o || 0) : (o || 0);
  279. const indr = o => insp(o).$ || o.$ || 0;
  280.  
  281. const prototypeInherit = (d, b) => {
  282. const m = Object.getOwnPropertyDescriptors(b);
  283. for (const p in m) {
  284. if (!Object.getOwnPropertyDescriptor(d, p)) {
  285. Object.defineProperty(d, p, m[p]);
  286. }
  287. }
  288. };
  289.  
  290. /** @type {(o: Object | null) => WeakRef | null} */
  291. const mWeakRef = typeof WeakRef === 'function' ? (o => o ? new WeakRef(o) : null) : (o => o || null);
  292.  
  293. /** @type {(wr: Object | null) => Object | null} */
  294. const kRef = (wr => (wr && wr.deref) ? wr.deref() : wr);
  295.  
  296. if (typeof Document.prototype.requestStorageAccessFor === 'function') {
  297. if (DENY_requestStorageAccess) {
  298. // https://developer.mozilla.org/en-US/docs/Web/API/Document/requestStorageAccessFor
  299. Document.prototype.requestStorageAccessFor = undefined;
  300. console.log('[yt-js-engine-tamer]', 'requestStorageAccessFor is removed.');
  301. } else if (DISABLE_IFRAME_requestStorageAccess && window !== top) {
  302. Document.prototype.requestStorageAccessFor = function () {
  303. return new Promise((resolve, reject) => {
  304. reject();
  305. });
  306. };
  307. }
  308. }
  309.  
  310.  
  311.  
  312. const isCustomElementsProvided = typeof customElements !== "undefined" && typeof (customElements || 0).whenDefined === "function";
  313.  
  314. const promiseForCustomYtElementsReady = isCustomElementsProvided ? Promise.resolve(0) : new Promise((callback) => {
  315. const EVENT_KEY_ON_REGISTRY_READY = "ytI-ce-registry-created";
  316. if (typeof customElements === 'undefined') {
  317. if (!('__CE_registry' in document)) {
  318. // https://github.com/webcomponents/polyfills/
  319. Object.defineProperty(document, '__CE_registry', {
  320. get() {
  321. // return undefined
  322. },
  323. set(nv) {
  324. if (typeof nv == 'object') {
  325. delete this.__CE_registry;
  326. this.__CE_registry = nv;
  327. this.dispatchEvent(new CustomEvent(EVENT_KEY_ON_REGISTRY_READY));
  328. }
  329. return true;
  330. },
  331. enumerable: false,
  332. configurable: true
  333. })
  334. }
  335. let eventHandler = (evt) => {
  336. document.removeEventListener(EVENT_KEY_ON_REGISTRY_READY, eventHandler, false);
  337. const f = callback;
  338. callback = null;
  339. eventHandler = null;
  340. f();
  341. };
  342. document.addEventListener(EVENT_KEY_ON_REGISTRY_READY, eventHandler, false);
  343. } else {
  344. callback();
  345. }
  346. });
  347.  
  348. const whenCEDefined = isCustomElementsProvided
  349. ? (nodeName) => customElements.whenDefined(nodeName)
  350. : (nodeName) => promiseForCustomYtElementsReady.then(() => customElements.whenDefined(nodeName));
  351.  
  352. FIX_perfNow && performance.timeOrigin > 9 && (() => {
  353. if (performance.now23 || performance.now16 || typeof Performance.prototype.now !== 'function') return;
  354. const f = performance.now23 = Performance.prototype.now;
  355.  
  356. let k = 0; // 0 <= k < 9998m
  357. let u = 0;
  358. let s = ((performance.timeOrigin % 7) + 1) / 7 - 1e-2 / 7; // s > 0.14
  359.  
  360. // By definition, performance.now() is mono increasing.
  361. // Fixing in YouTube.com is required to ensure performance.now() is strictly increasing.
  362. performance.now = performance.now16 = function () {
  363. /**
  364. * Bug 1842437 - When attempting to go back on youtube.com, the content remains the same
  365. *
  366. * If consecutive session history entries had history.state.entryTime set to same value,
  367. * back button doesn't work as expected. The entryTime value is coming from performance.now()
  368. * and modifying its return value slightly to make sure two close consecutive calls don't
  369. * get the same result helped with resolving the issue.
  370. */
  371. // see https://bugzilla.mozilla.org/show_bug.cgi?id=1756970
  372. // see https://bugzilla.mozilla.org/show_bug.cgi?id=1842437
  373.  
  374. const v = typeof (this || 0).now23 === 'function' ? this.now23() + s : f.call(performance) + s; // v > 0.14
  375. if (u + 0.0015 < (u = v)) k = 0; // note: hRes should be accurate to 5 µs in isolated contexts
  376. else if (k < 0.001428) k += 1e-6 / 7; // M = 10000 * m; m * 9996 = 0.001428
  377. else { // more than 9998 consecutive calls
  378. /**
  379. *
  380. * max no. of consecutive calls
  381. *
  382. * Sample Size: 4800
  383. * Sample Avg = 1565.375
  384. * Sample Median = 1469.5
  385. * Sample Max = 5660 << 7500 << 9999
  386. *
  387. *
  388. * */
  389. k = 0;
  390. s += 1 / 7;
  391. }
  392. return v + k; // 0 < v - M < v - M + k < v
  393. }
  394.  
  395. let loggerMsg = '';
  396. if (`${performance.now()}` === `${performance.now()}`) {
  397. const msg1 = 'performance.now is modified but performance.now() is not strictly increasing.';
  398. const msg2 = 'performance.now cannot be modified and performance.now() is not strictly increasing.';
  399. loggerMsg = performance.now !== performance.now16 ? msg1 : msg2; // might not able to set in Firefox
  400. }
  401. loggerMsg && console.warn(loggerMsg);
  402. })();
  403.  
  404. FIX_removeChild && (() => {
  405. if (typeof Node.prototype.removeChild === 'function' && typeof Node.prototype.removeChild062 !== 'function') {
  406. Node.prototype.removeChild062 = Node.prototype.removeChild;
  407. Node.prototype.removeChild = function (child) {
  408. if (typeof this.__shady_native_removeChild !== 'function' || ((child instanceof Node) && child.parentNode === this)) {
  409. this.removeChild062(child);
  410. } else if ((child instanceof Element) && child.is === 'tp-yt-paper-tooltip') {
  411. // tooltip bug
  412. } else {
  413. console.warn('[yt-js-engine-tamer] Node is not removed from parent', { parent: this, child: child })
  414. }
  415. return child;
  416. }
  417. }
  418. })();
  419.  
  420. // WEAKREF_ShadyDOM
  421.  
  422. MODIFY_ShadyDOM_OBJ && ((WeakRef) => {
  423.  
  424. const setupPlainShadyDOM = (b) => {
  425. (OMIT_ShadyDOM_settings & 1) && (b.inUse === true) && (b.inUse = false);
  426. (OMIT_ShadyDOM_settings & 2) && (b.handlesDynamicScoping === true) && (b.handlesDynamicScoping = false);
  427. (OMIT_ShadyDOM_settings & 4) && (b.force === true) && (b.force = false);
  428. b.patchOnDemand = true;
  429. b.preferPerformance = true;
  430. b.noPatch = true;
  431. }
  432.  
  433. const isPlainObject = (b, m) => {
  434. if (!b || typeof b !== 'object') return false;
  435. const e = Object.getOwnPropertyDescriptors(b);
  436. if (e.length <= m) return false;
  437. let pr = 0;
  438. for (const k in e) {
  439. const d = e[k];
  440. if (!d || d.get || d.set || !d.enumerable || !d.configurable) return false;
  441. if (!('value' in d) || typeof d.value === 'function') return false;
  442. pr++;
  443. }
  444. return pr > m;
  445. }
  446.  
  447. let b;
  448.  
  449. let lz = 0;
  450.  
  451. const sdp = Object.getOwnPropertyDescriptor(window, 'ShadyDOM');
  452. if (sdp && sdp.configurable && sdp.value && sdp.enumerable && sdp.writable) {
  453.  
  454. // Brave - ShadyDOM exists before userscripting
  455. b = sdp.value;
  456.  
  457. if (b && typeof b === 'object' && isPlainObject(b, 0)) {
  458. OMIT_ShadyDOM_EXPERIMENTAL && setupPlainShadyDOM(b);
  459. lz = 1;
  460. }
  461.  
  462. }
  463.  
  464.  
  465. if (sdp && sdp.configurable && sdp.value && sdp.enumerable && sdp.writable && !sdp.get && !sdp.set) {
  466. } else if (!sdp) {
  467. } else {
  468. console.log(3719, '[yt-js-engine-tamer] FIX::ShadyDOM is not applied [ PropertyDescriptor issue ]', sdp);
  469. return;
  470. }
  471.  
  472. const shadyDOMNodeWRM = new WeakMap();
  473.  
  474. console.log(3719, '[yt-js-engine-tamer] FIX::ShadyDOM << 01 >>', b);
  475.  
  476. const weakWrapperNodeHandlerFn = () => ({
  477. get() {
  478. let w = shadyDOMNodeWRM.get(this);
  479. if (typeof w === 'object') w = kRef(w) || (shadyDOMNodeWRM.delete(this), undefined);
  480. return w;
  481. },
  482. set(nv) {
  483. shadyDOMNodeWRM.set(this, mWeakRef(nv));
  484. return true;
  485. },
  486. enumerable: true,
  487. configurable: true
  488. });
  489.  
  490. function weakWrapper(_ShadyDOM) {
  491. const ShadyDOM = _ShadyDOM;
  492. if (WEAKREF_ShadyDOM && lz < 3 && typeof WeakRef === 'function' && typeof ShadyDOM.Wrapper === 'function' && ShadyDOM.Wrapper.length === 1 && typeof (ShadyDOM.Wrapper.prototype || 0) === 'object') {
  493. let nullElement = { node: null };
  494. Object.setPrototypeOf(nullElement, Element.prototype);
  495. let p = new ShadyDOM.Wrapper(nullElement);
  496. let d = Object.getOwnPropertyDescriptor(p, 'node');
  497. if (d.configurable && d.enumerable && !d.get && !d.set && d.writable && d.value === nullElement && !Object.getOwnPropertyDescriptor(ShadyDOM.Wrapper.prototype, 'node')) {
  498. Object.defineProperty(ShadyDOM.Wrapper.prototype, 'node', weakWrapperNodeHandlerFn());
  499. console.log('[yt-js-engine-tamer] FIX::ShadyDOM << WEAKREF_ShadyDOM >>')
  500. }
  501. }
  502. }
  503.  
  504. let previousWrapStore = null;
  505.  
  506. const standardWrap = function (a) {
  507. if (a instanceof ShadowRoot || a instanceof ShadyDOM.Wrapper) return a;
  508. if (previousWrapStore) {
  509. const s = kRef(previousWrapStore.get(a)); // kRef for play safe only
  510. if (s) {
  511. previousWrapStore.delete(a);
  512. shadyDOMNodeWRM.set(a, mWeakRef(s));
  513. }
  514. }
  515. let u = kRef(shadyDOMNodeWRM.get(a));
  516. if (!u) {
  517. u = new ShadyDOM.Wrapper(a);
  518. shadyDOMNodeWRM.set(a, mWeakRef(u));
  519. }
  520. return u;
  521. }
  522.  
  523.  
  524. function setupWrapFunc(_ShadyDOM) {
  525. const ShadyDOM = _ShadyDOM;
  526.  
  527.  
  528. const wmPD = Object.getOwnPropertyDescriptor(WeakMap.prototype, 'get');
  529. if (!(wmPD && wmPD.writable && !wmPD.enumerable && wmPD.configurable && wmPD.value && !wmPD.get && !wmPD.set)) {
  530. return;
  531. }
  532. let mm = new Set();
  533. const pget = wmPD.value;
  534. WeakMap.prototype.get = function (a) {
  535. mm.add(this);
  536. return a;
  537. }
  538. try {
  539. let nullElement = { node: null };
  540. Object.setPrototypeOf(nullElement, Element.prototype);
  541. ShadyDOM.wrapIfNeeded(nullElement)
  542. ShadyDOM.wrap(nullElement)
  543. } catch (e) { }
  544. WeakMap.prototype.get = pget;
  545. if (mm.size !== 1) {
  546. mm.clear();
  547. return;
  548. }
  549. const p = mm.values().next().value;
  550. if (!(p instanceof WeakMap)) return;
  551. // p.clear();
  552. // p.get = function (a) { return a }
  553. // p.set = function (a, b) { return this }
  554. // console.log(188, window.n2n = mm, window.n2p = p)
  555.  
  556. // console.log(34929,p.size)
  557. previousWrapStore = p;
  558.  
  559. if (typeof ShadyDOM.wrap === 'function' && ShadyDOM.wrap.length === 1) {
  560. ShadyDOM.wrap = function (a) { 0 && console.log(3719, '[yt-js-engine-tamer] (OMIT_ShadyDOM) function call - wrap'); return standardWrap(a) }
  561. }
  562. if (typeof ShadyDOM.wrapIfNeeded === 'function' && ShadyDOM.wrapIfNeeded.length === 1) {
  563. ShadyDOM.wrapIfNeeded = function (a) { console.log(3719, '[yt-js-engine-tamer] (OMIT_ShadyDOM) function call - wrapIfNeeded'); return standardWrap(a) }
  564. }
  565.  
  566. }
  567.  
  568. function setupLZ3(nv) {
  569.  
  570. const ShadyDOM = nv;
  571.  
  572. const ShadyDOMSettings = ShadyDOM.settings;
  573. if (!(ShadyDOMSettings.inUse === true && ShadyDOM.inUse === true && (ShadyDOMSettings.handlesDynamicScoping || ShadyDOM.handlesDynamicScoping) === true)) {
  574. console.log(3719, '[yt-js-engine-tamer] OMIT_ShadyDOM is not applied [02]', window.ShadyDOM);
  575. return false;
  576. }
  577.  
  578. weakWrapper(ShadyDOM);
  579.  
  580. if (OMIT_ShadyDOM_EXPERIMENTAL && lz < 3) {
  581.  
  582. setupPlainShadyDOM(ShadyDOMSettings);
  583. setupPlainShadyDOM(ShadyDOM);
  584.  
  585. ShadyDOM.isShadyRoot = function () { console.log(3719, '[yt-js-engine-tamer] (OMIT_ShadyDOM) function call - isShadyRoot'); return false; }
  586.  
  587. setupWrapFunc(ShadyDOM);
  588. ShadyDOM.patchElementProto = function () { console.log(3719, '[yt-js-engine-tamer] (OMIT_ShadyDOM) function call - patchElementProto') }
  589. ShadyDOM.patch = function () { console.log(3719, '[yt-js-engine-tamer] (OMIT_ShadyDOM) function call - patch') }
  590.  
  591. // To be confirmed
  592. if (OMIT_ShadyDOM_EXPERIMENTAL & 2) {
  593. ShadyDOM.composedPath = function (e) {
  594. const t = (e || 0).target || null;
  595. if (!(t instanceof HTMLElement)) {
  596. console.log(3719, '[yt-js-engine-tamer] (OMIT_ShadyDOM&2) composedPath', t)
  597. }
  598. return t instanceof HTMLElement ? [t] : [];
  599. };
  600. }
  601.  
  602. }
  603.  
  604. }
  605.  
  606.  
  607. function setupLZ6(nv) {
  608.  
  609. const ShadyDOM = nv;
  610.  
  611. const ShadyDOMSettings = ShadyDOM.settings;
  612.  
  613. if (!(ShadyDOMSettings.inUse === true && ShadyDOM.inUse === true && (ShadyDOMSettings.handlesDynamicScoping || ShadyDOM.handlesDynamicScoping) === true)) {
  614. console.log(3719, '[yt-js-engine-tamer] OMIT_ShadyDOM is not applied [02]', window.ShadyDOM);
  615. return false;
  616. }
  617.  
  618. weakWrapper(ShadyDOM);
  619.  
  620. if (OMIT_ShadyDOM_EXPERIMENTAL && lz < 3) {
  621.  
  622. setupPlainShadyDOM(ShadyDOMSettings);
  623. setupPlainShadyDOM(ShadyDOM);
  624.  
  625. setupWrapFunc(ShadyDOM);
  626.  
  627. }
  628.  
  629. }
  630.  
  631. if (b && typeof b.Wrapper === 'function' && typeof b.settings === 'object' && typeof b.wrap === 'function') {
  632.  
  633. const nv = b;
  634.  
  635. if (setupLZ6(nv) === false) return;
  636.  
  637. lz = 6;
  638.  
  639. console.log(3719, '[yt-js-engine-tamer] FIX::ShadyDOM << 02b >>', nv)
  640.  
  641. return;
  642. }
  643.  
  644. delete window.ShadyDOM;
  645.  
  646. Object.defineProperty(window, 'ShadyDOM', {
  647. get() {
  648. return b;
  649. },
  650. set(nv) {
  651. let ret = 0;
  652. try {
  653. do {
  654. if (!nv || !nv.settings) {
  655. if (lz < 1 && nv && typeof nv === 'object' && isPlainObject(nv, 0)) {
  656. OMIT_ShadyDOM_EXPERIMENTAL && setupPlainShadyDOM(nv);
  657. lz = 1;
  658. break;
  659. } else {
  660. console.log(3719, '[yt-js-engine-tamer] FIX::ShadyDOM is not applied [nv:null]', nv);
  661. break;
  662. }
  663. }
  664.  
  665. const sdp = Object.getOwnPropertyDescriptor(this || {}, 'ShadyDOM');
  666. if (!(sdp && sdp.configurable && sdp.get && sdp.set)) {
  667. console.log(3719, '[yt-js-engine-tamer] OMIT_ShadyDOM is not applied [ incorrect PropertyDescriptor ]', nv);
  668. break;
  669. }
  670.  
  671. if (setupLZ3(nv) === false) break;
  672.  
  673. lz = 3;
  674.  
  675. console.log(3719, '[yt-js-engine-tamer] FIX::ShadyDOM << 02a >>', nv)
  676.  
  677. ret = 1;
  678.  
  679. } while (0);
  680. } catch (e) {
  681. console.log('[yt-js-engine-tamer] FIX::ShadyDOM << ERROR >>', e)
  682. }
  683.  
  684. if (!ret) b = nv;
  685. else {
  686. delete this.ShadyDOM;
  687. this.ShadyDOM = nv;
  688. }
  689. return true;
  690. },
  691. enumerable: false,
  692. configurable: true
  693. });
  694.  
  695. })(typeof WeakRef !== 'undefined' ? WeakRef : function () { });
  696.  
  697. if (ENABLE_ASYNC_DISPATCHEVENT && nextBrowserTick) {
  698. const filter = new Set([
  699. 'yt-action',
  700. // 'iframe-src-replaced',
  701. 'shown-items-changed',
  702. 'can-show-more-changed', 'collapsed-changed',
  703.  
  704. 'yt-navigate', 'yt-navigate-start', 'yt-navigate-cache',
  705. 'yt-player-updated', 'yt-page-data-fetched', 'yt-page-type-changed', 'yt-page-data-updated',
  706. 'yt-navigate-finish',
  707.  
  708. // 'data-changed','yt-watch-comments-ready'
  709. ])
  710. EventTarget.prototype.dispatchEvent938 = EventTarget.prototype.dispatchEvent;
  711. EventTarget.prototype.dispatchEvent = function (event) {
  712. const type = (event || 0).type;
  713. if (typeof type === 'string' && event.isTrusted === false && (event instanceof CustomEvent) && event.cancelable === false) {
  714. if (!filter.has(type) && !type.endsWith('-changed')) {
  715. if (this instanceof Node || this instanceof Window) {
  716. nextBrowserTick(() => this.dispatchEvent938(event));
  717. return true;
  718. }
  719. }
  720. }
  721. return this.dispatchEvent938(event);
  722. }
  723. }
  724.  
  725. // avoid REGEXP testPattern execution in Brave's scriptlet for performance boost
  726. SCRIPTLET_REMOVE_PRUNE_propNeedles && (() => {
  727. // const xhr = new XMLHttpRequest;
  728. const pdOri = Object.getOwnPropertyDescriptor(Map.prototype, 'size');
  729. if (!pdOri || pdOri.configurable !== true) return;
  730. let propNeedles = null;
  731. const pdNew = {
  732. configurable: true,
  733. enumerable: true,
  734. get: function () {
  735. propNeedles = this;
  736. if (DEBUG_removePrune) debugger; // to locate Brave scriptlets
  737. throw new Error();
  738. }
  739. }
  740. Object.defineProperty(Map.prototype, 'size', pdNew);
  741. try {
  742. XMLHttpRequest.prototype.open.call(0);
  743. // xhr.open.call(null)
  744. } catch (e) { }
  745. Object.defineProperty(Map.prototype, 'size', pdOri);
  746. if (!propNeedles) return;
  747. const entries = [...propNeedles.entries()];
  748. propNeedles.clear();
  749. console.log('[yt-js-engine-tamer] propNeedles is cleared from scriptlet', entries, propNeedles);
  750. })();
  751.  
  752. if (FIX_XHR_REQUESTING) {
  753.  
  754. const URL = window.URL || new Function('return URL')();
  755. const createObjectURL = URL.createObjectURL.bind(URL);
  756.  
  757. XMLHttpRequest = (() => {
  758. const XMLHttpRequest_ = XMLHttpRequest;
  759. if ('__xmMc8__' in XMLHttpRequest_.prototype) return XMLHttpRequest_;
  760. const url0 = createObjectURL(new Blob([], { type: 'text/plain' }));
  761. const c = class XMLHttpRequest extends XMLHttpRequest_ {
  762. constructor(...args) {
  763. super(...args);
  764. }
  765. open(method, url, ...args) {
  766. let skip = false;
  767. if (!url || typeof url !== 'string') skip = true;
  768. else if (typeof url === 'string') {
  769. let turl = url[0] === '/' ? `.youtube.com${url}` : `${url}`;
  770. if (turl.includes('googleads') || turl.includes('doubleclick.net')) {
  771. skip = true;
  772. } else if (turl.includes('.youtube.com/pagead/')) {
  773. skip = true;
  774. } else if (turl.includes('.youtube.com/ptracking')) {
  775. skip = true;
  776. } else if (turl.includes('.youtube.com/youtubei/v1/log_event?')) {
  777. skip = true;
  778. } else if (turl.includes('.youtube.com/api/stats/')) { // /api/stats/
  779. if (turl.includes('.youtube.com/api/stats/qoe?')) {
  780. skip = true;
  781. } else if (turl.includes('.youtube.com/api/stats/ads?')) {
  782. skip = true;
  783. } else {
  784. // skip = true; // for user activity logging e.g. watched videos
  785. }
  786. } else if (turl.includes('play.google.com/log')) {
  787. skip = true;
  788. } else if (turl.includes('.youtube.com//?')) { // //?cpn=
  789. skip = true;
  790. }
  791. }
  792. if (!skip) {
  793. this.__xmMc8__ = 1;
  794. return super.open(method, url, ...args);
  795. } else {
  796. this.__xmMc8__ = 2;
  797. return super.open('GET', url0);
  798. }
  799. }
  800. send(...args) {
  801. if (this.__xmMc8__ === 1) {
  802. return super.send(...args);
  803. } else if (this.__xmMc8__ === 2) {
  804. return super.send();
  805. } else {
  806. console.log('[yt-js-engine-tamer]', 'xhr warning');
  807. return super.send(...args);
  808. }
  809. }
  810. }
  811. c.prototype.__xmMc8__ = 0;
  812. prototypeInherit(c.prototype, XMLHttpRequest_.prototype);
  813. return c;
  814. })();
  815. }
  816.  
  817. // Alternative HACK -> Tabview Youtube
  818. if (DISABLE_COOLDOWN_SCROLLING && typeof EventTarget.prototype.addEventListener52178 !== 'function' && typeof EventTarget.prototype.addEventListener === 'function') {
  819.  
  820. // ---- << this.overscrollConfig HACK >> -----
  821.  
  822. // 2024.04.19 - Playlist in Single Column Mode cannot be scrolled correctly.
  823.  
  824. /*
  825.  
  826. ;function gZb(a, b) {
  827. b = void 0 === b ? !0 : b;
  828. a.addEventListener("wheel", hZb);
  829. a.overscrollConfig = {
  830. cooldown: b
  831. }
  832. }
  833. function iZb(a) {
  834. a.overscrollConfig = void 0;
  835. a.removeEventListener("wheel", hZb)
  836. }
  837. function hZb(a) {
  838. var b = a.deltaY
  839. , c = a.target
  840. , d = null;
  841. if (window.Polymer && window.Polymer.Element) {
  842. if (c = a.path || a.composedPath && a.composedPath()) {
  843. c = g(c);
  844. for (var e = c.next(); !e.done && (e = e.value,
  845. !jZb(e, b)); e = c.next())
  846. if (e.overscrollConfig) {
  847. d = e;
  848. break
  849. }
  850. }
  851. } else
  852. for (; c && !jZb(c, b); ) {
  853. if (c.overscrollConfig) {
  854. d = c;
  855. break
  856. }
  857. c = c.parentElement
  858. }
  859. d && (b = d.overscrollConfig,
  860. b.cooldown ? (d = a.deltaY,
  861. c = b.lastDeltaY || 0,
  862. b.lastDeltaY = d,
  863. e = b.lastStopped || 0,
  864. c && e && 0 < c == 0 < d ? Math.abs(c) >= Math.abs(d) ? (d = e + 1200,
  865. c = !1) : (d = e + 600,
  866. c = !0) : (d = Date.now() + 600,
  867. c = !0),
  868. d > Date.now() && (a.preventDefault(),
  869. c && (b.lastStopped = Date.now()))) : a.preventDefault())
  870. }
  871. */
  872.  
  873. let wheelHandler = function (a) {
  874. if (window.Polymer && window.Polymer.Element) {
  875. let c;
  876. if (c = a.path || a.composedPath && a.composedPath()) {
  877. for (const e of c) {
  878. const cnt = insp(e);
  879. if (e.overscrollConfig) e.overscrollConfig = void 0;
  880. if (cnt.overscrollConfig) cnt.overscrollConfig = void 0;
  881. }
  882. }
  883. } else {
  884. let e = a.target;
  885. for (; e instanceof Element; e = e.parentElement) {
  886. const cnt = insp(e);
  887. if (e.overscrollConfig) e.overscrollConfig = void 0;
  888. if (cnt.overscrollConfig) cnt.overscrollConfig = void 0;
  889. }
  890. }
  891. };
  892.  
  893. let checkWheelListenerObjs = null;
  894.  
  895. let getObjsFn = () => {
  896. let euyVal = 0;
  897. const eukElm = {};
  898. Object.setPrototypeOf(eukElm, HTMLElement.prototype);
  899. const euzObj = new Proxy(eukElm, {
  900. get(target, prop) {
  901. throw `ErrorF31.get(${prop})`
  902. },
  903. set(target, prop, value) {
  904. throw `ErrorF33.set(${prop}, ${value})`
  905. }
  906. });
  907. const euxElm = new Proxy(eukElm, {
  908. get(target, prop) {
  909. if (prop === 'scrollTop') {
  910. euyVal = euyVal | 8;
  911. return 0;
  912. }
  913. if (prop === 'overscrollConfig') {
  914. euyVal = euyVal | 16;
  915. return void 0;
  916. }
  917. if (prop === 'scrollHeight' || prop === 'clientHeight' || prop === 'offsetHeight') {
  918. return 640;
  919. }
  920. if (prop === 'scrollLeft') {
  921. euyVal = euyVal | 8;
  922. return 0;
  923. }
  924. if (prop === 'scrollWidth' || prop === 'clientWidth' || prop === 'offsetWidth') {
  925. return 800;
  926. }
  927. throw `ErrorF45.get(${prop})`
  928. },
  929. set(target, prop, value) {
  930. throw `ErrorF47.set(${prop}, ${value})`
  931. }
  932. });
  933. const eukEvt = {};
  934. Object.setPrototypeOf(eukEvt, WheelEvent.prototype);
  935. const euyEvt = new Proxy(eukEvt, {
  936. get(target, prop) {
  937. if (prop === 'deltaY' || prop === 'deltaX') {
  938. euyVal = euyVal | 1;
  939. return -999;
  940. }
  941. if (prop === 'target') {
  942. euyVal = euyVal | 2;
  943. return euxElm
  944. }
  945. if (prop === 'path' || prop === 'composedPath') {
  946. euyVal = euyVal | 2;
  947. return [euxElm]
  948. }
  949. throw `ErrorF51.get(${prop})`
  950. },
  951. set(target, prop, value) {
  952. throw `ErrorF53.set(${prop}, ${value})`
  953. }
  954. });
  955. const setVal = (v) => {
  956. euyVal = v;
  957. }
  958. const getVal = () => {
  959. return euyVal;
  960. }
  961. return { euzObj, euyEvt, setVal, getVal };
  962. }
  963.  
  964. let checkWheelListener = (callback) => {
  965.  
  966. let callbackIdentifier = '';
  967.  
  968. let res = null;
  969. try {
  970. const { euzObj, euyEvt, getVal, setVal } = checkWheelListenerObjs || (checkWheelListenerObjs = getObjsFn());
  971. setVal(0);
  972. if (callback.call(euzObj, euyEvt) !== void 0) throw 'ErrorF99';
  973. throw `RESULT${getVal()}`;
  974. } catch (e) {
  975. res = e;
  976. }
  977.  
  978. res = `${res}` || `${null}`;
  979. if (res.length > 20) res = `${res.substring(0, 20)}...`;
  980.  
  981. callbackIdentifier = res;
  982. if (callbackIdentifier === 'RESULT27') 0;
  983. else if (callbackIdentifier === 'RESULT0') {
  984. // a.isSearch && !a.disableWheelScroll && B("desktop_enable_dmpanel_wheel_scroll")
  985. } else if (callbackIdentifier.startsWith('RESULT')) {
  986. console.log('wheel eventListener - RESULT', callbackIdentifier, callback)
  987. }
  988. return callbackIdentifier;
  989.  
  990. };
  991.  
  992. let callbackFound = false;
  993. EventTarget.prototype.addEventListener52178 = EventTarget.prototype.addEventListener;
  994. EventTarget.prototype.addEventListener = function (type, callback, option = void 0) {
  995. // M-youtube-js-engine-tamer.52178
  996. if (type === 'wheel' && !option && typeof callback === 'function' && callback.length === 1) {
  997. // (( match with signature `a.addEventListener("wheel", hZb);` )) [subject to further review]
  998. const callbackIdentifier = callback.yaujmoms || (callbackFound ? 'IGNORE' : (callback.yaujmoms = checkWheelListener(callback)));
  999. // RESULTXX / ErrorFXX / Other...
  1000. if (callbackIdentifier === 'RESULT27') {
  1001. this.overscrollConfigDisable = true;
  1002. if (!callbackFound) {
  1003. callbackFound = true; // suppose only one function is assigned to overscrollConfig cooldown [no function binding]
  1004. getObjsFn = checkWheelListener = null;
  1005. checkWheelListenerObjs = null;
  1006. wheelHandler = null;
  1007. }
  1008. return void 0;
  1009. } else if (!callbackFound && !this.overscrollConfigDisable) {
  1010. this.overscrollConfigDisable = true;
  1011. this.addEventListener52178('wheel', wheelHandler, { passive: false });
  1012. }
  1013. }
  1014. return this.addEventListener52178(type, callback, option);
  1015. };
  1016.  
  1017. // ---- << this.overscrollConfig HACK >> -----
  1018.  
  1019. }
  1020.  
  1021. const { pageMediaWatcher, shortcutKeysFixer, keyboardController } = (() => {
  1022.  
  1023. let p_a_objWR = null;
  1024. let isSpaceKeyImmediate = false; // for ADVANCED_FIX_SHORTCUTKEYS
  1025. let ytPageReady = 0;
  1026.  
  1027. let isSpeedMastSpacebarControlEnabled = false; // youtube experimental feature // can be forced by CHANGE_SPEEDMASTER_SPACEBAR_CONTROL
  1028. let isGlobalSpaceControl = true;
  1029. let mediaPlayerElementWR = null;
  1030. let focusedElementAtSelection = null;
  1031.  
  1032. // let want_control_video = false;
  1033.  
  1034. let spaceBarControl_keyG = '';
  1035.  
  1036. let lastUserAction = 0;
  1037.  
  1038. const wmKeyControlPhase = new WeakMap();
  1039.  
  1040. let currentSelectionText = null;
  1041.  
  1042. const getCurrentSelectionText = () => {
  1043. if (currentSelectionText !== null) return currentSelectionText
  1044. return (currentSelectionText = getSelection() + "")
  1045. }
  1046.  
  1047. const pageMediaWatcher = () => {
  1048.  
  1049. // CAN_TUNE_VOLUMN_AFTER_RESUME_OR_PAUSE && document.addEventListener('wheel', () => {
  1050. // want_control_video = false;
  1051. // }, { capture: true, passive: true });
  1052.  
  1053. document.addEventListener('yt-navigate', () => {
  1054. ytPageReady = 0;
  1055. });
  1056. document.addEventListener('yt-navigate-start', () => {
  1057. ytPageReady = 0;
  1058. });
  1059. document.addEventListener('yt-navigate-cache', () => {
  1060. ytPageReady = 0;
  1061. });
  1062.  
  1063. document.addEventListener('yt-navigate-finish', () => {
  1064. ytPageReady = 1;
  1065. });
  1066.  
  1067. document.addEventListener('durationchange', () => {
  1068. for (const elm of document.querySelectorAll('#movie_player video[src], #movie_player audio[src]')) {
  1069. if (elm.duration > 0.01) {
  1070. if (elm.closest('[hidden]')) continue;
  1071. mediaPlayerElementWR = mWeakRef(elm);
  1072. return;
  1073. }
  1074. }
  1075. }, { capture: true, passive: true });
  1076.  
  1077. document.addEventListener('selectionchange', (evt) => {
  1078. if (!evt || !evt.isTrusted || !(evt instanceof Event)) return;
  1079. currentSelectionText = null;
  1080. if (!(evt.target instanceof Node)) return;
  1081. focusedElementAtSelection = evt.target;
  1082. }, { capture: true, passive: true })
  1083.  
  1084. document.addEventListener('pointerdown', (evt) => {
  1085. if (evt.isTrusted && evt instanceof Event) lastUserAction = Date.now();
  1086. }, { capture: true, passive: true });
  1087.  
  1088.  
  1089. document.addEventListener('pointerup', (evt) => {
  1090. if (evt.isTrusted && evt instanceof Event) lastUserAction = Date.now();
  1091. }, { capture: true, passive: true });
  1092.  
  1093.  
  1094. document.addEventListener('keydown', (evt) => {
  1095. if (evt.isTrusted && evt instanceof Event) lastUserAction = Date.now();
  1096. }, { capture: true, passive: true });
  1097.  
  1098. document.addEventListener('keyup', (evt) => {
  1099. if (evt.isTrusted && evt instanceof Event) lastUserAction = Date.now();
  1100. }, { capture: true, passive: true });
  1101.  
  1102. };
  1103.  
  1104.  
  1105. const checkKeyB = (p_a_obj) => {
  1106.  
  1107. const boolList = new Set();
  1108. const p_a_obj_api = p_a_obj.api;
  1109.  
  1110. const nilFunc0 = function () {
  1111. return void 0
  1112. };
  1113. const mt = new Proxy({}, {
  1114. get(target, prop) {
  1115. if (prop === 'get') return nilFunc0;
  1116. return mt;
  1117. }
  1118. });
  1119. const nilFunc = function () {
  1120. return mt
  1121. };
  1122. const mw = new Proxy({}, {
  1123. get(target, prop) {
  1124. if (prop in p_a_obj_api) {
  1125. if (typeof p_a_obj_api.constructor.prototype[prop] === 'function') return nilFunc;
  1126. let q = Object.getOwnPropertyDescriptor(p_a_obj_api, prop);
  1127. if (q && q.value) {
  1128. if (!q.writable) return q.value;
  1129. if (typeof q.value === 'string') return '';
  1130. if (typeof q.value === 'number') return 0;
  1131. if (typeof q.value === 'boolean') return false;
  1132. if (q.value && typeof q.value === 'object') return {};
  1133. }
  1134. }
  1135. return undefined;
  1136. },
  1137. set(target, prop) {
  1138. throw 'mwSet';
  1139. }
  1140. });
  1141.  
  1142. const mq = new Proxy({}, {
  1143. get(target, prop) {
  1144. if (prop === 'api') return mw;
  1145. if (prop in p_a_obj) {
  1146. if (typeof p_a_obj.constructor.prototype[prop] === 'function') return nilFunc;
  1147. let q = Object.getOwnPropertyDescriptor(p_a_obj, prop);
  1148. if (q && q.value) {
  1149. if (!q.writable) return q.value;
  1150. if (typeof q.value === 'string') return '';
  1151. if (typeof q.value === 'number') return 0;
  1152. if (typeof q.value === 'boolean') return false;
  1153. if (q.value && typeof q.value === 'object') return {};
  1154. }
  1155. }
  1156. return undefined;
  1157. },
  1158. set(target, prop, val) {
  1159. if (typeof val === 'boolean') boolList.add(prop)
  1160. throw `mqSet(${prop},${val})`;
  1161. }
  1162. });
  1163.  
  1164. let res = ''
  1165. try {
  1166. res = `RESULT::${p_a_obj.handleGlobalKeyUp.call(mq, 9, false, false, false, false, "Tab", "Tab")}`;
  1167. } catch (e) {
  1168. res = `ERROR::${e}`;
  1169. }
  1170.  
  1171. if (boolList.size === 1) {
  1172. const value = boolList.values().next().value;
  1173. if (res === `ERROR::mqSet(${value},${true})`) {
  1174. p_a_obj.__uZWaD__ = value;
  1175. }
  1176. }
  1177.  
  1178. console.log('[yt-js-engine-tamer] global shortcut control', { '__uZWaD__': p_a_obj.__uZWaD__ });
  1179.  
  1180. }
  1181.  
  1182.  
  1183. let pm_p_a = null;
  1184.  
  1185. const p_a_init = function () {
  1186. const r = this.init91();
  1187. const keyBw = this.__cPzfo__ || '__NIL__';
  1188. const p_a_obj = this[keyBw];
  1189. if (!p_a_obj) return;
  1190. try {
  1191. checkKeyB(p_a_obj);
  1192. } catch (e) { }
  1193. p_a_objWR = mWeakRef(p_a_obj);
  1194. if (FIX_SHORTCUTKEYS > 0) {
  1195. if (p_a_obj && !p_a_obj.hVhtg) {
  1196. p_a_obj.hVhtg = 1;
  1197.  
  1198. p_a_obj.handleGlobalKeyUp91 = p_a_obj.handleGlobalKeyUp;
  1199. p_a_obj.handleGlobalKeyUp = p_a_xt.handleGlobalKeyUp;
  1200. p_a_obj.handleGlobalKeyDown91 = p_a_obj.handleGlobalKeyDown;
  1201. p_a_obj.handleGlobalKeyDown = p_a_xt.handleGlobalKeyDown;
  1202. p_a_obj.__handleGlobalKeyBefore__ = p_a_xt.__handleGlobalKeyBefore__;
  1203. p_a_obj.__handleGlobalKeyAfter__ = p_a_xt.__handleGlobalKeyAfter__;
  1204.  
  1205. }
  1206. // if (CAN_TUNE_VOLUMN_AFTER_RESUME_OR_PAUSE && p_a_obj && p_a_obj.api && !p_a_obj.api.hVhtg) {
  1207. // const api = p_a_obj.api
  1208. // api.hVhtg = 1;
  1209. // api.playVideo91 = api.playVideo;
  1210. // api.playVideo = p_a_jt.playVideo;
  1211. // api.pauseVideo91 = api.pauseVideo;
  1212. // api.pauseVideo = p_a_jt.pauseVideo;
  1213. // }
  1214. }
  1215. if (pm_p_a) {
  1216. pm_p_a.resolve();
  1217. pm_p_a = null;
  1218. }
  1219. return r;
  1220. };
  1221.  
  1222. const p_a_xt = {
  1223.  
  1224. __handleGlobalKeyBefore__(a, b, c, d, e, f, h, activeElement) {
  1225.  
  1226. if (FIX_SHORTCUTKEYS === 2) {
  1227.  
  1228. // if (flagSpeedMaster !== false && !getGlobalSpacebarControlFlag()) return false;
  1229.  
  1230. if (activeElement) {
  1231.  
  1232. const controlPhaseCache = wmKeyControlPhase.get(activeElement);
  1233.  
  1234. if (controlPhaseCache === 6 && getCurrentSelectionText() !== "") void 0;
  1235. else if (controlPhaseCache === 1 || controlPhaseCache === 2 || controlPhaseCache === 5) return false;
  1236. else if ((controlPhaseCache !== 6 || focusedElementAtSelection === document.activeElement) && getCurrentSelectionText() !== "") return false;
  1237.  
  1238. }
  1239.  
  1240. const isSpaceBar = a === 32 && b === false && c === false && d === false && e === false && f === ' ' && h === 'Space';
  1241. const isDelayedSpaceBar = FIX_SHORTCUTKEYS === 2 && isSpaceBar && !isSpaceKeyImmediate && (isSpeedMastSpacebarControlEnabled = getSpeedMasterControlFlag());
  1242. // console.log(582, isDelayedSpaceBar)
  1243. if (isDelayedSpaceBar) return void 0; // accept delay spacebar under isSpeedMastSpacebarControlEnabled (no rejection)
  1244.  
  1245. if (activeElement && (h === 'Space' || h === 'Enter')) {
  1246. const controlPhase = wmKeyControlPhase.get(activeElement);
  1247. if (controlPhase === 4 || controlPhase === 5) return false;
  1248. }
  1249. if (focusedElementAtSelection === activeElement && getCurrentSelectionText() !== "") return false;
  1250. // if (!isSpeedMastSpacebarControlEnabled && a === 32 && b === false && c === false && d === false && e === false && f === ' ' && h === 'Space') {
  1251. // if (!isSpaceKeyImmediate) return false;
  1252. // }
  1253. }
  1254.  
  1255. },
  1256.  
  1257. __handleGlobalKeyAfter__(a, b, c, d, e, f, h, activeElement, ret) {
  1258.  
  1259. if (FIX_SHORTCUTKEYS === 2 && ret && a >= 32 && ytPageReady === 1 && Date.now() - lastUserAction < 40 && activeElement === document.activeElement) {
  1260.  
  1261. const isSpaceBar = a === 32 && b === false && c === false && d === false && e === false && f === ' ' && h === 'Space';
  1262. const isDelayedSpaceBar = FIX_SHORTCUTKEYS === 2 && isSpaceBar && !isSpaceKeyImmediate && (isSpeedMastSpacebarControlEnabled = getSpeedMasterControlFlag());
  1263. // console.log(583, isDelayedSpaceBar)
  1264. if (isDelayedSpaceBar) return void 0; // accept delay spacebar under isSpeedMastSpacebarControlEnabled (no rejection)
  1265.  
  1266. const mediaPlayerElement = kRef(mediaPlayerElementWR);
  1267.  
  1268. let mediaWorking = false;
  1269. if (mediaPlayerElement && (mediaPlayerElement.readyState === 4 || mediaPlayerElement.readyState === 1) && mediaPlayerElement.networkState === 2 && mediaPlayerElement.duration > 0.01) {
  1270. mediaWorking = true;
  1271. } else if (mediaPlayerElement && !mediaPlayerElement.paused && !mediaPlayerElement.muted && mediaPlayerElement.duration > 0.01) {
  1272. mediaWorking = true;
  1273. }
  1274. // console.log(182, mediaWorking, mediaPlayerElement.readyState , mediaPlayerElement.networkState)
  1275. mediaWorking && Promise.resolve().then(() => {
  1276. if (activeElement === document.activeElement) {
  1277. return activeElement.blur()
  1278. } else {
  1279. return false
  1280. }
  1281. }).then((r) => {
  1282. r !== false && mediaPlayerElement.focus();
  1283. });
  1284. }
  1285. },
  1286.  
  1287.  
  1288. handleGlobalKeyUp(a, b, c, d, e, f, h) {
  1289.  
  1290. if (BY_PASS_KEYBOARD_CONTROL) return this.handleGlobalKeyUp91(a, b, c, d, e, f, h);
  1291.  
  1292. const activeElement = document.activeElement;
  1293.  
  1294. const allow = typeof this.__handleGlobalKeyBefore__ === 'function' ? this.__handleGlobalKeyBefore__(a, b, c, d, e, f, h, activeElement) : void 0;
  1295. if (allow === false) return false;
  1296.  
  1297. const ret = this.handleGlobalKeyUp91(a, b, c, d, e, f, h);
  1298. // console.log('handleGlobalKeyUp',ret, a, b, c, d, e, f, h);
  1299.  
  1300. typeof this.__handleGlobalKeyAfter__ === 'function' && this.__handleGlobalKeyAfter__(a, b, c, d, e, f, h, activeElement, ret);
  1301.  
  1302. return ret;
  1303. },
  1304. handleGlobalKeyDown(a, b, c, d, e, f, h, l) {
  1305.  
  1306.  
  1307. if (BY_PASS_KEYBOARD_CONTROL) return this.handleGlobalKeyDown91(a, b, c, d, e, f, h, l);
  1308.  
  1309. const activeElement = document.activeElement;
  1310. // if (a === 32 && b === false && c === false && d === false && e === false && f === ' ' && h === 'Space' && !(isSpeedMastSpacebarControlEnabled = getSpeedMasterControlFlag())) {
  1311. // return this.handleGlobalKeyDown91(a, b, c, d, e, f, h, l);
  1312. // }
  1313. const allow = typeof this.__handleGlobalKeyBefore__ === 'function' ? this.__handleGlobalKeyBefore__(a, b, c, d, e, f, h, activeElement) : void 0;
  1314. if (allow === false) return false;
  1315.  
  1316. const ret = this.handleGlobalKeyDown91(a, b, c, d, e, f, h, l);
  1317. // console.log('handleGlobalKeyDown',ret, a, b, c, d, e, f, h,l)
  1318.  
  1319. typeof this.__handleGlobalKeyAfter__ === 'function' && this.__handleGlobalKeyAfter__(a, b, c, d, e, f, h, activeElement, ret);
  1320.  
  1321. return ret;
  1322. }
  1323.  
  1324. };
  1325.  
  1326. // const p_a_jt = { // API
  1327.  
  1328. // playVideo(a) { // without spinner effect
  1329.  
  1330. // if (CAN_TUNE_VOLUMN_AFTER_RESUME_OR_PAUSE) {
  1331.  
  1332. // const mediaPlayerElement = kRef(mediaPlayerElementWR);
  1333. // if (mediaPlayerElement && !mediaPlayerElement.paused && !mediaPlayerElement.muted && mediaPlayerElement.duration > 0.01) {
  1334. // want_control_video = true;
  1335. // // Promise.resolve().then(()=> mediaPlayerElement.focus() );
  1336. // }
  1337.  
  1338. // }
  1339. // return this.playVideo91(a);
  1340.  
  1341. // },
  1342.  
  1343. // pauseVideo(a) { // without spinner effect
  1344.  
  1345. // if (CAN_TUNE_VOLUMN_AFTER_RESUME_OR_PAUSE) {
  1346.  
  1347. // const mediaPlayerElement = kRef(mediaPlayerElementWR);
  1348. // if (mediaPlayerElement && mediaPlayerElement.paused && !mediaPlayerElement.muted && mediaPlayerElement.duration > 0.01) {
  1349. // want_control_video = true;
  1350. // // Promise.resolve().then(()=> mediaPlayerElement.focus() );
  1351. // }
  1352.  
  1353. // }
  1354. // return this.pauseVideo91(a);
  1355.  
  1356. // }
  1357. // };
  1358.  
  1359. let flagSpeedMaster = null;
  1360. const getSpeedMasterControlFlag = () => {
  1361.  
  1362. const config = (win.yt || 0).config_ || (win.ytcfg || 0).data_ || 0;
  1363. isSpeedMastSpacebarControlEnabled = false;
  1364. if (config && config.EXPERIMENT_FLAGS && config.EXPERIMENT_FLAGS.web_speedmaster_spacebar_control) {
  1365. isSpeedMastSpacebarControlEnabled = true;
  1366. }
  1367. if (config && config.EXPERIMENTS_FORCED_FLAGS && config.EXPERIMENTS_FORCED_FLAGS.web_speedmaster_spacebar_control) {
  1368. isSpeedMastSpacebarControlEnabled = true;
  1369. }
  1370.  
  1371. if (flagSpeedMaster === null) {
  1372. const p = (((config || 0).WEB_PLAYER_CONTEXT_CONFIGS || 0).WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH || 0).serializedExperimentFlags;
  1373. if (!p) {
  1374. flagSpeedMaster = false;
  1375. } else {
  1376.  
  1377. flagSpeedMaster = (p.includes('web_enable_speedmaster=true') && p.includes('web_speedmaster_spacebar_control=true') && p.includes('web_speedmaster_updated_edu=true'));
  1378.  
  1379. }
  1380.  
  1381. }
  1382. if (!flagSpeedMaster) isSpeedMastSpacebarControlEnabled = false;
  1383.  
  1384. return isSpeedMastSpacebarControlEnabled;
  1385. }
  1386.  
  1387.  
  1388. const getGlobalSpacebarControlFlag = () => {
  1389.  
  1390. const config = (win.yt || 0).config_ || (win.ytcfg || 0).data_ || 0;
  1391. isGlobalSpaceControl = false;
  1392. if (config && config.EXPERIMENT_FLAGS && config.EXPERIMENT_FLAGS.global_spacebar_pause) {
  1393. isGlobalSpaceControl = true;
  1394. }
  1395. if (config && config.EXPERIMENTS_FORCED_FLAGS && config.EXPERIMENTS_FORCED_FLAGS.global_spacebar_pause) {
  1396. isGlobalSpaceControl = true;
  1397. }
  1398.  
  1399. return isGlobalSpaceControl;
  1400. }
  1401.  
  1402. const keyboardController = async (_yt_player) => {
  1403.  
  1404. const keyQT = getQT(_yt_player);
  1405. const keySV = getSV(_yt_player);
  1406. const keyDX = getDX(_yt_player);
  1407. console.log(`[QT,SV,DX]`, [keyQT, keySV, keyDX]);
  1408.  
  1409. if (!keyDX) return;
  1410. if (keyDX === keyQT || keyDX === keySV) return;
  1411.  
  1412. if (typeof keyDX !== 'string') return;
  1413.  
  1414. let lastAccessKey = '';
  1415. let lastAccessKeyConfirmed = '';
  1416. const mb = new Proxy({}, {
  1417. get(target, prop) {
  1418. if (prop === 'handleGlobalKeyUp') lastAccessKeyConfirmed = lastAccessKey;
  1419. throw 'mbGet'
  1420. },
  1421. set(target, prop, val) {
  1422. throw 'mbSet'
  1423. }
  1424. });
  1425. const ma = new Proxy({}, {
  1426. get(target, prop) {
  1427. lastAccessKey = prop;
  1428. return mb
  1429. },
  1430. set(target, prop, val) {
  1431. throw 'maSet'
  1432. }
  1433. });
  1434.  
  1435. let keyBw = '';
  1436. try {
  1437. _yt_player[keyDX].prototype.handleGlobalKeyUp.call(ma);
  1438. } catch (e) {
  1439. if (e === 'mbGet' && typeof lastAccessKeyConfirmed === 'string' && lastAccessKeyConfirmed.length > 0) {
  1440. keyBw = lastAccessKeyConfirmed;
  1441. }
  1442. }
  1443.  
  1444. if (!keyBw) return;
  1445.  
  1446. if (typeof _yt_player[keyDX].prototype.init !== 'function' || _yt_player[keyDX].prototype.init.length !== 0) return;
  1447.  
  1448. pm_p_a = new PromiseExternal();
  1449.  
  1450. _yt_player[keyDX].prototype.__cPzfo__ = keyBw;
  1451.  
  1452. _yt_player[keyDX].prototype.init91 = _yt_player[keyDX].prototype.init;
  1453.  
  1454. _yt_player[keyDX].prototype.init = p_a_init;
  1455.  
  1456. await pm_p_a.then();
  1457. const p_a_obj = kRef(p_a_objWR);
  1458.  
  1459. const isSpeedMastSpacebarControlEnabledA = getSpeedMasterControlFlag();
  1460.  
  1461.  
  1462. if (CHANGE_SPEEDMASTER_SPACEBAR_CONTROL > 0) {
  1463.  
  1464. isSpeedMastSpacebarControlEnabled = CHANGE_SPEEDMASTER_SPACEBAR_CONTROL == 1;
  1465.  
  1466. if (!isSpeedMastSpacebarControlEnabled) {
  1467.  
  1468. if (config && config.EXPERIMENT_FLAGS) {
  1469. config.EXPERIMENT_FLAGS.web_speedmaster_spacebar_control = false;
  1470. }
  1471. if (config && config.EXPERIMENTS_FORCED_FLAGS) {
  1472. config.EXPERIMENTS_FORCED_FLAGS.web_speedmaster_spacebar_control = false;
  1473. }
  1474.  
  1475. } else {
  1476.  
  1477. if (config && config.EXPERIMENT_FLAGS) {
  1478. config.EXPERIMENT_FLAGS.web_speedmaster_spacebar_control = true;
  1479. }
  1480. if (config && config.EXPERIMENTS_FORCED_FLAGS) {
  1481. config.EXPERIMENTS_FORCED_FLAGS.web_speedmaster_spacebar_control = true;
  1482. }
  1483.  
  1484. }
  1485.  
  1486. }
  1487.  
  1488. const isSpeedMastSpacebarControlEnabledB = getSpeedMasterControlFlag();
  1489.  
  1490.  
  1491.  
  1492.  
  1493. console.log('[yt-js-engine-tamer] speedmaster by space (yt setting)', isSpeedMastSpacebarControlEnabledA, isSpeedMastSpacebarControlEnabledB);
  1494.  
  1495. // console.log(p_a_obj.handleGlobalKeyUp)
  1496. console.log('[yt-js-engine-tamer] p_a', p_a_obj)
  1497.  
  1498. // console.log(p_a_obj.api)
  1499.  
  1500.  
  1501. // QT -> DX(SV) -> p_a
  1502.  
  1503.  
  1504. /*
  1505. *
  1506. *
  1507. g.k.handleGlobalKeyUp = function(a, b, c, d, e, f, h) {
  1508. b = void 0 === b ? !1 : b;
  1509. c = void 0 === c ? !1 : c;
  1510. d = void 0 === d ? !1 : d;
  1511. e = void 0 === e ? !1 : e;
  1512. var l = g.PT(this);
  1513. l && l.handleGlobalKeyUp(a, b, c, d, e, f, h)
  1514. }
  1515.  
  1516. */
  1517.  
  1518. /*
  1519. *
  1520. *
  1521. *
  1522. g.k.handleGlobalKeyUp = function(a, b, c, d, e, f, h) {
  1523. return this.Bw ? this.Bw.handleGlobalKeyUp(a, b, c, d, e, f, h) : !1
  1524. }
  1525.  
  1526. */
  1527.  
  1528.  
  1529. // if(!keyDX) return;
  1530.  
  1531. // console.log(4999, keyDX)
  1532.  
  1533. };
  1534.  
  1535.  
  1536. const ytResumeFn = function () { // ADVANCED_FIX_SHORTCUTKEYS
  1537.  
  1538. const p_a_obj = kRef(p_a_objWR);
  1539. // const api = p_a_obj.api;
  1540.  
  1541.  
  1542. // console.log(540);
  1543.  
  1544. let boolList = null;
  1545. let ret;
  1546. isSpaceKeyImmediate = true;
  1547. try {
  1548.  
  1549. ret = 0;
  1550. ret = ret | (p_a_obj.handleGlobalKeyDown(32, false, false, false, false, ' ', 'Space', false) ? 1 : 0);
  1551. let p_a_objT;
  1552. if (!spaceBarControl_keyG) { // just in case
  1553. boolList = new Set();
  1554. p_a_objT = new Proxy(p_a_obj, {
  1555. get(target, prop, handler) {
  1556. const val = target[prop];
  1557. if (typeof val !== 'boolean') return val;
  1558. boolList.add(prop);
  1559. // console.log(555, prop, val);
  1560. if (typeof prop === 'string' && prop.length <= 3 && val === true && boolList.length === 1) {
  1561. spaceBarControl_keyG = prop;
  1562. p_a_obj.__uZWaD__ = spaceBarControl_keyG;
  1563. val = false;
  1564. }
  1565. return val;
  1566. }
  1567. });
  1568.  
  1569.  
  1570. } else if (p_a_obj[spaceBarControl_keyG] === true) {
  1571. p_a_obj[spaceBarControl_keyG] = false;
  1572. p_a_objT = p_a_obj;
  1573. // console.log(p_a_obj, spaceBarControl_keyG, p_a_obj[spaceBarControl_keyG] )
  1574. } else {
  1575.  
  1576. p_a_objT = p_a_obj;
  1577. }
  1578.  
  1579. ret = ret | (p_a_objT.handleGlobalKeyUp(32, false, false, false, false, ' ', 'Space') ? 2 : 0);
  1580.  
  1581.  
  1582. } catch (e) {
  1583. console.log(e)
  1584. }
  1585. isSpaceKeyImmediate = false;
  1586.  
  1587. if (boolList && boolList.size === 1) {
  1588. const value = boolList.values().next().value;
  1589. spaceBarControl_keyG = value;
  1590. p_a_obj.__uZWaD__ = spaceBarControl_keyG;
  1591.  
  1592. }
  1593.  
  1594. if (spaceBarControl_keyG && p_a_obj[spaceBarControl_keyG] === true) p_a_obj[spaceBarControl_keyG] = false;
  1595.  
  1596. return ret;
  1597. }
  1598.  
  1599. const shortcutKeysFixer = () => {
  1600.  
  1601. let pausePromiseControlJ = 0;
  1602.  
  1603.  
  1604. const obtainCurrentControlPhase = (evt, mediaPlayerElement) => {
  1605.  
  1606. let controlPhase = 0;
  1607. const aElm = document.activeElement;
  1608.  
  1609. if (aElm) {
  1610.  
  1611. const controlPhaseCache = wmKeyControlPhase.get(aElm);
  1612.  
  1613. if (typeof controlPhaseCache === 'number') {
  1614.  
  1615. controlPhase = controlPhaseCache;
  1616. } else {
  1617.  
  1618. if (aElm instanceof HTMLInputElement) controlPhase = 1;
  1619. else if (aElm instanceof HTMLTextAreaElement) controlPhase = 1;
  1620. else if (aElm instanceof HTMLButtonElement) controlPhase = 2;
  1621. else if (aElm instanceof HTMLIFrameElement) controlPhase = 2;
  1622. else if (aElm instanceof HTMLImageElement) controlPhase = 2;
  1623. else if (aElm instanceof HTMLEmbedElement) controlPhase = 2;
  1624. else {
  1625. if (aElm instanceof HTMLElement && aElm.closest('[role]')) controlPhase = 5;
  1626. if (aElm instanceof HTMLDivElement) controlPhase = 2;
  1627. else if (aElm instanceof HTMLAnchorElement) controlPhase = 2;
  1628. else if (!(aElm instanceof HTMLElement) && (aElm instanceof Element)) controlPhase = 2; // svg
  1629. }
  1630.  
  1631. if ((controlPhase === 2 || controlPhase === 5) && (aElm instanceof HTMLElement) && aElm.contains(mediaPlayerElement)) {
  1632. controlPhase = 0;
  1633. }
  1634.  
  1635. if ((controlPhase === 2 || controlPhase === 5) && evt && evt.target && evt.target === aElm) {
  1636. if (aElm.closest('[contenteditable], input, textarea')) {
  1637. controlPhase = 5;
  1638. } else if (aElm.closest('button')) {
  1639. controlPhase = 4;
  1640. }
  1641. }
  1642.  
  1643. if (aElm.closest('#movie_player')) controlPhase = 6;
  1644.  
  1645. wmKeyControlPhase.set(aElm, controlPhase);
  1646.  
  1647. }
  1648. }
  1649.  
  1650. return controlPhase;
  1651.  
  1652. }
  1653.  
  1654. const isStateControllable = (api) => {
  1655. let appState = null;
  1656. let playerState = null;
  1657. let adState = null;
  1658. try {
  1659. appState = api.getAppState();
  1660. playerState = api.getPlayerState();
  1661. adState = api.getAdState();
  1662. } catch (e) { }
  1663. // ignore playerState -1
  1664. return appState === 5 && adState === -1 && (playerState === 1 || playerState === 2 || playerState === 3);
  1665. };
  1666.  
  1667.  
  1668. const keyEventListener = (evt) => {
  1669. if (BY_PASS_KEYBOARD_CONTROL) return;
  1670.  
  1671. if (evt.isTrusted && evt instanceof Event) lastUserAction = Date.now();
  1672. if (isSpaceKeyImmediate || !evt.isTrusted || !(evt instanceof KeyboardEvent)) return;
  1673. if (!ytPageReady) return;
  1674.  
  1675. if (evt.defaultPrevented === true) return;
  1676.  
  1677. const p_a_obj = kRef(p_a_objWR);
  1678.  
  1679. if (!p_a_obj) return;
  1680.  
  1681.  
  1682. const mediaPlayerElement = kRef(mediaPlayerElementWR);
  1683. if (!mediaPlayerElement) return;
  1684.  
  1685. // let focusBodyIfSuccess = false;
  1686.  
  1687. const controlPhase = obtainCurrentControlPhase(evt, mediaPlayerElement);
  1688.  
  1689. if (controlPhase === 6 && getCurrentSelectionText() !== "") void 0;
  1690. else if (controlPhase === 1 || controlPhase === 2 || controlPhase === 5) return;
  1691. else if ((controlPhase !== 6 || focusedElementAtSelection === document.activeElement) && getCurrentSelectionText() !== "") return;
  1692.  
  1693.  
  1694. if (evt.code === 'Space' && !getGlobalSpacebarControlFlag()) return;
  1695.  
  1696. // console.log(`${evt.type}::controlPhase`,controlPhase)
  1697.  
  1698. // if (controlPhase == 4) {
  1699. // focusBodyIfSuccess = true;
  1700. // }
  1701.  
  1702. spaceBarControl_keyG = spaceBarControl_keyG || p_a_obj.__uZWaD__ || ''
  1703. if (spaceBarControl_keyG && p_a_obj[spaceBarControl_keyG] === true) p_a_obj[spaceBarControl_keyG] = false;
  1704.  
  1705. if (FIX_SHORTCUTKEYS < 2) return;
  1706. if (!(!evt.shiftKey && !evt.ctrlKey && !evt.altKey && !evt.metaKey)) return; // ignore if modifier key is pressed -> let other event listener to handle first
  1707.  
  1708. let rr;
  1709. const isSpaceBar = evt.code === 'Space' && !evt.shiftKey && !evt.ctrlKey && !evt.altKey && !evt.metaKey;
  1710.  
  1711.  
  1712.  
  1713. let useImprovedPauseResume = false;
  1714.  
  1715. if (USE_IMPROVED_PAUSERESUME_UNDER_NO_SPEEDMASTER && isSpaceBar && !(isSpeedMastSpacebarControlEnabled = getSpeedMasterControlFlag())) {
  1716.  
  1717. const api = p_a_obj.api;
  1718. const stateControllable = isStateControllable(api);
  1719. // console.log(2122, appState, playerState, adState)
  1720.  
  1721. if (stateControllable && location.pathname === '/watch' && mediaPlayerElement.duration > 0.01 && (mediaPlayerElement.readyState === 4 || mediaPlayerElement.readyState === 1) && mediaPlayerElement.networkState === 2) {
  1722.  
  1723. useImprovedPauseResume = true;
  1724.  
  1725. }
  1726.  
  1727.  
  1728. }
  1729.  
  1730.  
  1731. // force flag: CHANGE_SPEEDMASTER_SPACEBAR_CONTROL
  1732. if (evt.type === 'keydown') {
  1733.  
  1734. if (useImprovedPauseResume) {
  1735.  
  1736. const isPaused = mediaPlayerElement.paused;
  1737.  
  1738. const cj = ++pausePromiseControlJ;
  1739. Promise.resolve().then(() => {
  1740.  
  1741. if (cj !== pausePromiseControlJ) return;
  1742.  
  1743. if (mediaPlayerElement.paused !== isPaused) return;
  1744.  
  1745. const ret = ytResumeFn();
  1746. if (!ret) { // fallback
  1747. isPaused ? api.playVideo() : api.pauseVideo();
  1748. }
  1749.  
  1750. /*
  1751. let a = void 0;
  1752. console.log('Rb', api.Rb())
  1753. a = !window._yt_player.nL(api.Rb());
  1754. p_a_obj.Wd.kG(a)
  1755. a ? api.playVideo() : api.pauseVideo();
  1756.  
  1757. */
  1758.  
  1759.  
  1760. });
  1761. rr = true;
  1762. } else {
  1763.  
  1764. isSpaceKeyImmediate = true;
  1765. rr = p_a_obj.handleGlobalKeyDown(evt.keyCode, evt.shiftKey, evt.ctrlKey, evt.altKey, evt.metaKey, evt.key, evt.code, evt.repeat);
  1766. isSpaceKeyImmediate = false;
  1767. if (spaceBarControl_keyG && p_a_obj[spaceBarControl_keyG] === true) p_a_obj[spaceBarControl_keyG] = false;
  1768.  
  1769. }
  1770.  
  1771.  
  1772. } else if (evt.type === 'keyup') {
  1773.  
  1774. if (isSpaceBar && useImprovedPauseResume && !(isSpeedMastSpacebarControlEnabled = getSpeedMasterControlFlag())) {
  1775.  
  1776. rr = true;
  1777. } else {
  1778.  
  1779. isSpaceKeyImmediate = true;
  1780. rr = p_a_obj.handleGlobalKeyUp(evt.keyCode, evt.shiftKey, evt.ctrlKey, evt.altKey, evt.metaKey, evt.key, evt.code);
  1781. isSpaceKeyImmediate = false;
  1782. if (spaceBarControl_keyG && p_a_obj[spaceBarControl_keyG] === true) p_a_obj[spaceBarControl_keyG] = false;
  1783.  
  1784. }
  1785.  
  1786.  
  1787. /*
  1788.  
  1789. if (d)
  1790. switch (c) {
  1791. case 32:
  1792. case 13:
  1793. if ("BUTTON" === d.tagName || "A" === d.tagName || "INPUT" === d.tagName)
  1794. b = !0,
  1795. e = !1;
  1796. else if (e) {
  1797. var m = d.getAttribute("role");
  1798. !m || "option" !== m && "button" !== m && 0 !== m.indexOf("menuitem") || (b = !0,
  1799. d.click(),
  1800. f = !0)
  1801. }
  1802. break;
  1803. case 37:
  1804. case 39:
  1805. case 36:
  1806. case 35:
  1807. b = "slider" === d.getAttribute("role");
  1808. break;
  1809. case 38:
  1810. case 40:
  1811. m = d.getAttribute("role"),
  1812. d = 38 === c ? d.previousSibling : d.nextSibling,
  1813. "slider" === m ? b = !0 : e && ("option" === m ? (d && "option" === d.getAttribute("role") && d.focus(),
  1814. f = b = !0) : m && 0 === m.indexOf("menuitem") && (d && d.hasAttribute("role") && 0 === d.getAttribute("role").indexOf("menuitem") && d.focus(),
  1815. f = b = !0))
  1816. }
  1817. if (e && !f)
  1818. switch (c) {
  1819. case 38:
  1820. f = Math.min(this.api.getVolume() + 5, 100);
  1821. XV(this.Wd, f, !1);
  1822. this.api.setVolume(f);
  1823. h = f = !0;
  1824. break;
  1825. case 40:
  1826. f = Math.max(this.api.getVolume() - 5, 0);
  1827. XV(this.Wd, f, !0);
  1828. this.api.setVolume(f);
  1829. h = f = !0;
  1830. break;
  1831. case 36:
  1832. this.api.Yh() && (this.api.startSeekCsiAction(),
  1833. this.api.seekTo(0, void 0, void 0, void 0, 79),
  1834. h = f = !0);
  1835. break;
  1836. case 35:
  1837. this.api.Yh() && (this.api.startSeekCsiAction(),
  1838. this.api.seekTo(Infinity, void 0, void 0, void 0, 80),
  1839. h = f = !0)
  1840. }
  1841. */
  1842.  
  1843. }
  1844.  
  1845.  
  1846. if (rr) {
  1847.  
  1848. // focusBodyIfSuccess && Promise.resolve().then(() => {
  1849. // activeElement === document.activeElement && activeElement.blur();
  1850. // });
  1851.  
  1852. evt.preventDefault();
  1853. evt.stopImmediatePropagation();
  1854. evt.stopPropagation();
  1855.  
  1856. }
  1857.  
  1858. };
  1859.  
  1860. document.addEventListener('keydown', keyEventListener, { capture: true });
  1861.  
  1862.  
  1863. document.addEventListener('keyup', keyEventListener, { capture: true });
  1864.  
  1865. }
  1866.  
  1867. return { pageMediaWatcher, shortcutKeysFixer, keyboardController };
  1868.  
  1869. })();
  1870.  
  1871.  
  1872. pageMediaWatcher();
  1873. FIX_SHORTCUTKEYS > 0 && shortcutKeysFixer();
  1874.  
  1875.  
  1876. const check_for_set_key_order = (() => {
  1877.  
  1878. let mySet = new Set();
  1879.  
  1880. mySet.add("value1");
  1881. mySet.add("value2");
  1882. mySet.add("value3");
  1883.  
  1884. // Function to convert Set values to an array
  1885. function getSetValues(set) {
  1886. return Array.from(set.values());
  1887. }
  1888.  
  1889. // Function to test if the Set maintains insertion order
  1890. function testSetOrder(set, expectedOrder) {
  1891. let values = getSetValues(set);
  1892. return expectedOrder.join(',') === values.join(',');
  1893. }
  1894.  
  1895. // Test 1: Initial order
  1896. if (mySet.values().next().value !== "value1") return false;
  1897. if (!testSetOrder(mySet, ["value1", "value2", "value3"])) return false;
  1898.  
  1899. // Test 2: After deleting an element
  1900. mySet.delete("value2");
  1901. if (mySet.values().next().value !== "value1") return false;
  1902. if (!testSetOrder(mySet, ["value1", "value3"])) return false;
  1903.  
  1904. // Test 3: After re-adding a deleted element
  1905. mySet.add("value2");
  1906. if (mySet.values().next().value !== "value1") return false;
  1907. if (!testSetOrder(mySet, ["value1", "value3", "value2"])) return false;
  1908.  
  1909. // Test 4: After adding a new element
  1910. mySet.add("value4");
  1911. if (mySet.values().next().value !== "value1") return false;
  1912. if (!testSetOrder(mySet, ["value1", "value3", "value2", "value4"])) return false;
  1913.  
  1914. // Test 5: Delete+Add
  1915. mySet.delete("value1");
  1916. mySet.delete("value3");
  1917. mySet.add("value3");
  1918. mySet.add("value1");
  1919. if (mySet.values().next().value !== "value2") return false;
  1920. if (!testSetOrder(mySet, ["value2", "value4", "value3", "value1"])) return false;
  1921.  
  1922. return true;
  1923. })();
  1924.  
  1925.  
  1926. // const qm47 = Symbol();
  1927. const qm57 = Symbol();
  1928. const qm53 = Symbol();
  1929. const qn53 = Symbol();
  1930.  
  1931.  
  1932. const ump3 = new WeakMap();
  1933.  
  1934. const stp = document.createElement('noscript');
  1935. stp.id = 'weakref-placeholder'
  1936.  
  1937.  
  1938. const handlerWFs = {};
  1939.  
  1940. const createHandlerWF = (z, usePlaceholder) => {
  1941.  
  1942. return {
  1943. get() {
  1944. const elm = this;
  1945. const wr = elm[z];
  1946. if (!wr) return null;
  1947. const m = kRef(wr);
  1948. if (!m && usePlaceholder) {
  1949. if (typeof usePlaceholder === 'function') usePlaceholder(elm);
  1950. return stp;
  1951. }
  1952. return m;
  1953. },
  1954. set(nv) {
  1955. const elm = this;
  1956. elm[z] = nv ? mWeakRef(nv) : null;
  1957. return true;
  1958. },
  1959. configurable: true,
  1960. enumerable: true
  1961.  
  1962. }
  1963. }
  1964.  
  1965. const setupWF = typeof WeakRef !== 'undefined' ? (elm, s, usePlaceholder) => {
  1966. const z = `${s}72`;
  1967. if (z in elm) return;
  1968. const pd = Object.getOwnPropertyDescriptor(elm, s);
  1969. if (pd && pd.configurable && !pd.get && !pd.set) {
  1970. const p = pd.value;
  1971. delete elm[s];
  1972. const handlerWF = handlerWFs[s] || (handlerWFs[s] = createHandlerWF(z, usePlaceholder));
  1973. Object.defineProperty(elm, s, handlerWF);
  1974. elm[s] = p;
  1975. elm = null;
  1976. }
  1977. } : null;
  1978.  
  1979. const mxMapPD = new WeakMap();
  1980.  
  1981. const identifierWD = Symbol();
  1982. const handlerWD = {
  1983. get(obj, prop) {
  1984. if (prop === identifierWD) return true;
  1985. const val = obj[prop];
  1986. if (typeof (val || 0).deref === 'function') {
  1987. return val.deref();
  1988. }
  1989. return val;
  1990. },
  1991. set(obj, prop, val) {
  1992. if (val instanceof Node) {
  1993. obj[prop] = mWeakRef(val);
  1994. } else {
  1995. obj[prop] = val;
  1996. }
  1997. return true;
  1998. }
  1999. };
  2000.  
  2001. const setupWD = WEAK_REF_PROXY_DOLLAR && typeof WeakRef !== 'undefined' ? function (dh) {
  2002.  
  2003. const $ = dh ? dh.$ : 0;
  2004.  
  2005. if (typeof ($ || 0) === 'object' && $[identifierWD] !== true) {
  2006.  
  2007. for (const [k, v] of Object.entries($)) {
  2008. if (v instanceof Node) {
  2009. $[k] = mWeakRef(v);
  2010. }
  2011. }
  2012.  
  2013. let kPD = mxMapPD.get($);
  2014. if (!kPD) {
  2015. kPD = new Proxy($, handlerWD);
  2016. mxMapPD.set($, kPD);
  2017. }
  2018. delete dh.$;
  2019. dh.$ = kPD;
  2020.  
  2021. }
  2022.  
  2023. } : null;
  2024.  
  2025.  
  2026. const configureVisibilityObserverT_ = function () {
  2027. const hostElement = this.hostElement;
  2028. if (!(hostElement instanceof Node) || hostElement.nodeName === 'NOSCRIPT') {
  2029. this.unobserve_();
  2030. } else {
  2031. return this.configureVisibilityObserver27_();
  2032. }
  2033. };
  2034. const getParentRendererT = function () {
  2035. const hostElement = this.hostElement;
  2036. if (!(hostElement instanceof Node) || hostElement.nodeName === 'NOSCRIPT') {
  2037. return null;
  2038. } else {
  2039. return this.getParentRenderer27();
  2040. }
  2041. }
  2042.  
  2043. const attachedT = function () {
  2044. const hostElement = this.hostElement;
  2045. if (!(hostElement instanceof Node) || hostElement.nodeName === 'NOSCRIPT') {
  2046. if (this.isAttached === true) this.isAttached = false;
  2047. return void 0;
  2048. } else {
  2049. return this.attached27();
  2050. }
  2051. }
  2052.  
  2053. const hostElementCleanUp = (dh) => {
  2054. if (typeof dh.dispose === 'function') {
  2055. try {
  2056. if (dh.visibilityMonitor || dh.visibilityObserver) {
  2057. dh.dispose();
  2058. dh.visibilityMonitor = null;
  2059. dh.visibilityObserver = null;
  2060. }
  2061. } catch (e) { }
  2062. }
  2063. if (typeof dh.detached === 'function') {
  2064. try {
  2065. if (dh.visibilityObserverForChild_ || dh.localVisibilityObserver_) {
  2066. dh.detached();
  2067. dh.visibilityObserverForChild_ = null;
  2068. dh.localVisibilityObserver_ = null;
  2069. }
  2070. } catch (e) { }
  2071. }
  2072. };
  2073.  
  2074. const setupDataHost = WEAK_REF_BINDING && setupWF && setupWD ? function (dh, opt) {
  2075.  
  2076. if (typeof (dh || 0) === 'object') {
  2077.  
  2078. if (typeof dh.configureVisibilityObserver_ === 'function' && !dh.configureVisibilityObserver27_) {
  2079. dh.configureVisibilityObserver27_ = dh.configureVisibilityObserver_;
  2080. dh.configureVisibilityObserver_ = configureVisibilityObserverT_;
  2081. }
  2082.  
  2083. if (typeof dh.getParentRenderer === 'function' && !dh.getParentRenderer27) {
  2084. dh.getParentRenderer27 = dh.getParentRenderer;
  2085. dh.getParentRenderer = getParentRendererT;
  2086. }
  2087.  
  2088. if (typeof dh.attached === 'function' && !dh.attached27) {
  2089. dh.attached27 = dh.attached;
  2090. dh.attached = attachedT;
  2091. }
  2092.  
  2093. dh.m822 = (dh.m822 || 0) + 1;
  2094.  
  2095. setupWF(dh, 'hostElement', hostElementCleanUp);
  2096. setupWF(dh, 'parentComponent');
  2097. setupWF(dh, 'localVisibilityObserver_');
  2098. setupWF(dh, 'cachedProviderNode_');
  2099.  
  2100.  
  2101. setupWF(dh, '__template');
  2102. setupWF(dh, '__templatizeOwner');
  2103. setupWF(dh, '__templateInfo');
  2104.  
  2105. // setupD1(dh, 'root', 1);
  2106.  
  2107. let elements_;
  2108. if (!('elements_72' in dh) && (elements_ = dh.elements_) && typeof elements_ === 'object' && Object.keys(elements_).length > 0) setupWF(dh, 'elements_');
  2109.  
  2110. setupWD(dh);
  2111. }
  2112.  
  2113.  
  2114.  
  2115.  
  2116. } : null;
  2117.  
  2118. PROP_OverReInclusion_AVOID && (() => {
  2119.  
  2120.  
  2121. if (typeof HTMLElement.prototype.hasOwnProperty72 === 'function' || typeof HTMLElement.prototype.hasOwnProperty !== 'function') return;
  2122. const f = HTMLElement.prototype.hasOwnProperty72 = HTMLElement.prototype.hasOwnProperty;
  2123. let byPassVal = null;
  2124. let byPassCount = 0;
  2125. let mmw = new Set()
  2126. HTMLElement.prototype.hasOwnProperty = function (prop) {
  2127. if (arguments.length !== 1) return f.apply(this, arguments);
  2128. if (byPassVal !== null && typeof prop === 'string') {
  2129.  
  2130.  
  2131. if (PROP_OverReInclusion_LIST.has(prop)) {
  2132.  
  2133. byPassCount++;
  2134. return byPassVal;
  2135. }
  2136.  
  2137. // if(byPassVal === true && !this.hasOwnProperty72(prop)){
  2138.  
  2139. // Object.de
  2140.  
  2141. // }
  2142.  
  2143. PROP_OverReInclusion_DEBUGLOG && mmw.add(prop);
  2144.  
  2145.  
  2146. }
  2147. return this.hasOwnProperty72(prop);
  2148. }
  2149.  
  2150.  
  2151. /*
  2152. z.prototype.forwardDynamicProps = function() {
  2153. var B = m(this.inst);
  2154. B = h(B);
  2155. for (var F = B.next(); !F.done; F = B.next()) {
  2156. var H = h(F.value);
  2157. F = H.next().value;
  2158. H = H.next().value;
  2159. my(this, F, H);
  2160. r(b) && !ly(F) && Wua(this.inst, F)
  2161. }
  2162. }
  2163. */
  2164.  
  2165.  
  2166.  
  2167. let byPassZeroShowed = false;
  2168. const forwardDynamicPropsGeneral = function () {
  2169. byPassVal = true;
  2170. byPassCount = 0;
  2171. PROP_OverReInclusion_DEBUGLOG && mmw.clear();
  2172. const ret = this.forwardDynamicProps72();
  2173. byPassVal = null;
  2174. if (byPassCount === 0 && !byPassZeroShowed) {
  2175. byPassZeroShowed = true;
  2176. console.log('[yt-js-engine-tamer] byPassCount = 0 in forwardDynamicProps')
  2177. }
  2178. byPassCount = 0;
  2179. if (PROP_OverReInclusion_DEBUGLOG && mmw.size > 0) console.log(399, '[yt-js-engine-tamer]', [...mmw])
  2180. PROP_OverReInclusion_DEBUGLOG && mmw.clear();
  2181. return ret;
  2182. };
  2183.  
  2184. const propCheck = (proto) => {
  2185. if (typeof (proto || 0) == 'object' && typeof proto.forwardDynamicProps === 'function' && typeof proto.forwardDynamicProps72 !== 'function') {
  2186. proto.forwardDynamicProps72 = proto.forwardDynamicProps;
  2187. if (proto.forwardDynamicProps.length === 0) {
  2188. proto.forwardDynamicProps = forwardDynamicPropsGeneral;
  2189. }
  2190. }
  2191. };
  2192.  
  2193. const valMap = new WeakMap();
  2194. Object.defineProperty(HTMLElement.prototype, 'didForwardDynamicProps', {
  2195. get() {
  2196. propCheck(this.constructor.prototype);
  2197. return valMap.get(this);
  2198. },
  2199. set(nv) {
  2200. propCheck(this.constructor.prototype);
  2201. valMap.set(this, nv);
  2202. return true;
  2203. },
  2204. enumerable: false,
  2205. configurable: true
  2206.  
  2207. });
  2208.  
  2209. promiseForCustomYtElementsReady.then(() => {
  2210. if (typeof customElements !== 'object' || typeof customElements.define72 === 'function' || typeof customElements.define !== 'function') return;
  2211. if (customElements.define.length !== 2) return;
  2212. customElements.define72 = customElements.define;
  2213. customElements.define = function (b, w) {
  2214. propCheck(w.prototype);
  2215. const ret = this.define72(b, w);
  2216. return ret;
  2217. }
  2218. });
  2219.  
  2220. })();
  2221.  
  2222.  
  2223. let delay300 = null;
  2224.  
  2225. if (UNLOAD_DETACHED_POLYMER || WEAK_REF_BINDING) {
  2226. delay300 = new PromiseExternal();
  2227. setInterval(() => {
  2228. delay300.resolve();
  2229. delay300 = new PromiseExternal();
  2230. }, 300);
  2231. }
  2232.  
  2233. const aDelay = async function () {
  2234. await delay300.then();
  2235. await delay300.then();
  2236. }
  2237.  
  2238. const convertionFuncMap = new WeakMap();
  2239. let val_kevlar_should_maintain_stable_list = null;
  2240.  
  2241. const createStampDomArrayFn_ = (fn) => {
  2242. if (val_kevlar_should_maintain_stable_list === null) {
  2243. const config_ = ((window.yt || 0).config_ || 0);
  2244. val_kevlar_should_maintain_stable_list = ((config_ || 0).EXPERIMENT_FLAGS || 0).kevlar_should_maintain_stable_list === true
  2245. }
  2246. const gn = function (a, b, c, d, e, h) {
  2247. const isNonEmptyArray = (a || 0).length >= 1
  2248. if (!isNonEmptyArray) {
  2249. return fn.call(this, undefined, b, undefined, d);
  2250. } else if (h === undefined && typeof b === 'string' && c && typeof c === 'object' && this.is && val_kevlar_should_maintain_stable_list) {
  2251. if (c.clientSideToggleMenuItemRenderer) {
  2252. h = false;
  2253. } else {
  2254. h = true;
  2255. }
  2256. }
  2257. return fn.call(this, a, b, c, d, e, h)
  2258. }
  2259. gn.originalFn = fn;
  2260. convertionFuncMap.set(fn, gn);
  2261. return gn;
  2262. }
  2263.  
  2264. const fixStampDomArrayStableList = (h) => {
  2265. if (!h.stampDomArray_) return;
  2266. const proto = h.__proto__;
  2267. const f = proto.stampDomArray_;
  2268. if (!proto.stampDomArrayF001_ && typeof f === 'function' && f.length === 6) {
  2269. proto.stampDomArrayF001_ = 1;
  2270. proto.stampDomArray_ = convertionFuncMap.get(f) || createStampDomArrayFn_(f);
  2271. }
  2272. }
  2273.  
  2274. const weakenStampReferences = (() => {
  2275.  
  2276. const DEBUG_STAMP = false;
  2277.  
  2278. const s1 = Symbol();
  2279. const handler1 = {
  2280. get(target, prop, receiver) {
  2281. if (prop === 'object') {
  2282. return kRef(target[s1]); // avoid memory leakage
  2283. }
  2284. if (prop === '__proxy312__') return 1;
  2285. return target[prop];
  2286. }
  2287. };
  2288. const handler2 = {
  2289. get(target, prop, receiver) {
  2290. if (prop === 'indexSplices') {
  2291. return kRef(target[s1]); // avoid memory leakage
  2292. }
  2293. if (prop === '__proxy312__') return 1;
  2294. return target[prop];
  2295. }
  2296. }
  2297. return (h) => {
  2298.  
  2299. if (h.rendererStamperApplyChangeRecord_ || h.stampDomArraySplices_) {
  2300. const proto = h.__proto__;
  2301. if (!proto.yzxer && (proto.rendererStamperApplyChangeRecord_ || proto.stampDomArraySplices_)) {
  2302. proto.yzxer = 1;
  2303.  
  2304. const list = [
  2305. // "rendererStamperObserver_", // 3 ==> rendererStamperApplyChangeRecord_
  2306. "rendererStamperApplyChangeRecord_", // 3
  2307. "forwardRendererStamperChanges_", // 3
  2308. "stampDomArraySplices_", // 3
  2309. "stampDomArray_", // 6
  2310. "deferRenderStamperBinding_", // 3
  2311. ];
  2312. for (const key of list) {
  2313. const pey = `${key}$wq0iw_`;
  2314. const vKey = proto[key];
  2315. if (typeof vKey !== 'function') continue;
  2316. if (proto[pey] || vKey.length === 0) continue;
  2317.  
  2318. if (key === 'stampDomArraySplices_' && vKey.length === 3) {
  2319. proto[pey] = vKey;
  2320. proto[key] = function (a, b, c) {
  2321.  
  2322. if (typeof a === 'string' && typeof b === 'string' && typeof c === 'object' && c && c.indexSplices && c.indexSplices.length >= 1 && !c.indexSplices.rzgjr) {
  2323.  
  2324. c.indexSplices = c.indexSplices.map(e => {
  2325. if (e.__proxy312__) return e;
  2326. e[s1] = mWeakRef(e.object);
  2327. e.object = null;
  2328. return new Proxy(e, handler1);
  2329. });
  2330. c.indexSplices.rzgjr = 1;
  2331.  
  2332. c[s1] = mWeakRef(c.indexSplices);
  2333. c.indexSplices = null;
  2334. c = new Proxy(c, handler2)
  2335. arguments[2] = c;
  2336.  
  2337. }
  2338. // console.log(key, arguments.length, [...arguments]);
  2339. return proto[pey].call(this, a, b, c);
  2340. }
  2341.  
  2342. } else if (key === 'rendererStamperApplyChangeRecord_' && vKey.length === 3) {
  2343.  
  2344. // Nil
  2345.  
  2346. } else if (DEBUG_STAMP) {
  2347.  
  2348. console.log(proto.isRenderer_, 'ms_' + key, vKey.length, h.is)
  2349. proto[pey] = vKey;
  2350. proto[key] = function () {
  2351. if (key === 'rendererStamperApplyChangeRecord_' && typeof arguments[3] === 'object') {
  2352. console.log(key, arguments.length, { value: arguments[3].value, base: arguments[3].base, })
  2353. }
  2354. console.log(key, arguments.length, [...arguments]);
  2355. return proto[pey].apply(this, arguments);
  2356. }
  2357.  
  2358. }
  2359.  
  2360. }
  2361.  
  2362.  
  2363. // const m = (Object.mkss = Object.mkss || new Set());
  2364. // Object.keys(h.__proto__).filter(e => e.toLowerCase().includes('stamp') && typeof h[e] === 'function').forEach(e => m.add(e))
  2365. // console.log([...m])
  2366. }
  2367. }
  2368.  
  2369. }
  2370. })();
  2371.  
  2372. const setupDiscreteTasks = (h, rb) => {
  2373.  
  2374. if (rb) {
  2375. if (h.ky36) return;
  2376. }
  2377.  
  2378.  
  2379. if (typeof h.onYtRendererstamperFinished === 'function' && !(h.onYtRendererstamperFinished.km34)) {
  2380. const f = h.onYtRendererstamperFinished;
  2381. const g = ump3.get(f) || function () {
  2382. if (this.updateChildVisibilityProperties && !this.markDirty) {
  2383. return f.apply(this, arguments);
  2384. }
  2385. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2386. }
  2387. ump3.set(f, g);
  2388. g.km34 = 1;
  2389. h.onYtRendererstamperFinished = g;
  2390.  
  2391. }
  2392.  
  2393. if (typeof h.onYtUpdateDescriptionAction === 'function' && !(h.onYtUpdateDescriptionAction.km34)) {
  2394. const f = h.onYtUpdateDescriptionAction;
  2395. const g = ump3.get(f) || function (a) {
  2396. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2397. }
  2398. ump3.set(f, g);
  2399. g.km34 = 1;
  2400. h.onYtUpdateDescriptionAction = g;
  2401.  
  2402. }
  2403.  
  2404. if (typeof h.handleUpdateDescriptionAction === 'function' && !(h.handleUpdateDescriptionAction.km34)) {
  2405. const f = h.handleUpdateDescriptionAction;
  2406. const g = ump3.get(f) || function (a) {
  2407. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2408. }
  2409. ump3.set(f, g);
  2410. g.km34 = 1;
  2411. h.handleUpdateDescriptionAction = g;
  2412.  
  2413. }
  2414.  
  2415. if (typeof h.handleUpdateLiveChatPollAction === 'function' && !(h.handleUpdateLiveChatPollAction.km34)) {
  2416. const f = h.handleUpdateLiveChatPollAction;
  2417. const g = ump3.get(f) || function (a) {
  2418. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2419. }
  2420. ump3.set(f, g);
  2421. g.km34 = 1;
  2422. h.handleUpdateLiveChatPollAction = g;
  2423.  
  2424. }
  2425.  
  2426. if (typeof h.onTextChanged === 'function' && !(h.onTextChanged.km34)) {
  2427. const f = h.onTextChanged;
  2428. const g = ump3.get(f) || function () {
  2429. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2430. }
  2431. ump3.set(f, g);
  2432. g.km34 = 1;
  2433. h.onTextChanged = g;
  2434.  
  2435. }
  2436.  
  2437. if (typeof h.onVideoDataChange === 'function' && !(h.onVideoDataChange.km34)) {
  2438. const f = h.onVideoDataChange;
  2439. const g = ump3.get(f) || function (a) {
  2440. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2441. }
  2442. ump3.set(f, g);
  2443. g.km34 = 1;
  2444. h.onVideoDataChange = g;
  2445.  
  2446. }
  2447.  
  2448. if (typeof h.onVideoDataChange_ === 'function' && !(h.onVideoDataChange_.km34)) {
  2449. const f = h.onVideoDataChange_;
  2450. const g = ump3.get(f) || function () {
  2451. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2452. }
  2453. ump3.set(f, g);
  2454. g.km34 = 1;
  2455. h.onVideoDataChange_ = g;
  2456.  
  2457. }
  2458.  
  2459. /*
  2460. // affect chat message icon tooltips
  2461. if (typeof h.addTooltips === 'function' && !(h.addTooltips.km34)) {
  2462.  
  2463. const f = h.addTooltips;
  2464. const g = ump3.get(f) || function () {
  2465. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2466. }
  2467. ump3.set(f, g);
  2468. g.km34 = 1;
  2469. h.addTooltips = g;
  2470.  
  2471. }
  2472. */
  2473. /*
  2474. if (typeof h.onMouseOver_ === 'function' && !(h.onMouseOver_.km34) && typeof h.createTooltipIfRequired_ === 'function') {
  2475. console.log(212, h.is);
  2476. const f = h.onMouseOver_;
  2477. const g = ump3.get(f) || function () {
  2478. if (!this.__mEZ__) {
  2479. const w = document.createElement;
  2480. let EU = null;
  2481. document.createElement = function () {
  2482. let r = w.apply(this, arguments);
  2483. EU = r;
  2484. return r;
  2485. };
  2486. let done = false;
  2487. try {
  2488. this.polymerController.createTooltipIfRequired_();
  2489. done = true;
  2490. } catch (e) {
  2491. }
  2492. if (!done) {
  2493. try {
  2494. this.createTooltipIfRequired_();
  2495. done = true;
  2496. } catch (e) {
  2497. }
  2498. }
  2499. this.__mEZ__ = EU;
  2500. document.createElement = w;
  2501. }
  2502. if(this.__mEZ__){
  2503. this.__mEZ__.remove();
  2504. // this.__mEZ__.for = null;
  2505. [...this.__mEZ__.querySelectorAll('.hidden')].forEach(e=>e.classList.remove('hidden'))
  2506. }
  2507. console.log(212,this, this.is, this.__mEZ__)
  2508. return f.apply(this, arguments)
  2509. }
  2510. ump3.set(f, g);
  2511. g.km34 = 1;
  2512. h.onMouseOver_ = g;
  2513. }
  2514. */
  2515.  
  2516.  
  2517. if (typeof h.addTooltips_ === 'function' && !(h.addTooltips_.km34)) {
  2518.  
  2519. const f = h.addTooltips_;
  2520. const g = ump3.get(f) || function () {
  2521. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2522. }
  2523. ump3.set(f, g);
  2524. g.km34 = 1;
  2525. h.addTooltips_ = g;
  2526.  
  2527. }
  2528.  
  2529. if (typeof h.updateRenderedElements === 'function' && !(h.updateRenderedElements.km34)) {
  2530.  
  2531. const f = h.updateRenderedElements;
  2532. const g = ump3.get(f) || function () {
  2533. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2534. }
  2535. ump3.set(f, g);
  2536. g.km34 = 1;
  2537. h.updateRenderedElements = g;
  2538.  
  2539. }
  2540.  
  2541. if ((WEAK_REF_BINDING_CONTROL & 2) && typeof h.loadPage_ === 'function' && !(h.loadPage_.km34)) {
  2542. const f = h.loadPage_;
  2543. const g = ump3.get(f) || function (a) {
  2544. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2545. }
  2546. ump3.set(f, g);
  2547. g.km34 = 1;
  2548. h.loadPage_ = g;
  2549.  
  2550. }
  2551. // updatePageData_ : possible conflict with Omit ShadyDOM
  2552. if ((WEAK_REF_BINDING_CONTROL & 2) && typeof h.updatePageData_ === 'function' && !(h.updatePageData_.km34)) {
  2553. const f = h.updatePageData_;
  2554. const g = ump3.get(f) || function (a) {
  2555. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2556. }
  2557. ump3.set(f, g);
  2558. g.km34 = 1;
  2559. h.updatePageData_ = g;
  2560.  
  2561. }
  2562.  
  2563.  
  2564. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onFocus_ === 'function' && !(h.onFocus_.km34)) {
  2565.  
  2566. const f = h.onFocus_;
  2567. const g = ump3.get(f) || function () {
  2568. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2569. }
  2570. ump3.set(f, g);
  2571. g.km34 = 1;
  2572. h.onFocus_ = g;
  2573.  
  2574. }
  2575.  
  2576. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onBlur_ === 'function' && !(h.onBlur_.km34)) {
  2577.  
  2578. const f = h.onBlur_;
  2579. const g = ump3.get(f) || function () {
  2580. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2581. }
  2582. ump3.set(f, g);
  2583. g.km34 = 1;
  2584. h.onBlur_ = g;
  2585.  
  2586. }
  2587.  
  2588.  
  2589. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.buttonClassChanged_ === 'function' && !(h.buttonClassChanged_.km34)) {
  2590.  
  2591. const f = h.buttonClassChanged_;
  2592. const g = ump3.get(f) || function (a, b) {
  2593. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2594. }
  2595. ump3.set(f, g);
  2596. g.km34 = 1;
  2597. h.buttonClassChanged_ = g;
  2598.  
  2599. }
  2600.  
  2601. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.buttonIconChanged_ === 'function' && !(h.buttonIconChanged_.km34)) {
  2602.  
  2603. const f = h.buttonIconChanged_;
  2604. const g = ump3.get(f) || function (a) {
  2605. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2606. }
  2607. ump3.set(f, g);
  2608. g.km34 = 1;
  2609. h.buttonIconChanged_ = g;
  2610.  
  2611. }
  2612.  
  2613. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.dataChangedInBehavior_ === 'function' && !(h.dataChangedInBehavior_.km34)) {
  2614.  
  2615. const f = h.dataChangedInBehavior_;
  2616. const g = ump3.get(f) || function () {
  2617. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2618. }
  2619. ump3.set(f, g);
  2620. g.km34 = 1;
  2621. h.dataChangedInBehavior_ = g;
  2622.  
  2623. }
  2624.  
  2625. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.continuationsChanged_ === 'function' && !(h.continuationsChanged_.km34)) {
  2626.  
  2627. const f = h.continuationsChanged_;
  2628. const g = ump3.get(f) || function () {
  2629. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2630. }
  2631. ump3.set(f, g);
  2632. g.km34 = 1;
  2633. h.continuationsChanged_ = g;
  2634.  
  2635. }
  2636.  
  2637.  
  2638. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.forceChatPoll_ === 'function' && !(h.forceChatPoll_.km34)) {
  2639.  
  2640. const f = h.forceChatPoll_;
  2641. const g = ump3.get(f) || function (a) {
  2642. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2643. }
  2644. ump3.set(f, g);
  2645. g.km34 = 1;
  2646. h.forceChatPoll_ = g;
  2647.  
  2648. }
  2649.  
  2650. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onEndpointClick_ === 'function' && !(h.onEndpointClick_.km34)) {
  2651.  
  2652. const f = h.onEndpointClick_;
  2653. const g = ump3.get(f) || function (a) {
  2654. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2655. }
  2656. ump3.set(f, g);
  2657. g.km34 = 1;
  2658. h.onEndpointClick_ = g;
  2659.  
  2660. }
  2661.  
  2662. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onEndpointTap_ === 'function' && !(h.onEndpointTap_.km34)) {
  2663.  
  2664. const f = h.onEndpointTap_;
  2665. const g = ump3.get(f) || function (a) {
  2666. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2667. }
  2668. ump3.set(f, g);
  2669. g.km34 = 1;
  2670. h.onEndpointTap_ = g;
  2671.  
  2672. }
  2673.  
  2674. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.handleClick_ === 'function' && !(h.handleClick_.km34)) {
  2675.  
  2676. const f = h.handleClick_;
  2677. const g = ump3.get(f) || function (a, b) {
  2678. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2679. }
  2680. ump3.set(f, g);
  2681. g.km34 = 1;
  2682. h.handleClick_ = g;
  2683.  
  2684. }
  2685.  
  2686. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onReadyStateChange_ === 'function' && !(h.onReadyStateChange_.km34)) {
  2687.  
  2688. const f = h.onReadyStateChange_;
  2689. const g = ump3.get(f) || function () {
  2690. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2691. }
  2692. ump3.set(f, g);
  2693. g.km34 = 1;
  2694. h.onReadyStateChange_ = g;
  2695.  
  2696. }
  2697.  
  2698. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onReadyStateChangeEntryPoint_ === 'function' && !(h.onReadyStateChangeEntryPoint_.km34)) {
  2699.  
  2700. const f = h.onReadyStateChangeEntryPoint_;
  2701. const g = ump3.get(f) || function () {
  2702. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2703. }
  2704. ump3.set(f, g);
  2705. g.km34 = 1;
  2706. h.onReadyStateChangeEntryPoint_ = g;
  2707.  
  2708. }
  2709.  
  2710. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.readyStateChangeHandler_ === 'function' && !(h.readyStateChangeHandler_.km34)) {
  2711.  
  2712. const f = h.readyStateChangeHandler_;
  2713. const g = ump3.get(f) || function (a) {
  2714. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2715. }
  2716. ump3.set(f, g);
  2717. g.km34 = 1;
  2718. h.readyStateChangeHandler_ = g;
  2719.  
  2720. }
  2721.  
  2722. if (typeof h.xmlHttpHandler_ === 'function' && !(h.xmlHttpHandler_.km34)) {
  2723.  
  2724. const f = h.xmlHttpHandler_;
  2725. const g = ump3.get(f) || function (a) {
  2726. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2727. }
  2728. ump3.set(f, g);
  2729. g.km34 = 1;
  2730. h.xmlHttpHandler_ = g;
  2731.  
  2732. }
  2733.  
  2734. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.executeCallbacks_ === 'function' && !(h.executeCallbacks_.km34)) {
  2735.  
  2736. const f = h.executeCallbacks_; // overloaded
  2737. const g = ump3.get(f) || function (a) {
  2738. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2739. }
  2740. ump3.set(f, g);
  2741. g.km34 = 1;
  2742. h.executeCallbacks_ = g;
  2743.  
  2744. }
  2745.  
  2746. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.handleInvalidationData_ === 'function' && !(h.handleInvalidationData_.km34)) {
  2747.  
  2748. const f = h.handleInvalidationData_;
  2749. const g = ump3.get(f) || function (a, b) {
  2750. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2751. }
  2752. ump3.set(f, g);
  2753. g.km34 = 1;
  2754. h.handleInvalidationData_ = g;
  2755.  
  2756. }
  2757.  
  2758. if (typeof h.onInput_ === 'function' && !(h.onInput_.km34)) {
  2759.  
  2760. const f = h.onInput_;
  2761. const g = ump3.get(f) || function () {
  2762. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2763. }
  2764. ump3.set(f, g);
  2765. g.km34 = 1;
  2766. h.onInput_ = g;
  2767.  
  2768. }
  2769. if (typeof h.trigger_ === 'function' && !(h.trigger_.km34)) {
  2770.  
  2771. const f = h.trigger_;
  2772. const g = ump3.get(f) || function (a) {
  2773. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2774. }
  2775. ump3.set(f, g);
  2776. g.km34 = 1;
  2777. h.trigger_ = g;
  2778.  
  2779. }
  2780.  
  2781. if (typeof h.requestData_ === 'function' && !(h.requestData_.km34)) {
  2782.  
  2783. const f = h.requestData_;
  2784. const g = ump3.get(f) || function (a) {
  2785. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2786. }
  2787. ump3.set(f, g);
  2788. g.km34 = 1;
  2789. h.requestData_ = g;
  2790.  
  2791. }
  2792.  
  2793. if (typeof h.onLoadReloadContinuation_ === 'function' && !(h.onLoadReloadContinuation_.km34)) {
  2794.  
  2795. const f = h.onLoadReloadContinuation_;
  2796. const g = ump3.get(f) || function (a, b) {
  2797. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2798. }
  2799. ump3.set(f, g);
  2800. g.km34 = 1;
  2801. h.onLoadReloadContinuation_ = g;
  2802.  
  2803. }
  2804.  
  2805. if (typeof h.onLoadIncrementalContinuation_ === 'function' && !(h.onLoadIncrementalContinuation_.km34)) {
  2806.  
  2807. const f = h.onLoadIncrementalContinuation_;
  2808. const g = ump3.get(f) || function (a, b) {
  2809. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2810. }
  2811. ump3.set(f, g);
  2812. g.km34 = 1;
  2813. h.onLoadIncrementalContinuation_ = g;
  2814.  
  2815. }
  2816.  
  2817. if (typeof h.onLoadSeekContinuation_ === 'function' && !(h.onLoadSeekContinuation_.km34)) {
  2818.  
  2819. const f = h.onLoadSeekContinuation_;
  2820. const g = ump3.get(f) || function (a, b) {
  2821. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2822. }
  2823. ump3.set(f, g);
  2824. g.km34 = 1;
  2825. h.onLoadSeekContinuation_ = g;
  2826.  
  2827. }
  2828. if (typeof h.onLoadReplayContinuation_ === 'function' && !(h.onLoadReplayContinuation_.km34)) {
  2829.  
  2830. const f = h.onLoadReplayContinuation_;
  2831. const g = ump3.get(f) || function (a, b) {
  2832. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2833. }
  2834. ump3.set(f, g);
  2835. g.km34 = 1;
  2836. h.onLoadReplayContinuation_ = g;
  2837.  
  2838. }
  2839. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.onNavigate_ === 'function' && !(h.onNavigate_.km34)) {
  2840.  
  2841. const f = h.onNavigate_;
  2842. const g = ump3.get(f) || function (a) {
  2843. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2844. }
  2845. ump3.set(f, g);
  2846. g.km34 = 1;
  2847. h.onNavigate_ = g;
  2848.  
  2849. }
  2850.  
  2851. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.ytRendererBehaviorDataObserver_ === 'function' && !(h.ytRendererBehaviorDataObserver_.km34)) {
  2852.  
  2853. const f = h.ytRendererBehaviorDataObserver_;
  2854. const g = ump3.get(f) || function () {
  2855. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2856. }
  2857. ump3.set(f, g);
  2858. g.km34 = 1;
  2859. h.ytRendererBehaviorDataObserver_ = g;
  2860.  
  2861. }
  2862.  
  2863. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.ytRendererBehaviorTargetIdObserver_ === 'function' && !(h.ytRendererBehaviorTargetIdObserver_.km34)) {
  2864.  
  2865. const f = h.ytRendererBehaviorTargetIdObserver_;
  2866. const g = ump3.get(f) || function () {
  2867. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2868. }
  2869. ump3.set(f, g);
  2870. g.km34 = 1;
  2871. h.ytRendererBehaviorTargetIdObserver_ = g;
  2872.  
  2873. }
  2874.  
  2875. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.unregisterRenderer_ === 'function' && !(h.unregisterRenderer_.km34)) {
  2876.  
  2877. const f = h.unregisterRenderer_;
  2878. const g = ump3.get(f) || function (a) {
  2879. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2880. }
  2881. ump3.set(f, g);
  2882. g.km34 = 1;
  2883. h.unregisterRenderer_ = g;
  2884.  
  2885. }
  2886.  
  2887. if ((WEAK_REF_BINDING_CONTROL & 1) && typeof h.textChanged_ === 'function' && !(h.textChanged_.km34)) {
  2888.  
  2889. const f = h.textChanged_;
  2890. const g = ump3.get(f) || function (a) {
  2891. if (void 0 !== this.isAttached) {
  2892. const hostElement = this.hostElement;
  2893. if (!(hostElement instanceof Node) || hostElement.nodeName === 'NOSCRIPT') {
  2894. return;
  2895. }
  2896. }
  2897. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2898. }
  2899. ump3.set(f, g);
  2900. g.km34 = 1;
  2901. h.textChanged_ = g;
  2902.  
  2903. }
  2904.  
  2905.  
  2906.  
  2907. /**
  2908. *
  2909. * Neglect following
  2910. *
  2911. * h.onYtAction_
  2912. * h.startLoadingWatch [ buggy for yt-player-updated ]
  2913. * h.deferRenderStamperBinding_
  2914. *
  2915. * h.stampDomArray_
  2916. * h.stampDomArraySplices_
  2917. *
  2918. */
  2919.  
  2920.  
  2921. // RP.prototype.searchChanged_ = RP.prototype.searchChanged_;
  2922. // RP.prototype.skinToneChanged_ = RP.prototype.skinToneChanged_;
  2923. // RP.prototype.onEmojiHover_ = RP.prototype.onEmojiHover_;
  2924. // RP.prototype.onSelectCategory_ = RP.prototype.onSelectCategory_;
  2925. // RP.prototype.onShowEmojiVariantSelector = RP.prototype.onShowEmojiVariantSelector;
  2926. // RP.prototype.updateCategoriesAndPlaceholder_ = RP.prototype.updateCategoriesAndPlaceholder_;
  2927.  
  2928. if (typeof h.searchChanged_ === 'function' && !(h.searchChanged_.km34)) {
  2929.  
  2930. const f = h.searchChanged_;
  2931. const g = ump3.get(f) || function () {
  2932. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2933. }
  2934. ump3.set(f, g);
  2935. g.km34 = 1;
  2936. h.searchChanged_ = g;
  2937.  
  2938. }
  2939.  
  2940. if (typeof h.skinToneChanged_ === 'function' && !(h.skinToneChanged_.km34)) {
  2941.  
  2942. const f = h.skinToneChanged_;
  2943. const g = ump3.get(f) || function (a) {
  2944. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2945. }
  2946. ump3.set(f, g);
  2947. g.km34 = 1;
  2948. h.skinToneChanged_ = g;
  2949.  
  2950. }
  2951.  
  2952. if (typeof h.onEmojiHover_ === 'function' && !(h.onEmojiHover_.km34)) {
  2953.  
  2954. const f = h.onEmojiHover_;
  2955. const g = ump3.get(f) || function (a) {
  2956. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2957. }
  2958. ump3.set(f, g);
  2959. g.km34 = 1;
  2960. h.onEmojiHover_ = g;
  2961.  
  2962. }
  2963.  
  2964. if (typeof h.onSelectCategory_ === 'function' && !(h.onSelectCategory_.km34)) {
  2965.  
  2966. const f = h.onSelectCategory_;
  2967. const g = ump3.get(f) || function (a) {
  2968. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2969. }
  2970. ump3.set(f, g);
  2971. g.km34 = 1;
  2972. h.onSelectCategory_ = g;
  2973.  
  2974. }
  2975.  
  2976. if (typeof h.onShowEmojiVariantSelector === 'function' && !(h.onShowEmojiVariantSelector.km34)) {
  2977.  
  2978. const f = h.onShowEmojiVariantSelector;
  2979. const g = ump3.get(f) || function (a) {
  2980. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2981. }
  2982. ump3.set(f, g);
  2983. g.km34 = 1;
  2984. h.onShowEmojiVariantSelector = g;
  2985.  
  2986. }
  2987.  
  2988. if (typeof h.updateCategoriesAndPlaceholder_ === 'function' && !(h.updateCategoriesAndPlaceholder_.km34)) {
  2989.  
  2990. const f = h.updateCategoriesAndPlaceholder_;
  2991. const g = ump3.get(f) || function () {
  2992. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  2993. }
  2994. ump3.set(f, g);
  2995. g.km34 = 1;
  2996. h.updateCategoriesAndPlaceholder_ = g;
  2997.  
  2998. }
  2999.  
  3000. if (typeof h.watchPageActiveChanged_ === 'function' && !(h.watchPageActiveChanged_.km34)) {
  3001.  
  3002. const f = h.watchPageActiveChanged_;
  3003. const g = ump3.get(f) || function () {
  3004. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3005. }
  3006. ump3.set(f, g);
  3007. g.km34 = 1;
  3008. h.watchPageActiveChanged_ = g;
  3009.  
  3010. }
  3011.  
  3012. if (typeof h.activate_ === 'function' && !(h.activate_.km34)) {
  3013.  
  3014. const f = h.activate_;
  3015. const g = ump3.get(f) || function () {
  3016. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3017. }
  3018. ump3.set(f, g);
  3019. g.km34 = 1;
  3020. h.activate_ = g;
  3021.  
  3022. }
  3023. if (typeof h.onYtPlaylistDataUpdated_ === 'function' && !(h.onYtPlaylistDataUpdated_.km34)) {
  3024.  
  3025. const f = h.onYtPlaylistDataUpdated_;
  3026. const g = ump3.get(f) || function () {
  3027. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3028. }
  3029. ump3.set(f, g);
  3030. g.km34 = 1;
  3031. h.onYtPlaylistDataUpdated_ = g;
  3032.  
  3033. }
  3034.  
  3035. FIX_stampDomArray_stableList && fixStampDomArrayStableList(h);
  3036. const ENABLE_weakenStampReferencesQ = ENABLE_weakenStampReferences && typeof DocumentTimeline !== 'undefined' && typeof WeakRef !== 'undefined';
  3037. ENABLE_weakenStampReferencesQ && weakenStampReferences(h);
  3038.  
  3039.  
  3040. /**
  3041. *
  3042. * Neglect following
  3043. *
  3044. * h.rendererStamperObserver_
  3045. * h.rendererStamperApplyChangeRecord_
  3046. * h.flushRenderStamperComponentBindings_
  3047. * h.forwardRendererStamperChanges_
  3048. *
  3049. */
  3050.  
  3051. if (typeof h.tryRenderChunk_ === 'function' && !(h.tryRenderChunk_.km34)) {
  3052.  
  3053. const f = h.tryRenderChunk_;
  3054. const g = ump3.get(f) || function () {
  3055. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3056. }
  3057. ump3.set(f, g);
  3058. g.km34 = 1;
  3059. h.tryRenderChunk_ = g;
  3060.  
  3061. }
  3062.  
  3063.  
  3064. if (typeof h.renderChunk_ === 'function' && !(h.renderChunk_.km34)) {
  3065.  
  3066. const f = h.renderChunk_;
  3067. const g = ump3.get(f) || function () {
  3068. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3069. }
  3070. ump3.set(f, g);
  3071. g.km34 = 1;
  3072. h.renderChunk_ = g;
  3073.  
  3074. }
  3075.  
  3076. if (typeof h.deepLazyListObserver_ === 'function' && !(h.deepLazyListObserver_.km34)) {
  3077.  
  3078. const f = h.deepLazyListObserver_;
  3079. const g = ump3.get(f) || function () {
  3080. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3081. }
  3082. ump3.set(f, g);
  3083. g.km34 = 1;
  3084. h.deepLazyListObserver_ = g;
  3085.  
  3086. }
  3087.  
  3088. if (typeof h.onItemsUpdated_ === 'function' && !(h.onItemsUpdated_.km34)) {
  3089.  
  3090. const f = h.onItemsUpdated_;
  3091. const g = ump3.get(f) || function () {
  3092. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3093. }
  3094. ump3.set(f, g);
  3095. g.km34 = 1;
  3096. h.onItemsUpdated_ = g;
  3097.  
  3098. }
  3099.  
  3100. if (typeof h.requestRenderChunk_ === 'function' && !(h.requestRenderChunk_.km34)) {
  3101.  
  3102. const f = h.requestRenderChunk_;
  3103. const g = ump3.get(f) || function () {
  3104. Promise.resolve().then(() => f.apply(this, arguments)).catch(console.log);
  3105. }
  3106. ump3.set(f, g);
  3107. g.km34 = 1;
  3108. h.requestRenderChunk_ = g;
  3109.  
  3110. }
  3111.  
  3112. /**
  3113. *
  3114. * Neglect following
  3115. *
  3116. * h.dataChanged_ [ buggy for page swtiching ]
  3117. *
  3118. * h.updateChangeRecord_ [ see https://github.com/cyfung1031/userscript-supports/issues/20 ]
  3119. *
  3120. * h.cancelPendingTasks_
  3121. * h.fillRange_
  3122. * h.addTextNodes_
  3123. * h.updateText_
  3124. * h.stampTypeChanged_
  3125. *
  3126. */
  3127.  
  3128.  
  3129. }
  3130.  
  3131. const keyStConnectedCallback = Symbol(); // avoid copying the value
  3132.  
  3133. // const keyStDisconnectedCallback = Symbol(); // avoid copying the value
  3134. const cmf = new WeakMap();
  3135. const dmf = new WeakMap();
  3136.  
  3137. const gvGenerator = (nv) => {
  3138. return function () {
  3139. const cnt = insp(this);
  3140. const hostElement = cnt.hostElement || 0;
  3141. const dollar = hostElement ? (this.$ || indr(this)) : 0;
  3142. let p = (hostElement instanceof HTMLElement) && (dollar || !this.is);
  3143. if (p && (!dollar && !this.is)) {
  3144. const nodeName = hostElement.nodeName;
  3145. if (typeof nodeName !== 'string') {
  3146. // just in case
  3147. } else if (nodeName.startsWith("DOM-")) {
  3148. // dom-if, dom-repeat, etc
  3149. } else {
  3150. // yt element - new model, yt-xxxx, anixxxxxx
  3151. p = false;
  3152. }
  3153. }
  3154. if (p) {
  3155. if (typeof cnt.markDirty === 'function') {
  3156. // the yt element might call markDirty (occasionally)
  3157. p = false;
  3158. } else if (this.is === 'ytd-engagement-panel-section-list-renderer') {
  3159. // see https://github.com/cyfung1031/userscript-supports/issues/20
  3160. p = false;
  3161. }
  3162. }
  3163. if (p) {
  3164.  
  3165. // << dom-repeat & dom-if >>
  3166.  
  3167. // sequence on the same instance
  3168. this[qm57] = (this[qm57] || Promise.resolve()).then(() => nv.apply(this, arguments)).catch(console.log);
  3169. } else {
  3170. nv.apply(this, arguments);
  3171. }
  3172. };
  3173. }
  3174.  
  3175. // const assignedHolderWS = new WeakSet();
  3176.  
  3177. const setupWeakRef = (h) => {
  3178.  
  3179.  
  3180.  
  3181. /*
  3182. if(typeof h.is === 'string'){
  3183.  
  3184. const holder = h.hostElement || h;
  3185. if (holder instanceof Node) {
  3186. if (!assignedHolderWS.has(holder)) {
  3187. assignedHolderWS.add(holder);
  3188. h.kz62 = 0;
  3189. }
  3190. }
  3191.  
  3192. }
  3193.  
  3194. */
  3195.  
  3196. // if(h.is === 'ytd-metadata-row-container-renderer'){
  3197.  
  3198. // if(!h.mk2145) h.mk2145 = crypto.randomUUID();
  3199.  
  3200. // let ww = '';
  3201. // const holder = h.hostElement || h;
  3202. // if(holder && holder.setAttribute){
  3203. // holder.setAttribute('sww',(holder.getAttribute('sww' ) || '' )+"*" )
  3204.  
  3205. // ww = holder.getAttribute('sww')
  3206. // }
  3207. // console.log(2929, `a.${'hostElement' in h};b.${'hostElement72' in h}`, h.mk2145, h.is ,ww, h, `kz62=${h.kz62}` , !!(setupWD && setupWF && setupDataHost && (h.is || h.__dataHost)) )
  3208.  
  3209. // }
  3210.  
  3211. if (setupDataHost !== null && ('hostElement' in h) && !('hostElement72' in h)) {
  3212.  
  3213. let skip = false;
  3214. // if (h.is && typeof h.is === 'string' && h.is.length > 15 && h.is.length < 30) {
  3215. // if (h.is.includes('yt-') && !h.$ && h.is.length !== 20 && h.is.length !== 21 && h.is.length !== 22) {
  3216. // skip = true;
  3217. // // return;
  3218. // }
  3219. // }
  3220.  
  3221. h.kz62 = (h.kz62 || 0) + 1;
  3222.  
  3223. //
  3224.  
  3225. setupWD(h);
  3226. const hostElement = h.hostElement;
  3227.  
  3228. for (const s of ['__dataHost', '__CE_shadowRoot', '__template', '__templatizeOwner']) {
  3229. setupWF(h, s);
  3230. setupWF(hostElement, s);
  3231. }
  3232.  
  3233. setupDataHost(h.__dataHost, skip);
  3234. setupDataHost(hostElement.__dataHost, skip);
  3235.  
  3236. hostElement && aDelay().then(() => {
  3237. setupWF(hostElement, '__CE_shadowRoot');
  3238. });
  3239.  
  3240. if (!h.m822) setupDataHost(h)
  3241.  
  3242. }
  3243.  
  3244. }
  3245.  
  3246.  
  3247. let nativeHTMLElement = window.HTMLElement;
  3248.  
  3249. try {
  3250.  
  3251. const q = document.createElement('template');
  3252. q.innerHTML = '<ytz-null361></ytz-null361>';
  3253. nativeHTMLElement = q.content.firstChild.constructor
  3254.  
  3255. } catch (e) { }
  3256.  
  3257. if (!nativeHTMLElement.prototype.connectedCallback) {
  3258. nativeHTMLElement.prototype.connectedCallback79 = nativeHTMLElement.prototype.connectedCallback;
  3259. nativeHTMLElement.prototype.connectedCallback = function () {
  3260. let r;
  3261. if (this.connectedCallback79) r = this.connectedCallback79.apply(this, arguments);
  3262.  
  3263. if (WEAK_REF_BINDING && (this instanceof Node) && (this.is || this.__dataHost)) {
  3264.  
  3265. setupWeakRef(insp(this))
  3266. // setupWeakRef(this.__dataHost)
  3267. }
  3268. return r;
  3269. }
  3270. }
  3271.  
  3272. SCRIPTLET_NOFIX_setTimeout && FIX_VIDEO_BLOCKING && typeof AbortSignal !== 'undefined' && (() => {
  3273. // resolve(1) is already done by JS Tamer (FIX_VIDEO_BLOCKING)
  3274. // `setTimeout(resolve(1), 5000)` is removed in 2024.05.12 YT Code
  3275.  
  3276. const delay = 5000;
  3277. let reNeedle = null;
  3278. let test;
  3279. try {
  3280. test = RegExp.prototype.test;
  3281. RegExp.prototype.test = function () { reNeedle = this; throw '' }
  3282. setTimeout(Symbol(), delay);
  3283. } catch (e) { }
  3284. if (test) RegExp.prototype.test = test;
  3285. if (reNeedle) {
  3286. reNeedle.test = () => false;
  3287. // reNeedle.test848= reNeedle.test;
  3288. // reNeedle.test = function(){
  3289. // const r = this.test848(...arguments);
  3290. // console.log('tested', r)
  3291. // return r;
  3292. // }
  3293. console.log('[yt-js-engine-tamer] Disabled Scriptlet setTimeout', reNeedle);
  3294. }
  3295.  
  3296. })();
  3297.  
  3298. ENABLE_discreteTasking && Object.defineProperty(Object.prototype, 'connectedCallback', {
  3299. get() {
  3300. const f = this[keyStConnectedCallback];
  3301. if (this.is) {
  3302. setupDiscreteTasks(this, true);
  3303. if (f) this.ky36 = 1;
  3304. }
  3305. if (WEAK_REF_BINDING && (this.is || this instanceof Node)) {
  3306. setupWeakRef(this)
  3307. }
  3308. return f;
  3309. },
  3310. set(nv) {
  3311. let gv;
  3312. if (typeof nv === 'function') {
  3313.  
  3314. gv = cmf.get(nv) || gvGenerator(nv);
  3315. if (gv !== nv) {
  3316. cmf.set(nv, gv);
  3317. cmf.set(gv, gv);
  3318. dmf.set(gv, nv);
  3319. }
  3320.  
  3321. } else {
  3322. gv = nv;
  3323. }
  3324. this[keyStConnectedCallback] = gv; // proto or object
  3325. if (this.is) {
  3326. setupDiscreteTasks(this);
  3327. }
  3328. if (WEAK_REF_BINDING && (this.is || this instanceof Node)) {
  3329. setupWeakRef(this)
  3330. }
  3331. return true;
  3332. },
  3333. enumerable: false,
  3334. configurable: true
  3335.  
  3336. });
  3337.  
  3338. const pLoad = new Promise(resolve => {
  3339. if (document.readyState !== 'loading') {
  3340. resolve();
  3341. } else {
  3342. window.addEventListener("DOMContentLoaded", resolve, false);
  3343. }
  3344. });
  3345. pLoad.then(() => {
  3346.  
  3347. let nonce = document.querySelector('style[nonce]');
  3348. nonce = nonce ? nonce.getAttribute('nonce') : null;
  3349. const st = document.createElement('style');
  3350. if (typeof nonce === 'string') st.setAttribute('nonce', nonce);
  3351. st.textContent = "none-element-k47{order:0}";
  3352. st.addEventListener('load', () => {
  3353. pf31.resolve();
  3354. p59 = 1;
  3355. }, false);
  3356. (document.body || document.head || document.documentElement).appendChild(st);
  3357.  
  3358. });
  3359.  
  3360. const prepareLogs = [];
  3361.  
  3362. const skipAdsDetection = new Set(['/robots.txt', '/live_chat', '/live_chat_replay']);
  3363.  
  3364. let winError00 = window.onerror;
  3365.  
  3366. let fix_error_many_stack_state = !FIX_error_many_stack ? 0 : skipAdsDetection.has(location.pathname) ? 2 : 1;
  3367.  
  3368. if (!JSON || !('parse' in JSON)) fix_error_many_stack_state = 0;
  3369.  
  3370. ; FIX_Iframe_NULL_SRC && (() => {
  3371.  
  3372. const emptyBlobUrl = URL.createObjectURL(new Blob([], { type: 'text/html' }));
  3373. const lcOpt = { sensitivity: 'base' };
  3374. document.createElement24 = document.createElement;
  3375. document.createElement = function (t) {
  3376. if (typeof t === 'string' && t.length === 6) {
  3377. if (t.localeCompare('iframe', undefined, lcOpt) === 0) {
  3378. const p = this.createElement24(t);
  3379. try {
  3380. const stack = new Error().stack;
  3381. const isSearchbox = stack.includes('initializeSearchbox'); // see https://greasyfork.org/scripts/473972-youtube-js-engine-tamer/discussions/217084
  3382. if (!isSearchbox) {
  3383. p.src = emptyBlobUrl; // avoid iframe is appended to DOM without any url
  3384. }
  3385. } catch (e) { }
  3386. return p;
  3387. }
  3388. }
  3389. return this.createElement24.apply(this, arguments);
  3390. };
  3391.  
  3392. })();
  3393.  
  3394. ; fix_error_many_stack_state === 1 && (() => {
  3395.  
  3396.  
  3397. let p1 = winError00;
  3398.  
  3399. let stackNeedleDetails = null;
  3400.  
  3401. Object.defineProperty(Object.prototype, 'matchAll', {
  3402. get() {
  3403. stackNeedleDetails = this;
  3404. return true;
  3405. },
  3406. enumerable: true,
  3407. configurable: true
  3408. });
  3409.  
  3410. try {
  3411. JSON.parse("{}");
  3412. } catch (e) {
  3413. console.warn(e)
  3414. fix_error_many_stack_state = 0;
  3415. }
  3416.  
  3417. delete Object.prototype['matchAll'];
  3418.  
  3419. let p2 = window.onerror;
  3420.  
  3421. window.onerror = p1;
  3422.  
  3423. if (fix_error_many_stack_state === 0) return;
  3424.  
  3425. if (stackNeedleDetails) {
  3426. JSON.parse.stackNeedleDetails = stackNeedleDetails;
  3427. stackNeedleDetails.matchAll = true;
  3428. }
  3429.  
  3430. if (p1 === p2) return (fix_error_many_stack_state = 0);
  3431.  
  3432. // p1!==p2
  3433. fix_error_many_stack_state = !stackNeedleDetails ? 4 : 3;
  3434.  
  3435. })();
  3436.  
  3437. ; fix_error_many_stack_state === 2 && (() => {
  3438.  
  3439.  
  3440. let p1 = winError00;
  3441.  
  3442. let objectPrune = null;
  3443. let stackNeedleDetails = null;
  3444.  
  3445. Object.defineProperty(Function.prototype, 'findOwner', {
  3446. get() {
  3447. objectPrune = this;
  3448. return this._findOwner;
  3449. },
  3450. set(nv) {
  3451. this._findOwner = nv;
  3452. return true;
  3453. },
  3454. enumerable: true,
  3455. configurable: true
  3456. });
  3457.  
  3458. Object.defineProperty(Object.prototype, 'matchAll', {
  3459. get() {
  3460. stackNeedleDetails = this;
  3461. return true;
  3462. },
  3463. enumerable: true,
  3464. configurable: true
  3465. });
  3466.  
  3467. try {
  3468. JSON.parse("{}");
  3469. } catch (e) {
  3470. console.warn(e)
  3471. fix_error_many_stack_state = 0;
  3472. }
  3473.  
  3474. delete Function.prototype['findOwner'];
  3475. delete Object.prototype['matchAll'];
  3476.  
  3477. let p2 = window.onerror;
  3478.  
  3479. if (p1 !== p2) return (fix_error_many_stack_state = 4); // p1 != p2
  3480.  
  3481. if (fix_error_many_stack_state == 0) return;
  3482.  
  3483. // the following will only execute when Brave's scriptlets.js is executed.
  3484.  
  3485. prepareLogs.push("fix_error_many_stack_state NB")
  3486.  
  3487. if (stackNeedleDetails) {
  3488. stackNeedleDetails.pattern = null;
  3489. stackNeedleDetails.re = null;
  3490. stackNeedleDetails.expect = null;
  3491. stackNeedleDetails.matchAll = true;
  3492. }
  3493.  
  3494. if (objectPrune) {
  3495. objectPrune.findOwner = objectPrune.mustProcess = objectPrune.logJson = () => { }
  3496. delete objectPrune._findOwner;
  3497. }
  3498.  
  3499. fix_error_many_stack_state = 3;
  3500. JSON.parse.stackNeedleDetails = stackNeedleDetails;
  3501. JSON.parse.objectPrune = objectPrune;
  3502.  
  3503. })();
  3504.  
  3505. ; fix_error_many_stack_state === 3 && (() => {
  3506.  
  3507.  
  3508. let p1 = winError00;
  3509.  
  3510. try {
  3511. JSON.parse("{}");
  3512. } catch (e) {
  3513. console.warn(e)
  3514. fix_error_many_stack_state = 0;
  3515. }
  3516.  
  3517. let p2 = window.onerror;
  3518.  
  3519. if (p1 === p2) return;
  3520.  
  3521. window.onerror = p1;
  3522.  
  3523. if (fix_error_many_stack_state === 0) return;
  3524.  
  3525. fix_error_many_stack_state = 4; // p1 != p2
  3526.  
  3527.  
  3528. })();
  3529.  
  3530. fix_error_many_stack_state === 4 && (() => {
  3531.  
  3532. // the following will only execute when Brave's scriptlets.js is executed.
  3533.  
  3534. prepareLogs.push("fix_error_many_stack_state AB")
  3535.  
  3536. JSON.parseProxy = JSON.parse;
  3537.  
  3538. JSON.parse = ((parse) => {
  3539.  
  3540. parse = parse.bind(JSON); // get a new instance of the current JSON.parse
  3541. return function (text, reviver) {
  3542. const onerror = window.onerror;
  3543. window.onerror = null;
  3544. let r;
  3545. try {
  3546. r = parse(...arguments);
  3547. } catch (e) {
  3548. r = e;
  3549. }
  3550. window.onerror = onerror;
  3551. if (r instanceof Error) {
  3552. throw r;
  3553. }
  3554. return r;
  3555. }
  3556.  
  3557. })(JSON.parse);
  3558.  
  3559.  
  3560. })();
  3561.  
  3562.  
  3563. // << if FIX_yt_player >>
  3564.  
  3565. // credit to @nopeless (https://greasyfork.org/scripts/471489-youtube-player-perf/)
  3566. const PERF_471489_ = true;
  3567. // PERF_471489_ is not exactly the same to Youtube Player perf v0.7
  3568. // This script uses a much gentle way to tamer the JS engine instead.
  3569.  
  3570. // << end >>
  3571.  
  3572. const steppingScaleN = 200; // transform: scaleX(k/N); 0<k<N
  3573.  
  3574.  
  3575.  
  3576. const nilFn = () => { };
  3577.  
  3578. let isMainWindow = false;
  3579. try {
  3580. isMainWindow = window.document === window.top.document
  3581. } catch (e) { }
  3582.  
  3583. let NO_PRELOAD_GENERATE_204_BYPASS = NO_PRELOAD_GENERATE_204 ? false : true;
  3584. let headLinkCollection = null;
  3585.  
  3586.  
  3587. // const assertor = (f) => f() || console.assert(false, f + "");
  3588.  
  3589. const fnIntegrity = (f, d) => {
  3590. if (!f || typeof f !== 'function') {
  3591. console.warn('f is not a function', f);
  3592. return;
  3593. }
  3594. let p = f + "", s = 0, j = -1, w = 0;
  3595. for (let i = 0, l = p.length; i < l; i++) {
  3596. const t = p[i];
  3597. if (((t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z'))) {
  3598. if (j < i - 1) w++;
  3599. j = i;
  3600. } else {
  3601. s++;
  3602. }
  3603. }
  3604. let itz = `${f.length}.${s}.${w}`;
  3605. if (!d) {
  3606. return itz;
  3607. } else {
  3608. return itz === d;
  3609. }
  3610. };
  3611.  
  3612. const getZqOu = (_yt_player) => {
  3613.  
  3614. const w = 'ZqOu';
  3615.  
  3616. let arr = [];
  3617.  
  3618. for (const [k, v] of Object.entries(_yt_player)) {
  3619.  
  3620. const p = typeof v === 'function' ? v.prototype : 0;
  3621. if (p
  3622. && typeof p.start === 'function' && p.start.length === 0 // Ou
  3623. && typeof p.isActive === 'function' && p.isActive.length === 0
  3624. && typeof p.stop === 'function' && p.stop.length === 0
  3625. && !p.isComplete && !p.getStatus && !p.getResponseHeader && !p.getLastError
  3626. && !p.send && !p.abort
  3627. && !p.sample && !p.initialize && !p.fail && !p.getName
  3628. // && !p.dispose && !p.isDisposed
  3629.  
  3630. ) {
  3631. arr = addProtoToArr(_yt_player, k, arr) || arr;
  3632.  
  3633.  
  3634. }
  3635.  
  3636. }
  3637.  
  3638. if (arr.length === 0) {
  3639.  
  3640. console.warn(`Key does not exist. [${w}]`);
  3641. } else {
  3642.  
  3643. console.log(`[${w}]`, arr);
  3644. return arr[0];
  3645. }
  3646.  
  3647. }
  3648.  
  3649. const getZqQu = (_yt_player) => {
  3650.  
  3651. const w = 'ZqQu';
  3652.  
  3653. let arr = [];
  3654.  
  3655.  
  3656. for (const [k, v] of Object.entries(_yt_player)) {
  3657.  
  3658. const p = typeof v === 'function' ? v.prototype : 0;
  3659. if (p
  3660. && typeof p.start === 'function' && p.start.length === 1 // Qu
  3661. && typeof p.isActive === 'function' && p.isActive.length === 0
  3662. && typeof p.stop === 'function' && p.stop.length === 0
  3663. && !p.isComplete && !p.getStatus && !p.getResponseHeader && !p.getLastError
  3664. && !p.send && !p.abort
  3665. && !p.sample && !p.initialize && !p.fail && !p.getName
  3666. // && !p.dispose && !p.isDisposed
  3667.  
  3668. ) {
  3669. arr = addProtoToArr(_yt_player, k, arr) || arr;
  3670.  
  3671.  
  3672. }
  3673.  
  3674. }
  3675.  
  3676. if (arr.length === 0) {
  3677.  
  3678. console.warn(`Key does not exist. [${w}]`);
  3679. } else {
  3680.  
  3681. console.log(`[${w}]`, arr);
  3682. return arr[0];
  3683. }
  3684.  
  3685. }
  3686.  
  3687.  
  3688. const getVG = (_yt_player) => {
  3689. const w = 'VG';
  3690.  
  3691. let arr = [];
  3692.  
  3693. for (const [k, v] of Object.entries(_yt_player)) {
  3694.  
  3695. const p = typeof v === 'function' ? v.prototype : 0;
  3696. if (p
  3697. && typeof p.show === 'function' && p.show.length === 1
  3698. && typeof p.hide === 'function' && p.hide.length === 0
  3699. && typeof p.stop === 'function' && p.stop.length === 0) {
  3700.  
  3701. arr = addProtoToArr(_yt_player, k, arr) || arr;
  3702.  
  3703. }
  3704.  
  3705. }
  3706.  
  3707.  
  3708. if (arr.length === 0) {
  3709.  
  3710. console.warn(`Key does not exist. [${w}]`);
  3711. } else {
  3712.  
  3713. console.log(`[${w}]`, arr);
  3714. return arr[0];
  3715. }
  3716.  
  3717.  
  3718.  
  3719. }
  3720.  
  3721.  
  3722. const getzo = (_yt_player) => {
  3723. const w = 'zo';
  3724.  
  3725. let arr = [];
  3726.  
  3727. for (const [k, v] of Object.entries(_yt_player)) {
  3728.  
  3729. if (
  3730. typeof v === 'function' && v.length === 3 && k.length < 3
  3731. && (v + "").includes("a.style[b]=c")
  3732. ) {
  3733.  
  3734. arr.push(k);
  3735.  
  3736. }
  3737.  
  3738. }
  3739.  
  3740.  
  3741. if (arr.length === 0) {
  3742.  
  3743. console.warn(`Key does not exist. [${w}]`);
  3744. } else {
  3745.  
  3746. console.log(`[${w}]`, arr);
  3747. return arr[0];
  3748. }
  3749.  
  3750. }
  3751.  
  3752. const addProtoToArr = (parent, key, arr) => {
  3753.  
  3754.  
  3755. let isChildProto = false;
  3756. for (const sr of arr) {
  3757. if (parent[key].prototype instanceof parent[sr]) {
  3758. isChildProto = true;
  3759. break;
  3760. }
  3761. }
  3762.  
  3763. if (isChildProto) return;
  3764.  
  3765. arr = arr.filter(sr => {
  3766. if (parent[sr].prototype instanceof parent[key]) {
  3767. return false;
  3768. }
  3769. return true;
  3770. });
  3771.  
  3772. arr.push(key);
  3773.  
  3774. return arr;
  3775.  
  3776.  
  3777. }
  3778.  
  3779. const getuG = (_yt_player) => {
  3780.  
  3781. const w = 'uG';
  3782.  
  3783. let arr = [];
  3784.  
  3785. for (const [k, v] of Object.entries(_yt_player)) {
  3786.  
  3787.  
  3788. const p = typeof v === 'function' ? v.prototype : 0;
  3789.  
  3790. if (p
  3791. && typeof p.createElement === 'function' && p.createElement.length === 2
  3792. && typeof p.detach === 'function' && p.detach.length === 0
  3793. && typeof p.update === 'function' && p.update.length === 1
  3794. && typeof p.updateValue === 'function' && p.updateValue.length === 2
  3795. ) {
  3796.  
  3797. arr = addProtoToArr(_yt_player, k, arr) || arr;
  3798.  
  3799. }
  3800.  
  3801. }
  3802.  
  3803.  
  3804.  
  3805.  
  3806.  
  3807. if (arr.length === 0) {
  3808.  
  3809. console.warn(`Key does not exist. [${w}]`);
  3810. } else {
  3811.  
  3812. console.log(`[${w}]`, arr);
  3813. return arr[0];
  3814. }
  3815.  
  3816. }
  3817.  
  3818.  
  3819. const getQT = (_yt_player) => {
  3820. const w = 'QT';
  3821.  
  3822. let arr = [];
  3823. let brr = new Map();
  3824.  
  3825. for (const [k, v] of Object.entries(_yt_player)) {
  3826.  
  3827. const p = typeof v === 'function' ? v.prototype : 0;
  3828. if (p) {
  3829. let q = 0;
  3830. if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 7) q += 400;
  3831. else if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 8) q += 300;
  3832. else if (typeof p.handleGlobalKeyUp === 'function') q += 200;
  3833.  
  3834. if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 0) q -= 600; // avoid SV
  3835.  
  3836. if (q < 200) continue; // p.handleGlobalKeyUp must be available
  3837.  
  3838. if (typeof p.handleGlobalKeyDown === 'function' && p.handleGlobalKeyDown.length === 8) q += 80;
  3839. if (typeof p.handleGlobalKeyDown === 'function' && p.handleGlobalKeyDown.length === 7) q += 30;
  3840. if (typeof p.step === 'function' && p.step.length === 1) q += 10;
  3841. if (typeof p.step === 'function' && p.step.length !== 1) q += 5;
  3842.  
  3843.  
  3844. // differentiate QT and DX
  3845.  
  3846. q += 280;
  3847. if (typeof p.cueVideoByPlayerVars === 'function') q += 4;
  3848. if (typeof p.loadVideoByPlayerVars === 'function') q += 4;
  3849. if (typeof p.preloadVideoByPlayerVars === 'function') q += 4;
  3850. if (typeof p.seekBy === 'function') q += 4;
  3851. if (typeof p.seekTo === 'function') q += 4;
  3852. if (typeof p.getStoryboardFormat === 'function') q += 4;
  3853. if (typeof p.getDuration === 'function') q += 4;
  3854. if (typeof p.loadModule === 'function') q += 4;
  3855. if (typeof p.unloadModule === 'function') q += 4;
  3856. if (typeof p.getOption === 'function') q += 4;
  3857. if (typeof p.getOptions === 'function') q += 4;
  3858. if (typeof p.setOption === 'function') q += 4;
  3859. if (typeof p.addCueRange === 'function') q += 4;
  3860. if (typeof p.getDebugText === 'function') q += 4;
  3861. if (typeof p.getCurrentBroadcastId === 'function') q += 4;
  3862. if (typeof p.setSizeStyle === 'function') q += 4;
  3863. if (typeof p.showControls === 'function') q += 4;
  3864. if (typeof p.hideControls === 'function') q += 4;
  3865. if (typeof p.getVideoContentRect === 'function') q += 4;
  3866. if (typeof p.toggleFullscreen === 'function') q += 4;
  3867. if (typeof p.isFullscreen === 'function') q += 4;
  3868. if (typeof p.cancelPlayback === 'function') q += 4;
  3869. if (typeof p.getProgressState === 'function') q += 4;
  3870. if (typeof p.isInline === 'function') q += 4;
  3871. if (typeof p.setInline === 'function') q += 4;
  3872. if (typeof p.toggleSubtitles === 'function') q += 4;
  3873. if (typeof p.getPlayerSize === 'function') q += 4;
  3874. if (typeof p.wakeUpControls === 'function') q += 4;
  3875. if (typeof p.setCenterCrop === 'function') q += 4;
  3876. if (typeof p.getLoopVideo === 'function') q += 4;
  3877. if (typeof p.setLoopVideo === 'function') q += 4;
  3878.  
  3879.  
  3880. if (q > 0) arr = addProtoToArr(_yt_player, k, arr) || arr;
  3881.  
  3882. if (q > 0) brr.set(k, q);
  3883.  
  3884. }
  3885.  
  3886. }
  3887.  
  3888. if (arr.length === 0) {
  3889.  
  3890. console.warn(`Key does not exist. [${w}]`);
  3891. } else {
  3892.  
  3893. arr = arr.map(key => [key, (brr.get(key) || 0)]);
  3894.  
  3895. if (arr.length > 1) arr.sort((a, b) => b[1] - a[1]);
  3896.  
  3897. if (arr.length > 2) console.log(`[${w}]`, arr);
  3898. return arr[0][0];
  3899. }
  3900.  
  3901.  
  3902.  
  3903. }
  3904.  
  3905.  
  3906.  
  3907. const getSV = (_yt_player) => {
  3908. const w = 'SV';
  3909.  
  3910. let arr = [];
  3911. let brr = new Map();
  3912.  
  3913. for (const [k, v] of Object.entries(_yt_player)) {
  3914.  
  3915. const p = typeof v === 'function' ? v.prototype : 0;
  3916. if (p) {
  3917. let q = 0;
  3918. if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 7) q += 400;
  3919. else if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 8) q += 300;
  3920. else if (typeof p.handleGlobalKeyUp === 'function') q += 200;
  3921.  
  3922. if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 0) q += 600; // SV
  3923.  
  3924. if (q < 200) continue; // p.handleGlobalKeyUp must be available
  3925.  
  3926. if (typeof p.handleGlobalKeyDown === 'function' && p.handleGlobalKeyDown.length === 8) q += 80;
  3927. if (typeof p.handleGlobalKeyDown === 'function' && p.handleGlobalKeyDown.length === 7) q += 30;
  3928. if (typeof p.step === 'function' && p.step.length === 1) q += 10;
  3929. if (typeof p.step === 'function' && p.step.length !== 1) q += 5;
  3930.  
  3931.  
  3932. // differentiate QT and DX
  3933.  
  3934.  
  3935. q += 280;
  3936.  
  3937. if (typeof p.cueVideoByPlayerVars === 'function') q -= 4;
  3938. if (typeof p.loadVideoByPlayerVars === 'function') q -= 4;
  3939. if (typeof p.preloadVideoByPlayerVars === 'function') q -= 4;
  3940. if (typeof p.seekBy === 'function') q -= 4;
  3941. if (typeof p.seekTo === 'function') q -= 4;
  3942. if (typeof p.getStoryboardFormat === 'function') q -= 4;
  3943. if (typeof p.getDuration === 'function') q -= 4;
  3944. if (typeof p.loadModule === 'function') q -= 4;
  3945. if (typeof p.unloadModule === 'function') q -= 4;
  3946. if (typeof p.getOption === 'function') q -= 4;
  3947. if (typeof p.getOptions === 'function') q -= 4;
  3948. if (typeof p.setOption === 'function') q -= 4;
  3949. if (typeof p.addCueRange === 'function') q -= 4;
  3950. if (typeof p.getDebugText === 'function') q -= 4;
  3951. if (typeof p.getCurrentBroadcastId === 'function') q -= 4;
  3952. if (typeof p.setSizeStyle === 'function') q -= 4;
  3953. if (typeof p.showControls === 'function') q -= 4;
  3954. if (typeof p.hideControls === 'function') q -= 4;
  3955. if (typeof p.getVideoContentRect === 'function') q -= 4;
  3956. if (typeof p.toggleFullscreen === 'function') q -= 4;
  3957. if (typeof p.isFullscreen === 'function') q -= 4;
  3958. if (typeof p.cancelPlayback === 'function') q -= 4;
  3959. if (typeof p.getProgressState === 'function') q -= 4;
  3960. if (typeof p.isInline === 'function') q -= 4;
  3961. if (typeof p.setInline === 'function') q -= 4;
  3962. if (typeof p.toggleSubtitles === 'function') q -= 4;
  3963. if (typeof p.getPlayerSize === 'function') q -= 4;
  3964. if (typeof p.wakeUpControls === 'function') q -= 4;
  3965. if (typeof p.setCenterCrop === 'function') q -= 4;
  3966. if (typeof p.getLoopVideo === 'function') q -= 4;
  3967. if (typeof p.setLoopVideo === 'function') q -= 4;
  3968.  
  3969.  
  3970. if (q > 0) arr = addProtoToArr(_yt_player, k, arr) || arr;
  3971.  
  3972. if (q > 0) brr.set(k, q);
  3973.  
  3974. }
  3975.  
  3976. }
  3977.  
  3978. if (arr.length === 0) {
  3979.  
  3980. console.warn(`Key does not exist. [${w}]`);
  3981. } else {
  3982.  
  3983. arr = arr.map(key => [key, (brr.get(key) || 0)]);
  3984.  
  3985. if (arr.length > 1) arr.sort((a, b) => b[1] - a[1]);
  3986.  
  3987. if (arr.length > 2) console.log(`[${w}]`, arr);
  3988. return arr[0][0];
  3989. }
  3990.  
  3991.  
  3992.  
  3993. }
  3994.  
  3995.  
  3996.  
  3997.  
  3998. const getDX = (_yt_player) => {
  3999. const w = 'DX';
  4000.  
  4001. let arr = [];
  4002. let brr = new Map();
  4003.  
  4004. for (const [k, v] of Object.entries(_yt_player)) {
  4005.  
  4006. const p = typeof v === 'function' ? v.prototype : 0;
  4007. if (p) {
  4008. let q = 0;
  4009. if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 7) q += 400;
  4010. else if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 8) q += 300;
  4011. else if (typeof p.handleGlobalKeyUp === 'function') q += 200;
  4012.  
  4013. if (typeof p.handleGlobalKeyUp === 'function' && p.handleGlobalKeyUp.length === 0) q -= 600; // avoid SV
  4014.  
  4015.  
  4016. if (!(typeof p.init === 'function' && p.init.length === 0)) q -= 300; // init is required
  4017.  
  4018. if (q < 200) continue; // p.handleGlobalKeyUp must be available
  4019.  
  4020. if (typeof p.handleGlobalKeyDown === 'function' && p.handleGlobalKeyDown.length === 8) q += 80;
  4021. if (typeof p.handleGlobalKeyDown === 'function' && p.handleGlobalKeyDown.length === 7) q += 30;
  4022. if (typeof p.step === 'function' && p.step.length === 1) q += 10;
  4023. if (typeof p.step === 'function' && p.step.length !== 1) q += 5;
  4024.  
  4025.  
  4026. // differentiate QT and DX
  4027.  
  4028.  
  4029. q += 280;
  4030.  
  4031. if (typeof p.cueVideoByPlayerVars === 'function') q -= 4;
  4032. if (typeof p.loadVideoByPlayerVars === 'function') q -= 4;
  4033. if (typeof p.preloadVideoByPlayerVars === 'function') q -= 4;
  4034. if (typeof p.seekBy === 'function') q -= 4;
  4035. if (typeof p.seekTo === 'function') q -= 4;
  4036. if (typeof p.getStoryboardFormat === 'function') q -= 4;
  4037. if (typeof p.getDuration === 'function') q -= 4;
  4038. if (typeof p.loadModule === 'function') q -= 4;
  4039. if (typeof p.unloadModule === 'function') q -= 4;
  4040. if (typeof p.getOption === 'function') q -= 4;
  4041. if (typeof p.getOptions === 'function') q -= 4;
  4042. if (typeof p.setOption === 'function') q -= 4;
  4043. if (typeof p.addCueRange === 'function') q -= 4;
  4044. if (typeof p.getDebugText === 'function') q -= 4;
  4045. if (typeof p.getCurrentBroadcastId === 'function') q -= 4;
  4046. if (typeof p.setSizeStyle === 'function') q -= 4;
  4047. if (typeof p.showControls === 'function') q -= 4;
  4048. if (typeof p.hideControls === 'function') q -= 4;
  4049. if (typeof p.getVideoContentRect === 'function') q -= 4;
  4050. if (typeof p.toggleFullscreen === 'function') q -= 4;
  4051. if (typeof p.isFullscreen === 'function') q -= 4;
  4052. if (typeof p.cancelPlayback === 'function') q -= 4;
  4053. if (typeof p.getProgressState === 'function') q -= 4;
  4054. if (typeof p.isInline === 'function') q -= 4;
  4055. if (typeof p.setInline === 'function') q -= 4;
  4056. if (typeof p.toggleSubtitles === 'function') q -= 4;
  4057. if (typeof p.getPlayerSize === 'function') q -= 4;
  4058. if (typeof p.wakeUpControls === 'function') q -= 4;
  4059. if (typeof p.setCenterCrop === 'function') q -= 4;
  4060. if (typeof p.getLoopVideo === 'function') q -= 4;
  4061. if (typeof p.setLoopVideo === 'function') q -= 4;
  4062.  
  4063.  
  4064. if (q > 0) arr = addProtoToArr(_yt_player, k, arr) || arr;
  4065.  
  4066. if (q > 0) brr.set(k, q);
  4067.  
  4068. }
  4069.  
  4070. }
  4071.  
  4072. if (arr.length === 0) {
  4073.  
  4074. console.warn(`Key does not exist. [${w}]`);
  4075. } else {
  4076.  
  4077. arr = arr.map(key => [key, (brr.get(key) || 0)]);
  4078.  
  4079. if (arr.length > 1) arr.sort((a, b) => b[1] - a[1]);
  4080.  
  4081. if (arr.length > 2) console.log(`[${w}]`, arr);
  4082. return arr[0][0];
  4083. }
  4084.  
  4085.  
  4086.  
  4087. }
  4088.  
  4089.  
  4090.  
  4091. const isPrepareCachedV = (FIX_avoid_incorrect_video_meta ? true : false) && (window === top);
  4092.  
  4093. let pageSetupVideoId = null; // set at finish; '' for indeterminate state
  4094. let pageSetupState = 0;
  4095.  
  4096. isPrepareCachedV && (() => {
  4097.  
  4098. pageSetupVideoId = '';
  4099. const clearCachedV = () => {
  4100. pageSetupVideoId = '';
  4101. pageSetupState = 0;
  4102. }
  4103. document.addEventListener('yt-navigate-start', clearCachedV, false); // user action
  4104. document.addEventListener('yt-navigate-cache', clearCachedV, false); // pop state
  4105. document.addEventListener('yt-page-data-fetched', clearCachedV, false); // still consider invalid until url is ready in yt-navigate-finish
  4106. document.addEventListener('yt-navigate-finish', () => {
  4107. pageSetupState = 1;
  4108. try {
  4109. const url = new URL(location.href);
  4110. if (!url || url.pathname !== '/watch') {
  4111. pageSetupVideoId = '';
  4112. } else {
  4113. pageSetupVideoId = url.searchParams.get('v') || '';
  4114. }
  4115. } catch (e) {
  4116. pageSetupVideoId = '';
  4117. }
  4118. }, false);
  4119.  
  4120. })();
  4121.  
  4122. let videoPlayingY = null;
  4123.  
  4124. isPrepareCachedV && (() => {
  4125.  
  4126. let getNext = true;
  4127. let videoPlayingX = {
  4128. get videoId() {
  4129. if (getNext) {
  4130. getNext = false;
  4131.  
  4132. let elements = document.querySelectorAll('ytd-watch-flexy[video-id]');
  4133. const arr = [];
  4134. for (const element of elements) {
  4135. if (!element.closest('[hidden]')) arr.push(element);
  4136. }
  4137. if (arr.length !== 1) this.__videoId__ = '';
  4138. else {
  4139. this.__videoId__ = arr[0].getAttribute('video-id');
  4140. }
  4141.  
  4142. }
  4143. return this.__videoId__ || '';
  4144. }
  4145. }
  4146.  
  4147. videoPlayingY = videoPlayingX;
  4148. const handler = (evt) => {
  4149. const target = (evt || 0).target;
  4150. if (target instanceof HTMLVideoElement) {
  4151. getNext = true;
  4152. }
  4153. }
  4154. document.addEventListener('loadedmetadata', handler, true);
  4155. document.addEventListener('durationchange', handler, true);
  4156.  
  4157. })();
  4158.  
  4159.  
  4160.  
  4161. const cleanContext = async (win) => {
  4162. const waitFn = requestAnimationFrame; // shall have been binded to window
  4163. try {
  4164. let mx = 16; // MAX TRIAL
  4165. const frameId = 'vanillajs-iframe-v1';
  4166. /** @type {HTMLIFrameElement | null} */
  4167. let frame = document.getElementById(frameId);
  4168. let removeIframeFn = null;
  4169. if (!frame) {
  4170. frame = document.createElement('iframe');
  4171. frame.id = frameId;
  4172. const blobURL = typeof webkitCancelAnimationFrame === 'function' ? (frame.src = URL.createObjectURL(new Blob([], { type: 'text/html' }))) : null; // avoid Brave Crash
  4173. frame.sandbox = 'allow-same-origin'; // script cannot be run inside iframe but API can be obtained from iframe
  4174. let n = document.createElement('noscript'); // wrap into NOSCRPIT to avoid reflow (layouting)
  4175. n.appendChild(frame);
  4176. while (!document.documentElement && mx-- > 0) await new Promise(waitFn); // requestAnimationFrame here could get modified by YouTube engine
  4177. const root = document.documentElement;
  4178. root.appendChild(n); // throw error if root is null due to exceeding MAX TRIAL
  4179. if (blobURL) Promise.resolve().then(() => URL.revokeObjectURL(blobURL));
  4180.  
  4181. removeIframeFn = (setTimeout) => {
  4182. const removeIframeOnDocumentReady = (e) => {
  4183. e && win.removeEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);
  4184. e = n;
  4185. n = win = removeIframeFn = 0;
  4186. setTimeout ? setTimeout(() => e.remove(), 200) : e.remove();
  4187. }
  4188. if (!setTimeout || document.readyState !== 'loading') {
  4189. removeIframeOnDocumentReady();
  4190. } else {
  4191. win.addEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);
  4192. }
  4193. }
  4194. }
  4195. while (!frame.contentWindow && mx-- > 0) await new Promise(waitFn);
  4196. const fc = frame.contentWindow;
  4197. if (!fc) throw "window is not found."; // throw error if root is null due to exceeding MAX TRIAL
  4198. try {
  4199. const { requestAnimationFrame, setTimeout, clearTimeout, cancelAnimationFrame, setInterval, clearInterval, requestIdleCallback, getComputedStyle } = fc;
  4200. const res = { requestAnimationFrame, setTimeout, clearTimeout, cancelAnimationFrame, setInterval, clearInterval, requestIdleCallback, getComputedStyle };
  4201. for (let k in res) res[k] = res[k].bind(win); // necessary
  4202. if (removeIframeFn) Promise.resolve(res.setTimeout).then(removeIframeFn);
  4203. res.animate = fc.HTMLElement.prototype.animate;
  4204. res.perfNow = fc.performance.now;
  4205. return res;
  4206. } catch (e) {
  4207. if (removeIframeFn) removeIframeFn();
  4208. return null;
  4209. }
  4210. } catch (e) {
  4211. console.warn(e);
  4212. return null;
  4213. }
  4214. };
  4215.  
  4216. const promiseForYtActionCalled = new Promise(resolve => {
  4217. if (typeof AbortSignal !== 'undefined') {
  4218. let hn = () => {
  4219. if (!hn) return;
  4220. hn = null;
  4221. resolve(document.querySelector('ytd-app'));
  4222. };
  4223. document.addEventListener('yt-action', hn, { capture: true, passive: true, once: true });
  4224. } else {
  4225. let hn = () => {
  4226. if (!hn) return;
  4227. document.removeEventListener('yt-action', hn, true);
  4228. hn = null;
  4229. resolve(document.querySelector('ytd-app'));
  4230. };
  4231. document.addEventListener('yt-action', hn, true);
  4232. }
  4233. });
  4234.  
  4235.  
  4236.  
  4237. cleanContext(window).then(__CONTEXT__ => {
  4238. if (!__CONTEXT__) return null;
  4239.  
  4240. const { requestAnimationFrame, setTimeout, clearTimeout, cancelAnimationFrame, setInterval, clearInterval, animate, requestIdleCallback, getComputedStyle, perfNow } = __CONTEXT__;
  4241.  
  4242.  
  4243. performance.now17 = perfNow.bind(performance);
  4244.  
  4245.  
  4246.  
  4247. __requestAnimationFrame__ = requestAnimationFrame;
  4248.  
  4249. const isGPUAccelerationAvailable = (() => {
  4250. // https://gist.github.com/cvan/042b2448fcecefafbb6a91469484cdf8
  4251. try {
  4252. const canvas = document.createElement('canvas');
  4253. return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
  4254. } catch (e) {
  4255. return false;
  4256. }
  4257. })();
  4258.  
  4259. const foregroundPromiseFn_noGPU = (() => {
  4260.  
  4261. if (isGPUAccelerationAvailable) return null;
  4262.  
  4263. const pd = Object.getOwnPropertyDescriptor(Document.prototype, 'visibilityState');
  4264. if (!pd || typeof pd.get !== 'function') return null;
  4265. const pdGet = pd.get;
  4266.  
  4267. let pr = null;
  4268.  
  4269. let hState = pdGet.call(document) === 'hidden';
  4270. // let cid = 0;
  4271. pureAddEventListener.call(document, 'visibilitychange', (evt) => {
  4272. const newHState = pdGet.call(document) === 'hidden';
  4273. if (hState !== newHState) {
  4274. // if (cid > 0) cid = clearInterval(cid);
  4275. hState = newHState;
  4276. if (!hState && pr) pr = pr.resolve();
  4277. }
  4278. });
  4279.  
  4280. // cid = setInterval(() => {
  4281. // const newHState = document.visibilityState === 'hidden';
  4282. // if (hState !== newHState) {
  4283. // hState = newHState;
  4284. // if (!hState && pr) pr = pr.resolve();
  4285. // }
  4286. // }, 100);
  4287.  
  4288.  
  4289. return (() => {
  4290. if (pr) return pr;
  4291. const w = ((!hState && setTimeout(() => {
  4292. if (!hState && pr === w) pr = pr.resolve();
  4293. })), (pr = new PromiseExternal()));
  4294. return w;
  4295. });
  4296.  
  4297. })();
  4298.  
  4299.  
  4300. let rafPromise = null;
  4301. const getRafPromise = () => rafPromise || (rafPromise = new Promise(resolve => {
  4302. requestAnimationFrame(hRes => {
  4303. rafPromise = null;
  4304. resolve(hRes);
  4305. });
  4306. }));
  4307.  
  4308. const foregroundPromiseFn = foregroundPromiseFn_noGPU || getRafPromise;
  4309.  
  4310.  
  4311. const wmComputedStyle = new WeakMap();
  4312.  
  4313. if (!window.__native__getComputedStyle__ && !window.__jst__getComputedStyle__ && typeof window.getComputedStyle === 'function' && window.getComputedStyle.length === 1) {
  4314. window.__native__getComputedStyle__ = getComputedStyle;
  4315. if (ENABLE_COMPUTEDSTYLE_CACHE) {
  4316. window.__original__getComputedStyle__ = window.getComputedStyle;
  4317. window.getComputedStyle = function (elem) {
  4318. if (!(elem instanceof Element) || (arguments.length === 2 && arguments[1]) || (arguments.length > 2)) {
  4319. return window.__native__getComputedStyle__(...arguments);
  4320. }
  4321. let cs = wmComputedStyle.get(elem);
  4322. if (!cs) {
  4323. cs = window.__native__getComputedStyle__(elem);
  4324. wmComputedStyle.set(elem, cs);
  4325. }
  4326. return cs;
  4327. };
  4328. } else {
  4329. window.__original__getComputedStyle__ = null;
  4330. }
  4331. window.__jst__getComputedStyle__ = window.getComputedStyle;
  4332. }
  4333.  
  4334. NO_SCHEDULING_DUE_TO_COMPUTEDSTYLE && promiseForYtActionCalled.then(() => {
  4335. if (typeof window.__jst__getComputedStyle__ === 'function' && window.__jst__getComputedStyle__.length === 1 && window.__jst__getComputedStyle__ !== window.getComputedStyle) {
  4336. window.getComputedStyle = window.__jst__getComputedStyle__;
  4337. }
  4338. });
  4339.  
  4340. const isUrlInEmbed = location.href.includes('.youtube.com/embed/');
  4341. const isAbortSignalSupported = typeof AbortSignal !== "undefined";
  4342.  
  4343. const promiseForTamerTimeout = new Promise(resolve => {
  4344. !isUrlInEmbed && isAbortSignalSupported && document.addEventListener('yt-action', function () {
  4345. setTimeout(resolve, 480);
  4346. }, { capture: true, passive: true, once: true });
  4347. !isUrlInEmbed && isAbortSignalSupported && typeof customElements === "object" && whenCEDefined('ytd-app').then(() => {
  4348. setTimeout(resolve, 1200);
  4349. });
  4350. setTimeout(resolve, 3000);
  4351. });
  4352.  
  4353. const promiseForPageInitied = new Promise(resolve => {
  4354. !isUrlInEmbed && isAbortSignalSupported && document.addEventListener('yt-action', function () {
  4355. setTimeout(resolve, 450);
  4356. }, { capture: true, passive: true, once: true });
  4357. !isUrlInEmbed && isAbortSignalSupported && typeof customElements === "object" && whenCEDefined('ytd-app').then(() => {
  4358. setTimeout(resolve, 900);
  4359. });
  4360. setTimeout(resolve, 1800);
  4361. });
  4362.  
  4363. NO_PRELOAD_GENERATE_204_BYPASS || promiseForPageInitied.then(() => {
  4364. NO_PRELOAD_GENERATE_204_BYPASS = true;
  4365. headLinkCollection = null;
  4366. });
  4367.  
  4368.  
  4369. NATIVE_CANVAS_ANIMATION && (() => {
  4370.  
  4371. observablePromise(() => {
  4372. HTMLCanvasElement.prototype.animate = animate;
  4373. }, promiseForTamerTimeout).obtain();
  4374.  
  4375. })();
  4376.  
  4377. FIX_ytAction_ && (async () => {
  4378.  
  4379. const ytdApp = await new Promise(resolve => {
  4380.  
  4381. whenCEDefined('ytd-app').then(() => {
  4382. const ytdApp = document.querySelector('ytd-app');
  4383. if (ytdApp) {
  4384. resolve(ytdApp);
  4385. return;
  4386. }
  4387. let mo = new MutationObserver(() => {
  4388. const ytdApp = document.querySelector('ytd-app');
  4389. if (!ytdApp) return;
  4390. if (mo) {
  4391. mo.disconnect();
  4392. mo.takeRecords();
  4393. mo = null;
  4394. }
  4395. resolve(ytdApp);
  4396. });
  4397. mo.observe(document, { subtree: true, childList: true });
  4398. });
  4399.  
  4400. });
  4401.  
  4402. if (!ytdApp) return;
  4403. const cProto = insp(ytdApp).constructor.prototype;
  4404.  
  4405. if (!cProto) return;
  4406. let mbd = 0;
  4407.  
  4408. const fixer = (_ytdApp) => {
  4409. const ytdApp = insp(_ytdApp);
  4410. if (ytdApp && typeof ytdApp.onYtActionBoundListener_ === 'function' && !ytdApp.onYtActionBoundListener57_) {
  4411. ytdApp.onYtActionBoundListener57_ = ytdApp.onYtActionBoundListener_;
  4412. ytdApp.onYtActionBoundListener_ = ytdApp.onYtAction_.bind(ytdApp);
  4413. mbd++;
  4414. }
  4415. }
  4416.  
  4417. observablePromise(() => {
  4418.  
  4419. if (typeof cProto.created === 'function' && !cProto.created56) {
  4420. cProto.created56 = cProto.created;
  4421. cProto.created = function (...args) {
  4422. const r = this.created56(...args);
  4423. fixer(this);
  4424. return r;
  4425. };
  4426. mbd++;
  4427. }
  4428.  
  4429. if (typeof cProto.onYtAction_ === 'function' && !cProto.onYtAction57_) {
  4430. cProto.onYtAction57_ = cProto.onYtAction_;
  4431. cProto.onYtAction_ = function (...args) {
  4432. Promise.resolve().then(() => this.onYtAction57_(...args));
  4433. };
  4434. mbd++;
  4435. }
  4436.  
  4437. if (ytdApp) fixer(ytdApp);
  4438.  
  4439. /*
  4440. const actionRouter_ = ytdApp ? ytdApp.actionRouter_ : null;
  4441. if (actionRouter_ && typeof actionRouter_.handleAction === 'function' && !actionRouter_.handleAction57) {
  4442. actionRouter_.handleAction57 = actionRouter_.handleAction;
  4443. actionRouter_.handleAction = function (...args) {
  4444. Promise.resolve().then(() => this.handleAction57(...args));
  4445. }
  4446. mbd++;
  4447. }
  4448. */
  4449.  
  4450. // if(mbd === 3) return 1;
  4451. if (mbd >= 3) return 1;
  4452.  
  4453. }, new Promise(r => setTimeout(r, 1000))).obtain();
  4454.  
  4455. })();
  4456.  
  4457. const observablePromise = (proc, timeoutPromise) => {
  4458. let promise = null;
  4459. return {
  4460. obtain() {
  4461. if (!promise) {
  4462. promise = new Promise(resolve => {
  4463. let mo = null;
  4464. const f = () => {
  4465. let t = proc();
  4466. if (t) {
  4467. mo.disconnect();
  4468. mo.takeRecords();
  4469. mo = null;
  4470. resolve(t);
  4471. }
  4472. }
  4473. mo = new MutationObserver(f);
  4474. mo.observe(document, { subtree: true, childList: true })
  4475. f();
  4476. timeoutPromise && timeoutPromise.then(() => {
  4477. resolve(null)
  4478. });
  4479. });
  4480. }
  4481. return promise
  4482. }
  4483. }
  4484. }
  4485.  
  4486. // let _yt_player_promise = null;
  4487. /*
  4488. const getYtPlayerPromise = () => {
  4489. if (!_yt_player_promise) {
  4490. _yt_player_promise = new Promise(resolve => {
  4491. let cid = setInterval(() => {
  4492. let t = (((window || 0)._yt_player || 0) || 0);
  4493. if (t) {
  4494. clearInterval(cid);
  4495. resolve(t);
  4496. }
  4497. }, 1);
  4498. promiseForTamerTimeout.then(() => {
  4499. resolve(null)
  4500. });
  4501. });
  4502. }
  4503. return _yt_player_promise;
  4504. }
  4505. */
  4506. const _yt_player_observable = observablePromise(() => {
  4507. return (((window || 0)._yt_player || 0) || 0);
  4508. }, promiseForTamerTimeout);
  4509.  
  4510. const polymerObservable = observablePromise(() => {
  4511. const Polymer = window.Polymer;
  4512. if (typeof Polymer !== 'function') return;
  4513. if (!(Polymer.Base || 0).connectedCallback || !(Polymer.Base || 0).disconnectedCallback) return;
  4514. return Polymer;
  4515. }, promiseForTamerTimeout);
  4516.  
  4517. const schedulerInstanceObservable = observablePromise(() => {
  4518. return (((window || 0).ytglobal || 0).schedulerInstanceInstance_ || 0);
  4519. }, promiseForTamerTimeout);
  4520.  
  4521. const timelineObservable = observablePromise(() => {
  4522. let t = (((document || 0).timeline || 0) || 0);
  4523. if (t && typeof t._play === 'function') {
  4524. return t;
  4525. }
  4526. }, promiseForTamerTimeout);
  4527. const animationObservable = observablePromise(() => {
  4528. let t = (((window || 0).Animation || 0) || 0);
  4529. if (t && typeof t === 'function' && t.length === 2 && typeof t.prototype._updatePromises === 'function') {
  4530. return t;
  4531. }
  4532. }, promiseForTamerTimeout);
  4533.  
  4534.  
  4535.  
  4536.  
  4537. const generalEvtHandler = async (_evKey, _fvKey, _debug) => {
  4538.  
  4539. const evKey = `${_evKey}`;
  4540. const fvKey = `${_fvKey}`;
  4541. const debug = !!_debug;
  4542.  
  4543. const _yt_player = await _yt_player_observable.obtain();
  4544.  
  4545.  
  4546. if (!_yt_player || typeof _yt_player !== 'object') return;
  4547.  
  4548.  
  4549. const getArr = (_yt_player) => {
  4550.  
  4551. let arr = [];
  4552.  
  4553. for (const [k, v] of Object.entries(_yt_player)) {
  4554.  
  4555. const p = typeof v === 'function' ? v.prototype : 0;
  4556. if (p
  4557. && typeof p[evKey] === 'function' && p[evKey].length >= 0 && !p[fvKey]
  4558.  
  4559. ) {
  4560. arr = addProtoToArr(_yt_player, k, arr) || arr;
  4561.  
  4562. }
  4563.  
  4564. }
  4565.  
  4566. if (arr.length === 0) {
  4567.  
  4568. console.warn(`Key prop [${evKey}] does not exist.`);
  4569. } else {
  4570.  
  4571. return arr;
  4572. }
  4573.  
  4574. };
  4575.  
  4576. const arr = getArr(_yt_player);
  4577.  
  4578.  
  4579. if (!arr) return;
  4580.  
  4581. debug && console.log(`FIX_${evKey}`, arr);
  4582.  
  4583. const f = function (...args) {
  4584. Promise.resolve().then(() => this[fvKey](...args));
  4585. };
  4586.  
  4587.  
  4588. for (const k of arr) {
  4589.  
  4590. const g = _yt_player;
  4591. const gk = g[k];
  4592. const gkp = gk.prototype;
  4593.  
  4594. debug && console.log(237, k, gkp)
  4595.  
  4596. if (typeof gkp[evKey] == 'function' && !gkp[fvKey]) {
  4597. gkp[fvKey] = gkp[evKey];
  4598. gkp[evKey] = f;
  4599. }
  4600. }
  4601.  
  4602.  
  4603.  
  4604.  
  4605. }
  4606.  
  4607. FIX_onVideoDataChange && generalEvtHandler('onVideoDataChange', 'onVideoDataChange57');
  4608. // FIX_onClick && generalEvtHandler('onClick', 'onClick57');
  4609. FIX_onStateChange && generalEvtHandler('onStateChange', 'onStateChange57');
  4610. FIX_onLoopRangeChange && generalEvtHandler('onLoopRangeChange', 'onLoopRangeChange57');
  4611. if (FIX_VideoEVENTS_v2) {
  4612. const FIX_VideoEVENTS_DEBUG = 0;
  4613. generalEvtHandler('onVideoProgress', 'onVideoProgress57', FIX_VideoEVENTS_DEBUG); // --
  4614. // generalEvtHandler('onAutoplayBlocked', 'onAutoplayBlocked57', FIX_VideoEVENTS_DEBUG);
  4615. // generalEvtHandler('onLoadProgress', 'onLoadProgress57', FIX_VideoEVENTS_DEBUG); // << CAUSE ISSUE >>
  4616. generalEvtHandler('onFullscreenChange', 'onFullscreenChange57', FIX_VideoEVENTS_DEBUG); // --
  4617. // generalEvtHandler('onLoadedMetadata', 'onLoadedMetadata57', FIX_VideoEVENTS_DEBUG);
  4618. // generalEvtHandler('onDrmOutputRestricted', 'onDrmOutputRestricted57', FIX_VideoEVENTS_DEBUG);
  4619. // generalEvtHandler('onAirPlayActiveChange', 'onAirPlayActiveChange57', FIX_VideoEVENTS_DEBUG);
  4620. // generalEvtHandler('onAirPlayAvailabilityChange', 'onAirPlayAvailabilityChange57', FIX_VideoEVENTS_DEBUG);
  4621. // generalEvtHandler('onApiChange', 'onApiChange57', FIX_VideoEVENTS_DEBUG);
  4622.  
  4623. }
  4624. // onMutedAutoplayChange
  4625. // onVolumeChange
  4626. // onPlaybackRateChange
  4627.  
  4628. // onAirPlayActiveChange
  4629. // onAirPlayAvailabilityChange
  4630. // onApiChange
  4631. // onAutoplayBlocked
  4632. // onDrmOutputRestricted
  4633. // onFullscreenChange
  4634. // onLoadProgress
  4635. // onLoadedMetadata
  4636. // onVideoDataChange
  4637. // onVideoProgress
  4638.  
  4639.  
  4640. (ENABLE_discreteTasking || UNLOAD_DETACHED_POLYMER || FIX_Polymer_dom) && (async () => {
  4641.  
  4642. const Polymer = await polymerObservable.obtain();
  4643. if (!Polymer) return;
  4644.  
  4645. if (FIX_Polymer_dom) {
  4646.  
  4647. const checkPDFuncValue = (pd) => {
  4648. return pd && pd.writable && pd.enumerable && pd.configurable && typeof pd.value == 'function'
  4649. }
  4650. const checkPDFuncValue2 = (pd) => {
  4651. return pd && typeof pd.value == 'function'
  4652. }
  4653.  
  4654. const checkPDFuncGet = (pd) => {
  4655. return pd && typeof pd.get == 'function'
  4656. }
  4657.  
  4658. const domX = Polymer.dom(document.createElement('null'));
  4659. const domXP = (((domX || 0).constructor || 0).prototype || 0);
  4660. const pd1 = Object.getOwnPropertyDescriptor(domXP, 'getOwnerRoot');
  4661. const pd2 = Object.getOwnPropertyDescriptor(Node.prototype, 'parentElement');
  4662. const pd3 = Object.getOwnPropertyDescriptor(domXP, 'querySelector'); // undefined
  4663. const pd4 = Object.getOwnPropertyDescriptor(Element.prototype, 'querySelector');
  4664. const pd4b = Object.getOwnPropertyDescriptor(Document.prototype, 'querySelector');
  4665. const pd5 = Object.getOwnPropertyDescriptor(domXP, 'querySelectorAll'); // undefined
  4666. const pd6 = Object.getOwnPropertyDescriptor(Element.prototype, 'querySelectorAll');
  4667. const pd6b = Object.getOwnPropertyDescriptor(Document.prototype, 'querySelectorAll');
  4668.  
  4669.  
  4670. // getOwnerRoot - to be reviewed
  4671. if (0 && checkPDFuncValue(pd1) && checkPDFuncGet(pd2) && !domXP.getOwnerRoot15 && typeof domXP.getOwnerRoot === 'function') {
  4672.  
  4673. domXP.getOwnerRoot15 = domXP.getOwnerRoot;
  4674. domXP.getOwnerRoot = function () {
  4675. try {
  4676. const p = this.node;
  4677.  
  4678. if (p instanceof HTMLElement) {
  4679. const pp = pd2.get.call(p);
  4680. if (pp instanceof HTMLElement && pp.isConnected === true) {
  4681. return pp.getRootNode();
  4682. }
  4683.  
  4684. }
  4685. } catch (e) { }
  4686. return this.getOwnerRoot15();
  4687. }
  4688.  
  4689. Polymer.__fixedGetOwnerRoot__ = 1;
  4690. }
  4691.  
  4692.  
  4693.  
  4694.  
  4695. if ((!pd3 || checkPDFuncValue(pd3)) && checkPDFuncValue2(pd4) && checkPDFuncValue2(pd4b) && !('querySelector15' in domXP)) {
  4696.  
  4697. domXP.querySelector15 = domXP.querySelector;
  4698.  
  4699. const querySelectorFn = function (query) {
  4700. try {
  4701. const p = this.node;
  4702.  
  4703. // if (p instanceof HTMLElement && p.isConnected === true) {
  4704. // return pd4.value.call(p, query);
  4705. // }
  4706.  
  4707. if (p instanceof Document && p.isConnected === true) {
  4708. return pd4b.value.call(p, query);
  4709. }
  4710.  
  4711. } catch (e) { }
  4712. return this.querySelector15(query);
  4713. }
  4714.  
  4715. Object.defineProperty(domXP, 'querySelector', {
  4716. get() {
  4717. return querySelectorFn;
  4718. },
  4719. set(nv) {
  4720. if (nv === querySelectorFn) return true;
  4721. this.querySelector15 = nv;
  4722. return true;
  4723. },
  4724.  
  4725. enumerable: false,
  4726. configurable: true
  4727. });
  4728.  
  4729. Polymer.__fixedQuerySelector__ = 1;
  4730. }
  4731.  
  4732. if ((!pd5 || checkPDFuncValue(pd5)) && checkPDFuncValue2(pd6) && checkPDFuncValue2(pd6b) && !('querySelectorAll15' in domXP)) {
  4733.  
  4734. domXP.querySelectorAll15 = domXP.querySelectorAll;
  4735.  
  4736. const querySelectorAllFn = function (query) {
  4737.  
  4738. try {
  4739.  
  4740. const p = this.node;
  4741.  
  4742. // if (p instanceof HTMLElement && p.isConnected === true) {
  4743. // return pd6.value.call(p, query);
  4744. // }
  4745.  
  4746. if (p instanceof Document && p.isConnected === true) {
  4747. return pd6b.value.call(p, query);
  4748. }
  4749.  
  4750. } catch (e) {
  4751.  
  4752. }
  4753. return this.querySelectorAll15(query);
  4754. }
  4755.  
  4756. Object.defineProperty(domXP, 'querySelectorAll', {
  4757. get() {
  4758. return querySelectorAllFn;
  4759. },
  4760. set(nv) {
  4761. if (nv === querySelectorAllFn) return true;
  4762. this.querySelectorAll15 = nv;
  4763. return true;
  4764. },
  4765.  
  4766. enumerable: false,
  4767. configurable: true
  4768. });
  4769.  
  4770. Polymer.__fixedQuerySelectorAll__ = 1;
  4771. }
  4772. }
  4773.  
  4774. if (UNLOAD_DETACHED_POLYMER && typeof Polymer.Base.detached === 'function' && !Polymer.Base.detached92 && Polymer.Base.detached.length === 0) {
  4775. Polymer.Base.detached92 = Polymer.Base.detached;
  4776.  
  4777. const detachedPlus = async function (elem) {
  4778. await delay300.then();
  4779. if (elem.isAttached !== false) return;
  4780. await delay300.then();
  4781. if (elem.isAttached !== false) return;
  4782.  
  4783. if (elem.__dataClientsReady === true) elem.__dataClientsReady = false;
  4784. // if (elem.__dataEnabled === true) elem.__dataEnabled = false;
  4785. if (elem.__dataReady === true) elem.__dataReady = false;
  4786.  
  4787. elem.__dataLinkedPaths = elem.__dataToNotify = elem.__dataPendingClients = null;
  4788. elem.__dataHasPaths = false;
  4789. // elem.__dataCompoundStorage = null;
  4790. elem.__dataHost = null;
  4791. elem.__dataTemp = null;
  4792. elem.__dataClientsInitialized = false;
  4793.  
  4794.  
  4795. // elem.data = {};
  4796. elem.data = null;
  4797. elem.__dataPending = null;
  4798. elem.__dataOld = null;
  4799. elem.__dataInstanceProps = null;
  4800.  
  4801. elem.__dataCounter = 0;
  4802. elem.__serializing = false;
  4803.  
  4804. }
  4805. Polymer.Base.detached = function () {
  4806. Promise.resolve(this).then(detachedPlus);
  4807. return Polymer.Base.detached92();
  4808. };
  4809. }
  4810.  
  4811.  
  4812. if (ENABLE_discreteTasking) {
  4813.  
  4814. Polymer.Base.__connInit__ = function () {
  4815. setupDiscreteTasks(this);
  4816. // if (WEAK_REF_BINDING && (this.is || this instanceof Node)) {
  4817. // setupWeakRef(this)
  4818. // }
  4819. }
  4820.  
  4821.  
  4822. /** @type {Function} */
  4823. const connectedCallbackK = function (...args) {
  4824. !this.mh35 && typeof this.__connInit__ === 'function' && this.__connInit__();
  4825. const r = this[qm53](...args);
  4826. !this.mh35 && typeof this.__connInit__ === 'function' && this.__connInit__();
  4827. this.mh35 = 1;
  4828. return r;
  4829. };
  4830.  
  4831. connectedCallbackK.m353 = 1;
  4832.  
  4833.  
  4834. const qt53 = Polymer.Base.connectedCallback;
  4835. Polymer.Base[qm53] = dmf.get(qt53) || qt53;
  4836.  
  4837. Polymer.Base.connectedCallback = connectedCallbackK;
  4838.  
  4839.  
  4840. /** @type {Function} */
  4841. const createdK = function (...args) {
  4842. !this.mh36 && typeof this.__connInit__ === 'function' && this.__connInit__();
  4843. const r = this[qn53](...args);
  4844. !this.mh36 && typeof this.__connInit__ === 'function' && this.__connInit__();
  4845. this.mh36 = 1;
  4846. return r;
  4847. };
  4848.  
  4849.  
  4850. createdK.m353 = 1;
  4851. Polymer.Base[qn53] = Polymer.Base.created;
  4852. Polymer.Base.created = createdK;
  4853.  
  4854. }
  4855.  
  4856. })();
  4857.  
  4858.  
  4859. /*
  4860.  
  4861. e.nativeAppendChild = d.prototype.appendChild,
  4862. d.prototype.appendChild = function(h) {
  4863. return function(l) {
  4864. if (l instanceof DocumentFragment) {
  4865. var m = Array.from(l.children);
  4866. l = h.nativeAppendChild.call(this, l);
  4867. if (this.isConnected) {
  4868. m = g(m);
  4869. for (var p = m.next(); !p.done; p = m.next())
  4870. YD(p.value)
  4871. }
  4872. return l
  4873. }
  4874. m = l instanceof Element && l.isConnected;
  4875. p = h.nativeAppendChild.call(this, l);
  4876. m && ZD(l);
  4877. this.isConnected && YD(l);
  4878. return p
  4879. }
  4880. }(e),
  4881.  
  4882. */
  4883.  
  4884. CHANGE_appendChild && !Node.prototype.appendChild73 && Node.prototype.appendChild && (() => {
  4885.  
  4886. let __src__ = '';
  4887. const handlerCanplay = (evt) => {
  4888. const a = evt.target;
  4889. console.log('[yt-js-engine-tamer]', `video element added to dom | canplay`, mWeakRef(a), a.readyState, a.networkState, a.currentTime);
  4890. if (a.currentTime < 1e-8 && a.currentTime > -1e-9 && a.autoplay === false) a.currentTime += 1e-8;
  4891. };
  4892.  
  4893. const handlerTimeupdate = (evt) => {
  4894. const a = evt.target;
  4895. console.log('[yt-js-engine-tamer]', `video element added to dom | ontimeupdate`, mWeakRef(a), a.readyState, a.networkState, a.currentTime);
  4896. if (a.duration < 2.01 && a.duration > 1.99 && a.currentSrc === __src__) {
  4897. try {
  4898. URL.revokeObjectURL(__src__);
  4899. __src__ = '';
  4900. } finally {
  4901. console.log('[yt-js-engine-tamer]', `video element added to dom | revokeObjectURL`, mWeakRef(a), a.readyState, a.networkState, a.currentTime);
  4902. }
  4903. }
  4904. };
  4905.  
  4906. const f = Node.prototype.appendChild73 = Node.prototype.appendChild;
  4907. if (f) Node.prototype.appendChild = function (a) {
  4908. if (this instanceof Element) { // exclude DocumentFragment
  4909. try {
  4910. if (a instanceof HTMLVideoElement && FIX_VIDEO_BLOCKING && typeof AbortSignal !== 'undefined') {
  4911. const src = `${a.src}`;
  4912. const b = src.length > 5 && src.startsWith('blob:') && typeof a.ontimeupdate === 'function' && a.autoplay === false && a.paused === true && a.isConnected === false;
  4913. if (b) {
  4914. __src__ = src;
  4915. a.addEventListener('canplay', handlerCanplay, { once: true, passive: true, capture: false });
  4916. a.addEventListener('timeupdate', handlerTimeupdate, { once: true, passive: true, capture: false });
  4917. }
  4918. console.log('[yt-js-engine-tamer]', `video element added to dom | treatment = ${b}`, mWeakRef(a), a.readyState, a.networkState);
  4919. } else {
  4920. let checkFragmentA = true;
  4921. if (!NO_PRELOAD_GENERATE_204_BYPASS && document.head === this) {
  4922. if (headLinkCollection === null) headLinkCollection = document.head.getElementsByTagName('LINK');
  4923. for (const node of headLinkCollection) {
  4924. if (node.rel === 'preload' && node.as === 'fetch') {
  4925. node.rel = 'prefetch'; // see https://github.com/GoogleChromeLabs/quicklink
  4926. }
  4927. }
  4928. } else if (this.nodeName.startsWith('YT-')) { // yt-animated-rolling-number, yt-attributed-string
  4929. checkFragmentA = false;
  4930. }
  4931. if ((a instanceof DocumentFragment) && checkFragmentA && a.firstElementChild === null) {
  4932. // no element in fragmentA
  4933. let doNormal = false;
  4934. for (let child = a.firstChild; child instanceof Node; child = child.nextSibling) {
  4935. if (child.nodeType === 3) { doNormal = true; break; }
  4936. }
  4937. if (!doNormal) return a;
  4938. }
  4939. }
  4940. } catch (e) {
  4941. console.log(e);
  4942. }
  4943. }
  4944. return arguments.length === 1 && this.appendChild73 ? this.appendChild73(a) : (this.appendChild73 || Node.prototype.appendChild73 || f).apply(this, arguments);
  4945. }
  4946.  
  4947.  
  4948. })();
  4949.  
  4950. if (FIX_Shady) {
  4951.  
  4952. observablePromise(() => {
  4953. const { ShadyDOM, ShadyCSS } = window;
  4954. if (ShadyDOM) {
  4955. ShadyDOM.handlesDynamicScoping = false; // 9 of 10
  4956. ShadyDOM.noPatch = true; // 1 of 10
  4957. ShadyDOM.patchOnDemand = false; // 1 of 10
  4958. ShadyDOM.preferPerformance = true; // 1 of 10
  4959. ShadyDOM.querySelectorImplementation = undefined; // 1 of 10
  4960. }
  4961. if (ShadyCSS) {
  4962. ShadyCSS.nativeCss = true; // 1 of 10
  4963. ShadyCSS.nativeShadow = true; // 6 of 10
  4964. ShadyCSS.cssBuild = undefined; // 1 of 10
  4965. ShadyCSS.disableRuntime = true; // 1 of 10
  4966. }
  4967. if (ShadyDOM && ShadyCSS) return 1;
  4968. }, promiseForTamerTimeout).obtain(); // clear until 1 is return
  4969.  
  4970. }
  4971.  
  4972.  
  4973. // let schedulerInstancePropOfTimerType = '';
  4974. // let schedulerInstancePropOfTimerId = '';
  4975. (FIX_schedulerInstanceInstance & 2) && (async () => {
  4976.  
  4977. const schedulerInstanceInstance_ = await schedulerInstanceObservable.obtain();
  4978.  
  4979. if (!schedulerInstanceInstance_) return;
  4980.  
  4981. const checkOK = typeof schedulerInstanceInstance_.start === 'function' && !schedulerInstanceInstance_.start993 && !schedulerInstanceInstance_.stop && !schedulerInstanceInstance_.cancel && !schedulerInstanceInstance_.terminate && !schedulerInstanceInstance_.interupt;
  4982. if (checkOK) {
  4983.  
  4984. schedulerInstanceInstance_.start993 = schedulerInstanceInstance_.start;
  4985.  
  4986. let requestingFn = null;
  4987. let requestingArgs = null;
  4988.  
  4989. const f = function () {
  4990. requestingFn = this.fn;
  4991. requestingArgs = [...arguments];
  4992. return 12373;
  4993. };
  4994.  
  4995. const fakeFns = [
  4996. f.bind({ fn: requestAnimationFrame }),
  4997. f.bind({ fn: setInterval }),
  4998. f.bind({ fn: setTimeout }),
  4999. f.bind({ fn: requestIdleCallback })
  5000. ];
  5001.  
  5002. let mzt = 0;
  5003.  
  5004. let _fnSelectorProp = null;
  5005. const mkFns = new Array(4);
  5006.  
  5007. /*
  5008. case 1:
  5009. var a = this.K;
  5010. this.g = this.I ? window.requestIdleCallback(a, {
  5011. timeout: 3E3
  5012. }) : window.setTimeout(a, ma);
  5013. break;
  5014. case 2:
  5015. this.g = window.setTimeout(this.M, this.N);
  5016. break;
  5017. case 3:
  5018. this.g = window.requestAnimationFrame(this.L);
  5019. break;
  5020. case 4:
  5021. this.g = window.setTimeout(this.J, 0)
  5022. }
  5023.  
  5024. */
  5025. const startFnHandler = {
  5026. get(target, prop, receiver) {
  5027. if (prop === '$$12377$$') return true;
  5028. if (prop === '$$12378$$') return target;
  5029.  
  5030. // console.log('get',prop)
  5031. return target[prop]
  5032. },
  5033. set(target, prop, value, receiver) {
  5034. // console.log('set', prop, value)
  5035.  
  5036. if (value >= 1 && value <= 4) _fnSelectorProp = prop;
  5037. if (value === 12373 && _fnSelectorProp) {
  5038.  
  5039. const schedulerTypeSelection = target[_fnSelectorProp];
  5040. const timerIdProp = prop;
  5041.  
  5042. // if (schedulerTypeSelection && schedulerTypeSelection >= 1 && schedulerTypeSelection <= 4 && timerIdProp) {
  5043. // schedulerInstancePropOfTimerType = _fnSelectorProp || '';
  5044. // schedulerInstancePropOfTimerId = timerIdProp || '';
  5045. // }
  5046.  
  5047. if (schedulerTypeSelection === 3 && requestingFn === requestAnimationFrame) { // rAF(fn)
  5048. target[timerIdProp] = baseRAF.apply(window, requestingArgs);
  5049. } else if (schedulerTypeSelection === 2 && requestingFn === setTimeout) { // setTimeout(fn, delay)
  5050. // rare
  5051. target[timerIdProp] = mkFns[2].apply(window, requestingArgs);
  5052. } else if (schedulerTypeSelection === 4 && requestingFn === setTimeout && !requestingArgs[1]) { // setTimeout(fn, 0)
  5053. // often
  5054. if ((FIX_schedulerInstanceInstance & 4) && typeof nextBrowserTick == 'function') {
  5055. const f = requestingArgs[0];
  5056. const tir = ++mzt;
  5057. nextBrowserTick(() => {
  5058. if (target[timerIdProp] === -tir) f();
  5059. });
  5060. target[_fnSelectorProp] = 940;
  5061. target[timerIdProp] = -tir;
  5062. } else {
  5063. const f = requestingArgs[0];
  5064. const tir = ++mzt;
  5065. Promise.resolve().then(() => {
  5066. if (target[timerIdProp] === -tir) f();
  5067. });
  5068. target[_fnSelectorProp] = 930;
  5069. target[timerIdProp] = -tir;
  5070. }
  5071. } else if (schedulerTypeSelection === 1 && (requestingFn === requestIdleCallback || requestingFn === setTimeout)) { // setTimeout(requestIdleCallback)
  5072. // often
  5073. if (requestingFn === requestIdleCallback) {
  5074. target[timerIdProp] = requestIdleCallback.apply(window, requestingArgs);
  5075. } else {
  5076. target[timerIdProp] = mkFns[2].apply(window, requestingArgs);
  5077. }
  5078. } else {
  5079. target[_fnSelectorProp] = 0;
  5080. target[timerIdProp] = 0;
  5081. }
  5082. } else {
  5083. target[prop] = value;
  5084. }
  5085. return true;
  5086. }
  5087. };
  5088.  
  5089. let startBusy = false;
  5090. schedulerInstanceInstance_.start = function () {
  5091. if (startBusy) return;
  5092. startBusy = true;
  5093. try {
  5094. mkFns[0] = window.requestAnimationFrame;
  5095. mkFns[1] = window.setInterval;
  5096. mkFns[2] = window.setTimeout;
  5097. mkFns[3] = window.requestIdleCallback;
  5098. const tThis = this['$$12378$$'] || this;
  5099. window.requestAnimationFrame = fakeFns[0]
  5100. window.setInterval = fakeFns[1]
  5101. window.setTimeout = fakeFns[2]
  5102. window.requestIdleCallback = fakeFns[3]
  5103. _fnSelectorProp = null;
  5104. tThis.start993.call(new Proxy(tThis, startFnHandler));
  5105. _fnSelectorProp = null;
  5106. window.requestAnimationFrame = mkFns[0];
  5107. window.setInterval = mkFns[1];
  5108. window.setTimeout = mkFns[2];
  5109. window.requestIdleCallback = mkFns[3];
  5110. } catch (e) {
  5111. console.warn(e);
  5112. }
  5113. startBusy = false;
  5114. }
  5115.  
  5116. schedulerInstanceInstance_.start.toString = schedulerInstanceInstance_.start993.toString.bind(schedulerInstanceInstance_.start993);
  5117.  
  5118. }
  5119. })();
  5120.  
  5121. FIX_yt_player && (async () => {
  5122. // rAf scheduling
  5123.  
  5124. const _yt_player = await _yt_player_observable.obtain();
  5125.  
  5126. if (!_yt_player || typeof _yt_player !== 'object') return;
  5127.  
  5128. let keyZqOu = getZqOu(_yt_player);
  5129.  
  5130.  
  5131. if (!keyZqOu) return;
  5132.  
  5133.  
  5134. const g = _yt_player
  5135. let k = keyZqOu
  5136.  
  5137. const gk = g[k];
  5138. if (typeof gk !== 'function') return;
  5139. const gkp = gk.prototype;
  5140.  
  5141. let dummyObject = new gk;
  5142. let nilFunc = () => { };
  5143.  
  5144. let nilObj = {};
  5145.  
  5146. // console.log(1111111111)
  5147.  
  5148. let keyBoolD = '';
  5149. let keyWindow = '';
  5150. let keyFuncC = '';
  5151. let keyCidj = '';
  5152.  
  5153. for (const [t, y] of Object.entries(dummyObject)) {
  5154. if (y instanceof Window) keyWindow = t;
  5155. }
  5156.  
  5157. const dummyObjectProxyHandler = {
  5158. get(target, prop) {
  5159. let v = target[prop]
  5160. if (v instanceof Window && !keyWindow) {
  5161. keyWindow = t;
  5162. }
  5163. let y = typeof v === 'function' ? nilFunc : typeof v === 'object' ? nilObj : v;
  5164. if (prop === keyWindow) y = {
  5165. requestAnimationFrame(f) {
  5166. return 3;
  5167. },
  5168. cancelAnimationFrame() {
  5169.  
  5170. }
  5171. }
  5172. if (!keyFuncC && typeof v === 'function' && !(prop in target.constructor.prototype)) {
  5173. keyFuncC = prop;
  5174. }
  5175. // console.log('[get]', prop, typeof target[prop])
  5176.  
  5177.  
  5178. return y;
  5179. },
  5180. set(target, prop, value) {
  5181.  
  5182. if (typeof value === 'boolean' && !keyBoolD) {
  5183. keyBoolD = prop;
  5184. }
  5185. if (typeof value === 'number' && !keyCidj && value >= 2) {
  5186. keyCidj = prop;
  5187. }
  5188.  
  5189. // console.log('[set]', prop, value)
  5190. target[prop] = value
  5191.  
  5192. return true;
  5193. }
  5194. };
  5195.  
  5196. dummyObject.start.call(new Proxy(dummyObject, dummyObjectProxyHandler));
  5197.  
  5198. // console.log('gkp.start',gkp.start);
  5199. // console.log('gkp.stop',gkp.stop);
  5200. gkp._activation = false;
  5201.  
  5202. gkp.start = function () {
  5203. // p59 || console.log(12100)
  5204. if (!this._activation) {
  5205. this._activation = true;
  5206. foregroundPromiseFn().then(() => {
  5207. this._activation = false;
  5208. if (this[keyCidj]) {
  5209. Promise.resolve().then(this[keyFuncC]);
  5210. }
  5211. });
  5212. }
  5213. this[keyCidj] = 1;
  5214. this[keyBoolD] = true;
  5215. }
  5216. ;
  5217. gkp.stop = function () {
  5218. this[keyCidj] = null
  5219. }
  5220.  
  5221.  
  5222. /*
  5223. g[k].start = function() {
  5224. this.stop();
  5225. this.D = true;
  5226. var a = requestAnimationFrame
  5227. , b = cancelAnimationFrame;
  5228. this.j = a.call(this.B, this.C)
  5229. }
  5230. ;
  5231. g[k].stop = function() {
  5232. if (this.isActive()) {
  5233. var a = requestAnimationFrame
  5234. , b = cancelAnimationFrame;
  5235. b.call(this.B, this.j)
  5236. }
  5237. this.j = null
  5238. }
  5239. */
  5240.  
  5241. const keyzo = PERF_471489_ ? getzo(_yt_player) : null;
  5242.  
  5243. if (keyzo) {
  5244.  
  5245. k = keyzo;
  5246.  
  5247. const attrUpdateFn = g[k];
  5248. // console.log(5992, attrUpdateFn)
  5249. g['$$original$$' + k] = attrUpdateFn;
  5250. const zoTransform = async (a, c) => {
  5251.  
  5252. let transformType = '';
  5253. let transformValue = 0;
  5254. let transformUnit = '';
  5255. let transformTypeI = 0;
  5256.  
  5257. const aStyle = a.style;
  5258.  
  5259. if (c.length < 9) {
  5260.  
  5261. } else if (c.startsWith('scalex(0.') || (c === 'scalex(0)' || c === 'scalex(1)')) {
  5262. let p = c.substring(7, c.length - 1);
  5263. let q = p.length >= 1 ? parseFloat(p) : -1;
  5264. if (q > -1e-5 && q < 1 + 1e-5) {
  5265. transformType = 'scaleX'
  5266. transformValue = q;
  5267. transformUnit = '';
  5268. transformTypeI = 1;
  5269. }
  5270. } else if (c.startsWith('translateX(') && c.endsWith('px)')) {
  5271. let p = c.substring(11, c.length - 3);
  5272. let q = p.length >= 1 ? parseFloat(p) : NaN;
  5273. if (typeof q === 'number' && !isNaN(q)) {
  5274. transformType = 'translateX'
  5275. transformValue = q;
  5276. transformUnit = 'px';
  5277. transformTypeI = 2;
  5278. } else if (p === 'NaN') {
  5279. return;
  5280. }
  5281. } else if (c.startsWith('scaley(0.') || (c === 'scaley(0)' || c === 'scaley(1)')) {
  5282. let p = c.substring(7, c.length - 1);
  5283. let q = p.length >= 1 ? parseFloat(p) : -1;
  5284. if (q > -1e-5 && q < 1 + 1e-5) {
  5285. transformType = 'scaleY'
  5286. transformValue = q;
  5287. transformUnit = '';
  5288. transformTypeI = 1;
  5289. }
  5290. } else if (c.startsWith('translateY(') && c.endsWith('px)')) {
  5291. let p = c.substring(11, c.length - 3);
  5292. let q = p.length >= 1 ? parseFloat(p) : NaN;
  5293. if (typeof q === 'number' && !isNaN(q)) {
  5294. transformType = 'translateY'
  5295. transformValue = q;
  5296. transformUnit = 'px';
  5297. transformTypeI = 2;
  5298. } else if (p === 'NaN') {
  5299. return;
  5300. }
  5301. } else if (c.startsWith('scalex(') && c.includes('e-')) {
  5302. // scalex(1.252057684158767e-16)
  5303. // scalex(3.0393632069734948e-9)
  5304. let p = c.substring(7, c.length - 1);
  5305. let q = p.length >= 1 ? parseFloat(p) : -1;
  5306. if (q > -1e-5 && q < 1e-5) {
  5307. transformType = 'scaleX'
  5308. transformValue = 0;
  5309. transformUnit = '';
  5310. transformTypeI = 1;
  5311. }
  5312. } else if (c.startsWith('scaley(') && c.includes('e-')) {
  5313. let p = c.substring(7, c.length - 1);
  5314. let q = p.length >= 1 ? parseFloat(p) : -1;
  5315. if (q > -1e-5 && q < 1e-5) {
  5316. transformType = 'scaleY'
  5317. transformValue = 0;
  5318. transformUnit = '';
  5319. transformTypeI = 1;
  5320. }
  5321. }
  5322.  
  5323. if (transformTypeI === 1) {
  5324. const q = Math.round(transformValue * steppingScaleN) / steppingScaleN;
  5325. const vz = toFixed2(q, 3);
  5326. c = `${transformType}(${vz})`;
  5327. const cv = aStyle.transform;
  5328. if (c === cv) return;
  5329. aStyle.transform = c;
  5330. } else if (transformTypeI === 2) {
  5331. const q = transformValue;
  5332. const vz = toFixed2(q, 1);
  5333. c = `${transformType}(${vz}${transformUnit})`;
  5334. const cv = aStyle.transform;
  5335. if (c === cv) return;
  5336. aStyle.transform = c;
  5337. } else { // eg empty
  5338. const cv = aStyle.transform;
  5339. if (!c && !cv) return;
  5340. else if (c === cv) return;
  5341. aStyle.transform = c;
  5342. }
  5343.  
  5344. };
  5345.  
  5346. const elmTransformTemp = new WeakMap();
  5347. const elmPropTemps = {
  5348. 'display': new WeakMap(),
  5349. 'width': new WeakMap(),
  5350. 'height': new WeakMap(),
  5351. 'outlineWidth': new WeakMap(),
  5352. 'position': new WeakMap(),
  5353. 'padding': new WeakMap(),
  5354. "cssText": new WeakMap(),
  5355. "right": new WeakMap(),
  5356. "left": new WeakMap(),
  5357. "top": new WeakMap(),
  5358. "bottom": new WeakMap(),
  5359. "transitionDelay": new WeakMap(),
  5360. "marginLeft": new WeakMap(),
  5361. "marginTop": new WeakMap(),
  5362. "marginRight": new WeakMap(),
  5363. "marginBottom": new WeakMap(),
  5364. }
  5365.  
  5366. const ns5 = Symbol();
  5367. const nextModify = (a, c, m, f, immediate) => {
  5368. const a_ = a;
  5369. const m_ = m;
  5370. const noKey = !m_.has(a_);
  5371. if (immediate || noKey) {
  5372. m_.set(a_, ns5);
  5373. f(a_, c);
  5374. noKey && nextBrowserTick_(() => {
  5375. const d = m_.get(a_);
  5376. if (d === undefined) return;
  5377. m_.delete(a_);
  5378. if (d !== ns5) f(a_, d);
  5379. });
  5380. } else {
  5381. m_.set(a_, c);
  5382. }
  5383. };
  5384.  
  5385. const set66 = new Set();
  5386. // const set77 = new Set(['top', 'left', 'bottom', 'right']); // caption positioning - immediate change
  5387.  
  5388. const modifiedFn = function (a, b, c, immediateChange = false) { // arrow function does not have function.prototype
  5389.  
  5390. // console.log(140000, a, b, c);
  5391. if (typeof c === 'number' && typeof b === 'string' && a instanceof HTMLElement) {
  5392. const num = c;
  5393. c = `${num}`;
  5394. if (c.length > 5) c = (num < 10 && num > -10) ? toFixed2(num, 3) : toFixed2(num, 1);
  5395. }
  5396.  
  5397. if (typeof b === 'string' && typeof c === 'string' && a instanceof HTMLElement) {
  5398.  
  5399. let elmPropTemp = null;
  5400.  
  5401. if (b === "transform") {
  5402.  
  5403. nextModify(a, c, elmTransformTemp, zoTransform, immediateChange);
  5404. return;
  5405.  
  5406. } else if (elmPropTemp = elmPropTemps[b]) {
  5407.  
  5408. // if (c.length > 5 && c.includes('.')) {
  5409. // console.log(123213, c)
  5410. // }
  5411.  
  5412. const b_ = b;
  5413. nextModify(a, c, elmPropTemp, (a, c) => {
  5414. const style = a.style;
  5415. const cv = style[b_];
  5416. if (!cv && !c) return;
  5417. if (cv === c) return;
  5418. style[b_] = c;
  5419. }, immediateChange);
  5420. return;
  5421.  
  5422. } else if (b === "outline-width") {
  5423.  
  5424. const b_ = 'outlineWidth';
  5425. elmPropTemp = elmPropTemps[b_];
  5426. nextModify(a, c, elmPropTemp, (a, c) => {
  5427. const style = a.style;
  5428. const cv = style[b_];
  5429. if (!cv && !c) return;
  5430. if (cv === c) return;
  5431. style[b_] = c;
  5432. }, immediateChange);
  5433. return;
  5434.  
  5435. } else if (b === 'maxWidth' || b === 'maxHeight') {
  5436. // I think these can be directly assigned.
  5437.  
  5438. const b_ = b;
  5439. const style = a.style;
  5440. const cv = style[b_];
  5441. if (!cv && !c) return;
  5442. if (cv === c) return;
  5443. style[b_] = c;
  5444. return;
  5445.  
  5446. } else {
  5447. // if(immediate && elmPropTemps[b]){
  5448. // console.log(5191, b)
  5449. // }
  5450. // caption-window
  5451. // margin-left max-height max-width font-family fill color font-size background white-space margin
  5452. // text-align background-color
  5453. // console.log(27304, a, b, c)
  5454. if (!set66.has(b)) {
  5455. set66.add(b);
  5456. nextBrowserTick_(() => {
  5457. if (!a.classList.contains('caption-window') && !a.classList.contains('ytp-caption-segment')) {
  5458. console.log(27304, a, b, c)
  5459. }
  5460. })
  5461. }
  5462. }
  5463.  
  5464. attrUpdateFn.call(this, a, b, c);
  5465. return;
  5466. } else if (typeof (b || 0) === 'object') {
  5467.  
  5468. // this is to fix caption positioning
  5469. // const immediate = (a.id || 0).length > 14 && (('top' in b) || ('left' in b) || ('right' in b) || ('bottom' in b));
  5470. const immediate = (a.id || 0).length > 14;
  5471. for (const [k, v] of Object.entries(b)) {
  5472. modifiedFn.call(this, a, k, v, immediate);
  5473. }
  5474.  
  5475. } else {
  5476. console.log(27306, a, b, c);
  5477.  
  5478. attrUpdateFn.call(this, a, b, c);
  5479. return;
  5480. }
  5481.  
  5482. // console.log(130000, a, b, c);
  5483.  
  5484. };
  5485. g[k] = modifiedFn;
  5486.  
  5487.  
  5488. /*
  5489.  
  5490. g.zo = function(a, b, c) {
  5491. if ("string" === typeof b)
  5492. (b = yo(a, b)) && (a.style[b] = c);
  5493. else
  5494. for (var d in b) {
  5495. c = a;
  5496. var e = b[d]
  5497. , f = yo(c, d);
  5498. f && (c.style[f] = e)
  5499. }
  5500. }
  5501.  
  5502.  
  5503. */
  5504.  
  5505.  
  5506. }
  5507.  
  5508.  
  5509.  
  5510. const keyuG = PERF_471489_ ? getuG(_yt_player) : null;
  5511.  
  5512. if (keyuG) {
  5513.  
  5514. k = keyuG;
  5515.  
  5516. const gk = g[k];
  5517. const gkp = gk.prototype;
  5518.  
  5519.  
  5520. /** @type { Map<string, WeakMap<any, any>> } */
  5521. const ntLogs = new Map();
  5522.  
  5523. if (typeof gkp.updateValue === 'function' && gkp.updateValue.length === 2 && !gkp.updateValue31) {
  5524.  
  5525. gkp.updateValue31 = gkp.updateValue;
  5526. gkp.updateValue = function (a, b) {
  5527. if (typeof a !== 'string') return this.updateValue31(a, b);
  5528.  
  5529. const element = this.element;
  5530. if (!(element instanceof HTMLElement)) return this.updateValue31(a, b);
  5531.  
  5532. let ntLog = ntLogs.get(a);
  5533. if (!ntLog) ntLogs.set(a, (ntLog = new WeakMap()));
  5534.  
  5535. let cache = ntLog.get(element);
  5536. if (cache && cache.value === b) {
  5537. return;
  5538. }
  5539. if (!cache) {
  5540. this.__oldValueByUpdateValue__ = null;
  5541. ntLog.set(element, cache = { value: b });
  5542. } else {
  5543. this.__oldValueByUpdateValue__ = cache.value;
  5544. cache.value = b;
  5545. }
  5546.  
  5547. return this.updateValue31(a, b);
  5548. }
  5549.  
  5550. /*
  5551. g.k.update = function(a) {
  5552. for (var b = g.u(Object.keys(a)), c = b.next(); !c.done; c = b.next())
  5553. c = c.value,
  5554. this.updateValue(c, a[c])
  5555. }
  5556. ;
  5557. g.k.updateValue = function(a, b) {
  5558. (a = this.Td["{{" + a + "}}"]) && wG(this, a[0], a[1], b)
  5559. }
  5560. */
  5561.  
  5562. }
  5563.  
  5564.  
  5565. }
  5566.  
  5567.  
  5568.  
  5569.  
  5570. })();
  5571.  
  5572.  
  5573. FIX_yt_player && FIX_SHORTCUTKEYS > 0 && (async () => {
  5574. // keyboard shortcut keys controller
  5575.  
  5576. const _yt_player = await _yt_player_observable.obtain();
  5577.  
  5578. if (!_yt_player || typeof _yt_player !== 'object') return;
  5579.  
  5580. keyboardController(_yt_player);
  5581.  
  5582. })();
  5583.  
  5584. FIX_yt_player && (async () => {
  5585. // timer scheduling
  5586.  
  5587. const _yt_player = await _yt_player_observable.obtain();
  5588.  
  5589. if (!_yt_player || typeof _yt_player !== 'object') return;
  5590.  
  5591. let keyZqQu = getZqQu(_yt_player);
  5592.  
  5593. if (!keyZqQu) return;
  5594.  
  5595. const g = _yt_player
  5596. let k = keyZqQu
  5597.  
  5598. const gk = g[k];
  5599. if (typeof gk !== 'function') return;
  5600. const gkp = gk.prototype;
  5601.  
  5602. const extractKeysZqQu = () => {
  5603.  
  5604.  
  5605. let _keyeC = '';
  5606. try {
  5607. gkp.stop.call(new Proxy({
  5608. isActive: () => { }
  5609. }, {
  5610. set(target, prop, value) {
  5611. if (value === 0) _keyeC = prop;
  5612. return true;
  5613. }
  5614. }));
  5615. } catch (e) { }
  5616. if (!_keyeC) return;
  5617. const keyeC = _keyeC;
  5618.  
  5619. let keyC = ''; // this.C = this.ST.bind(this)
  5620. let keyhj = ''; // 1000ms
  5621. try {
  5622. gkp.start.call(new Proxy({
  5623. stop: () => { },
  5624. [keyeC]: 0,
  5625. }, {
  5626. get(target, prop) {
  5627. if (prop in target) return target[prop];
  5628. if (!keyC) {
  5629. keyC = prop;
  5630. return null; // throw error
  5631. }
  5632. else if (!keyhj) {
  5633. keyhj = prop;
  5634. }
  5635.  
  5636. }
  5637. }));
  5638. } catch (e) {
  5639. if (!keyC || !keyhj) {
  5640. console.log(e)
  5641. }
  5642. }
  5643.  
  5644. if (!keyC || !keyhj) return;
  5645. let keyST = '';
  5646. let keyj = '';
  5647. let keyB = '';
  5648. let keyxa = '';
  5649.  
  5650. const possibleKs = new Set();
  5651.  
  5652. for (const [k, v] of Object.entries(gkp)) {
  5653. if (k === 'stop' || k === 'start' || k === 'isActive' || k === 'constructor' || k === keyeC || k === keyC || k === keyhj) {
  5654. continue;
  5655. }
  5656. if (typeof v === 'function') {
  5657. const m = /this\.(\w+)\.call\(this\.(\w+)\)/.exec(v + '');
  5658. if (m) {
  5659. keyST = k;
  5660. keyj = m[1];
  5661. keyB = m[2];
  5662. } else {
  5663. possibleKs.add(k);
  5664. }
  5665. }
  5666. }
  5667.  
  5668. if (!keyST || !keyj || !keyB) return;
  5669.  
  5670. for (const k of possibleKs) {
  5671. if (k === keyST || k === keyj || k === keyB) {
  5672. continue;
  5673. }
  5674. const v = gkp[k];
  5675. if (typeof v === 'function' && (v + '').includes(`this.stop();delete this.${keyj};delete this.${keyB}`)) {
  5676. keyxa = k;
  5677. }
  5678. }
  5679.  
  5680. return [keyeC, keyC, keyhj, keyST, keyj, keyB, keyxa];
  5681.  
  5682. }
  5683.  
  5684. const keys = extractKeysZqQu();
  5685. if (!keys || !keys.length) return;
  5686. const [keyeC, keyC, keyhj, keyST, keyj, keyB, keyxa] = keys; // [timerId, binded executorFn, 1000ms, executorFn, dataJ, objectB, disposeFn]
  5687.  
  5688. if (!keyeC || !keyC || !keyhj || !keyST || !keyj || !keyB || !keyxa) return;
  5689.  
  5690. let disposeKeys = null;
  5691.  
  5692. gkp[keyxa] = function () {
  5693. // dispose
  5694. if (!disposeKeys) {
  5695. disposeKeys = Object.getOwnPropertyNames(this).filter(key => {
  5696. if (key != keyeC && key != keyC && key != keyhj && key != keyST && key != keyj && key != keyB && key != keyxa) {
  5697. const t = typeof this[key];
  5698. return t === 'undefined' || t === 'object'
  5699. }
  5700. return false;
  5701. });
  5702. }
  5703. for (const key of disposeKeys) {
  5704. const v = this[key];
  5705. if ((v || 0).length >= 1) v.length = 0; // function (){if(this.fn)for(;this.fn.length;)this.fn.shift()()}
  5706. }
  5707. if (this[keyeC] > 0) this.stop();
  5708. this[keyj] = null;
  5709. this[keyB] = null;
  5710. };
  5711.  
  5712. gkp.start = function (a) {
  5713. if (this[keyeC] > 0) this.stop();
  5714. const delay = void 0 !== a ? a : this[keyhj];
  5715. this[keyeC] = window.setTimeout(this[keyC], delay);
  5716. };
  5717. gkp.stop = function () {
  5718. if (this[keyeC] > 0) {
  5719. window.clearTimeout(this[keyeC]);
  5720. this[keyeC] = 0;
  5721. }
  5722. };
  5723.  
  5724. gkp.isActive = function () {
  5725. return this[keyeC] > 0;
  5726. };
  5727.  
  5728. gkp[keyST] = function () {
  5729. this.stop(); // this[keyeC] = 0;
  5730. const fn = this[keyj];
  5731. const obj = this[keyB];
  5732. let skip = false;
  5733. if (!fn) skip = true;
  5734. else if (IGNORE_bufferhealth_CHECK && obj) {
  5735. let m;
  5736. if ((m = obj[keyC]) instanceof Map || (m = obj[keyj]) instanceof Map) {
  5737. if (m.has("bufferhealth")) skip = true;
  5738. }
  5739. }
  5740. if (!skip) {
  5741. fn.call(obj);
  5742. }
  5743. };
  5744.  
  5745.  
  5746.  
  5747.  
  5748. /*
  5749.  
  5750. g.k.eC = 0;
  5751. g.k.xa = function() {
  5752. g.Qu.Vf.xa.call(this);
  5753. this.stop();
  5754. delete this.j;
  5755. delete this.B
  5756. }
  5757. ;
  5758. g.k.start = function(a) {
  5759. this.stop();
  5760. this.eC = g.gg(this.C, void 0 !== a ? a : this.hj)
  5761. }
  5762. ;
  5763. g.k.stop = function() {
  5764. this.isActive() && g.Sa.clearTimeout(this.eC);
  5765. this.eC = 0
  5766. }
  5767. ;
  5768. g.k.isActive = function() {
  5769. return 0 != this.eC
  5770. }
  5771. ;
  5772. g.k.ST = function() {
  5773. this.eC = 0;
  5774. this.j && this.j.call(this.B)
  5775. }
  5776. ;
  5777. */
  5778.  
  5779.  
  5780.  
  5781.  
  5782. })();
  5783.  
  5784. FIX_Animation_n_timeline && (async () => {
  5785.  
  5786. const [timeline, Animation] = await Promise.all([timelineObservable.obtain(), animationObservable.obtain()]);
  5787.  
  5788. if (!timeline || !Animation) return;
  5789.  
  5790. const aniProto = Animation.prototype;
  5791. // aniProto.sequenceNumber = 0; // native YouTube engine bug - sequenceNumber is not set
  5792.  
  5793. const getXroto = (x) => {
  5794. try {
  5795. return x.__proto__;
  5796. } catch (e) { }
  5797. return null;
  5798. }
  5799. const timProto = getXroto(timeline);
  5800. if (!timProto) return;
  5801. if (
  5802. (
  5803. typeof timProto.getAnimations === 'function' && typeof timProto.play === 'function' &&
  5804. typeof timProto._discardAnimations === 'function' && typeof timProto._play === 'function' &&
  5805. typeof timProto._updateAnimationsPromises === 'function' && !timProto.nofCQ &&
  5806. typeof aniProto._updatePromises === 'function' && !aniProto.nofYH
  5807. )
  5808.  
  5809. ) {
  5810.  
  5811. timProto.nofCQ = 1;
  5812. aniProto.nofYH = 1;
  5813.  
  5814. const originalAnimationsWithPromises = ((_updateAnimationsPromises) => {
  5815.  
  5816.  
  5817. /*
  5818. v.animationsWithPromises = v.animationsWithPromises.filter(function (c) {
  5819. return c._updatePromises();
  5820. });
  5821. */
  5822.  
  5823. const p = Array.prototype.filter;
  5824.  
  5825. let res = null;
  5826. Array.prototype.filter = function () {
  5827.  
  5828. res = this;
  5829. return this;
  5830.  
  5831. };
  5832.  
  5833. _updateAnimationsPromises.call({});
  5834.  
  5835. Array.prototype.filter = p;
  5836.  
  5837. if (res && typeof res.length === 'number') {
  5838. /** @type {any[]} */
  5839. const _res = res;
  5840. return _res;
  5841. }
  5842.  
  5843.  
  5844. return null;
  5845.  
  5846.  
  5847.  
  5848.  
  5849. })(timProto._updateAnimationsPromises);
  5850.  
  5851. if (!originalAnimationsWithPromises || typeof originalAnimationsWithPromises.length !== 'number') return;
  5852.  
  5853. // console.log('originalAnimationsWithPromises', originalAnimationsWithPromises)
  5854.  
  5855. aniProto._updatePromises31 = aniProto._updatePromises;
  5856.  
  5857. /*
  5858. aniProto._updatePromises = function(){
  5859. console.log('eff',this._oldPlayState, this.playState)
  5860. return this._updatePromises31.apply(this, arguments)
  5861. }
  5862. */
  5863.  
  5864. aniProto._updatePromises = function () {
  5865. var oldPlayState = this._oldPlayState;
  5866. var newPlayState = this.playState;
  5867. // console.log('ett', oldPlayState, newPlayState)
  5868. if (newPlayState !== oldPlayState) {
  5869. this._oldPlayState = newPlayState;
  5870. if (this._readyPromise) {
  5871. if ("idle" == newPlayState) {
  5872. this._rejectReadyPromise();
  5873. this._readyPromise = void 0;
  5874. } else if ("pending" == oldPlayState) {
  5875. this._resolveReadyPromise();
  5876. } else if ("pending" == newPlayState) {
  5877. this._readyPromise = void 0;
  5878. }
  5879. }
  5880. if (this._finishedPromise) {
  5881. if ("idle" == newPlayState) {
  5882. this._rejectFinishedPromise();
  5883. this._finishedPromise = void 0;
  5884. } else if ("finished" == newPlayState) {
  5885. this._resolveFinishedPromise();
  5886. } else if ("finished" == oldPlayState) {
  5887. this._finishedPromise = void 0;
  5888. }
  5889. }
  5890. }
  5891. return this._readyPromise || this._finishedPromise;
  5892. };
  5893.  
  5894.  
  5895. let restartWebAnimationsNextTickFlag = false;
  5896.  
  5897. const looperMethodT = () => {
  5898.  
  5899. const runnerFn = (hRes) => {
  5900. var b = timeline;
  5901. b.currentTime = hRes;
  5902. b._discardAnimations();
  5903. if (0 == b._animations.length) {
  5904. restartWebAnimationsNextTickFlag = false;
  5905. } else {
  5906. getRafPromise().then(runnerFn);
  5907. }
  5908. }
  5909.  
  5910. const restartWebAnimationsNextTick = () => {
  5911. if (!restartWebAnimationsNextTickFlag) {
  5912. restartWebAnimationsNextTickFlag = true;
  5913. getRafPromise().then(runnerFn);
  5914. }
  5915. }
  5916.  
  5917. return { restartWebAnimationsNextTick }
  5918. };
  5919.  
  5920.  
  5921. const looperMethodN = () => {
  5922.  
  5923. const acs = document.createElement('a-f');
  5924. acs.id = 'a-f';
  5925.  
  5926. if (!document.getElementById('afscript')) {
  5927. const style = document.createElement('style');
  5928. style.id = 'afscript';
  5929. style.textContent = `
  5930. @keyFrames aF1 {
  5931. 0% {
  5932. order: 0;
  5933. }
  5934. 100% {
  5935. order: 1;
  5936. }
  5937. }
  5938. #a-f[id] {
  5939. visibility: collapse !important;
  5940. position: fixed !important;
  5941. display: block !important;
  5942. top: -100px !important;
  5943. left: -100px !important;
  5944. margin:0 !important;
  5945. padding:0 !important;
  5946. outline:0 !important;
  5947. border:0 !important;
  5948. z-index:-1 !important;
  5949. width: 0px !important;
  5950. height: 0px !important;
  5951. contain: strict !important;
  5952. pointer-events: none !important;
  5953. animation: 1ms steps(2, jump-none) 0ms infinite alternate forwards running aF1 !important;
  5954. }
  5955. `;
  5956. (document.head || document.documentElement).appendChild(style);
  5957. }
  5958.  
  5959. document.documentElement.insertBefore(acs, document.documentElement.firstChild);
  5960.  
  5961. const _onanimationiteration = function (evt) {
  5962. const hRes = evt.timeStamp;
  5963. var b = timeline;
  5964. b.currentTime = hRes;
  5965. b._discardAnimations();
  5966. if (0 == b._animations.length) {
  5967. restartWebAnimationsNextTickFlag = false;
  5968. acs.onanimationiteration = null;
  5969. } else {
  5970. acs.onanimationiteration = _onanimationiteration;
  5971. }
  5972.  
  5973. }
  5974.  
  5975.  
  5976.  
  5977. const restartWebAnimationsNextTick = () => {
  5978. if (!restartWebAnimationsNextTickFlag) {
  5979. restartWebAnimationsNextTickFlag = true;
  5980. acs.onanimationiteration = _onanimationiteration;
  5981.  
  5982. }
  5983. }
  5984.  
  5985. return { restartWebAnimationsNextTick }
  5986. };
  5987.  
  5988.  
  5989.  
  5990. const { restartWebAnimationsNextTick } = ('onanimationiteration' in document.documentElement) ? looperMethodN() : looperMethodT();
  5991.  
  5992.  
  5993. // console.log(571, timProto);
  5994. timProto._play = function (c) {
  5995. c = new Animation(c, this);
  5996. this._animations.push(c);
  5997. restartWebAnimationsNextTick();
  5998. c._updatePromises();
  5999. c._animation.play();
  6000. c._updatePromises();
  6001. return c
  6002. }
  6003.  
  6004. const animationsWithPromisesMap = new Set(originalAnimationsWithPromises);
  6005. originalAnimationsWithPromises.length = 0;
  6006. originalAnimationsWithPromises.push = null;
  6007. originalAnimationsWithPromises.splice = null;
  6008. originalAnimationsWithPromises.slice = null;
  6009. originalAnimationsWithPromises.indexOf = null;
  6010. originalAnimationsWithPromises.unshift = null;
  6011. originalAnimationsWithPromises.shift = null;
  6012. originalAnimationsWithPromises.pop = null;
  6013. originalAnimationsWithPromises.filter = null;
  6014. originalAnimationsWithPromises.forEach = null;
  6015. originalAnimationsWithPromises.map = null;
  6016.  
  6017.  
  6018. const _updateAnimationsPromises = () => {
  6019. animationsWithPromisesMap.forEach(c => {
  6020. if (!c._updatePromises()) animationsWithPromisesMap.delete(c);
  6021. });
  6022. /*
  6023. v.animationsWithPromises = v.animationsWithPromises.filter(function (c) {
  6024. return c._updatePromises();
  6025. });
  6026. */
  6027. }
  6028.  
  6029. timProto._updateAnimationsPromises31 = timProto._updateAnimationsPromises;
  6030.  
  6031. timProto._updateAnimationsPromises = _updateAnimationsPromises;
  6032.  
  6033. delete timProto._updateAnimationsPromises;
  6034. Object.defineProperty(timProto, '_updateAnimationsPromises', {
  6035. get() {
  6036. if (animationsWithPromisesMap.size === 0) return nilFn;
  6037. return _updateAnimationsPromises;
  6038. },
  6039. set(nv) {
  6040. delete this._updateAnimationsPromises;
  6041. this._updateAnimationsPromises = nv;
  6042. },
  6043. enumerable: true,
  6044. configurable: true,
  6045. });
  6046.  
  6047.  
  6048. let pdFinished = Object.getOwnPropertyDescriptor(aniProto, 'finished');
  6049. aniProto.__finished_native_get__ = pdFinished.get;
  6050. if (typeof pdFinished.get === 'function' && !pdFinished.set && pdFinished.configurable === true && pdFinished.enumerable === true) {
  6051.  
  6052.  
  6053. Object.defineProperty(aniProto, 'finished', {
  6054. get() {
  6055. this._finishedPromise || (!animationsWithPromisesMap.has(this) && animationsWithPromisesMap.add(this),
  6056. this._finishedPromise = new Promise((resolve, reject) => {
  6057. this._resolveFinishedPromise = function () {
  6058. resolve(this)
  6059. };
  6060. this._rejectFinishedPromise = function () {
  6061. reject({
  6062. type: DOMException.ABORT_ERR,
  6063. name: "AbortError"
  6064. })
  6065. };
  6066. }),
  6067. "finished" == this.playState && this._resolveFinishedPromise());
  6068. return this._finishedPromise
  6069. },
  6070. set: undefined,
  6071. enumerable: true,
  6072. configurable: true
  6073. });
  6074.  
  6075. }
  6076.  
  6077.  
  6078.  
  6079. let pdReady = Object.getOwnPropertyDescriptor(aniProto, 'ready');
  6080. aniProto.__ready_native_get__ = pdReady.get;
  6081. if (typeof pdReady.get === 'function' && !pdReady.set && pdReady.configurable === true && pdReady.enumerable === true) {
  6082.  
  6083. Object.defineProperty(aniProto, 'ready', {
  6084. get() {
  6085. this._readyPromise || (!animationsWithPromisesMap.has(this) && animationsWithPromisesMap.add(this),
  6086. this._readyPromise = new Promise((resolve, reject) => {
  6087. this._resolveReadyPromise = function () {
  6088. resolve(this)
  6089. };
  6090. this._rejectReadyPromise = function () {
  6091. reject({
  6092. type: DOMException.ABORT_ERR,
  6093. name: "AbortError"
  6094. })
  6095. };
  6096. }),
  6097. "pending" !== this.playState && this._resolveReadyPromise());
  6098. return this._readyPromise
  6099. },
  6100. set: undefined,
  6101. enumerable: true,
  6102. configurable: true
  6103. });
  6104.  
  6105. }
  6106.  
  6107.  
  6108. if (IGNORE_bindAnimationForCustomEffect && typeof aniProto._rebuildUnderlyingAnimation === 'function' && !aniProto._rebuildUnderlyingAnimation21 && aniProto._rebuildUnderlyingAnimation.length === 0) {
  6109.  
  6110. aniProto._rebuildUnderlyingAnimation21 = aniProto._rebuildUnderlyingAnimation;
  6111. const _rebuildUnderlyingAnimation = function () {
  6112. // if (isNaN(this._sequenceNumber)) return; // do not rebuild underlying animation if native animation is used.
  6113. this.effect && this.effect._onsample && (this.effect._onsample = null);
  6114. return this._rebuildUnderlyingAnimation21();
  6115. }
  6116. aniProto._rebuildUnderlyingAnimation = _rebuildUnderlyingAnimation;
  6117. // delete aniProto._rebuildUnderlyingAnimation;
  6118. // Object.defineProperty(aniProto, '_rebuildUnderlyingAnimation', {
  6119. // get() {
  6120. // if (isNaN(this._sequenceNumber)) return nilFn;
  6121. // return this._rebuildUnderlyingAnimation21;
  6122. // },
  6123. // set(nv) {
  6124. // delete this._rebuildUnderlyingAnimation;
  6125. // this._rebuildUnderlyingAnimation = nv;
  6126. // },
  6127. // enumerable: true,
  6128. // configurable: true
  6129. // });
  6130. }
  6131.  
  6132.  
  6133. /*
  6134.  
  6135.  
  6136. function f(c) {
  6137. var b = v.timeline;
  6138. b.currentTime = c;
  6139. b._discardAnimations();
  6140. 0 == b._animations.length ? d = !1 : requestAnimationFrame(f)
  6141. }
  6142. var h = window.requestAnimationFrame;
  6143. window.requestAnimationFrame = function(c) {
  6144. return h(function(b) {
  6145. v.timeline._updateAnimationsPromises();
  6146. c(b);
  6147. v.timeline._updateAnimationsPromises()
  6148. })
  6149. }
  6150. ;
  6151. v.AnimationTimeline = function() {
  6152. this._animations = [];
  6153. this.currentTime = void 0
  6154. }
  6155. ;
  6156. v.AnimationTimeline.prototype = {
  6157. getAnimations: function() {
  6158. this._discardAnimations();
  6159. return this._animations.slice()
  6160. },
  6161. _updateAnimationsPromises: function() {
  6162. v.animationsWithPromises = v.animationsWithPromises.filter(function(c) {
  6163. return c._updatePromises()
  6164. })
  6165. },
  6166. _discardAnimations: function() {
  6167. this._updateAnimationsPromises();
  6168. this._animations = this._animations.filter(function(c) {
  6169. return "finished" != c.playState && "idle" != c.playState
  6170. })
  6171. },
  6172. _play: function(c) {
  6173. c = new v.Animation(c,this);
  6174. this._animations.push(c);
  6175. v.restartWebAnimationsNextTick();
  6176. c._updatePromises();
  6177. c._animation.play();
  6178. c._updatePromises();
  6179. return c
  6180. },
  6181. play: function(c) {
  6182. c && c.remove();
  6183. return this._play(c)
  6184. }
  6185. };
  6186. var d = !1;
  6187. v.restartWebAnimationsNextTick = function() {
  6188. d || (d = !0,
  6189. requestAnimationFrame(f))
  6190. }
  6191. ;
  6192. var a = new v.AnimationTimeline;
  6193. v.timeline = a;
  6194. try {
  6195. Object.defineProperty(window.document, "timeline", {
  6196. configurable: !0,
  6197. get: function() {
  6198. return a
  6199. }
  6200. })
  6201. } catch (c) {}
  6202. try {
  6203. window.document.timeline = a
  6204. } catch (c) {}
  6205.  
  6206. */
  6207.  
  6208.  
  6209.  
  6210. /*
  6211.  
  6212. var g = window.getComputedStyle;
  6213. Object.defineProperty(window, "getComputedStyle", {
  6214. configurable: !0,
  6215. enumerable: !0,
  6216. value: function() {
  6217. v.timeline._updateAnimationsPromises();
  6218. var e = g.apply(this, arguments);
  6219. h() && (e = g.apply(this, arguments));
  6220. v.timeline._updateAnimationsPromises();
  6221. return e
  6222. }
  6223. });
  6224.  
  6225. */
  6226.  
  6227.  
  6228.  
  6229.  
  6230. }
  6231.  
  6232.  
  6233.  
  6234.  
  6235. })();
  6236.  
  6237. !isUrlInEmbed && Promise.resolve().then(() => {
  6238.  
  6239. // ==================================== FIX_avoid_incorrect_video_meta ====================================
  6240.  
  6241.  
  6242.  
  6243. class LimitedSizeSet extends Set {
  6244. constructor(n) {
  6245. super();
  6246. this.limit = n;
  6247. }
  6248.  
  6249. add(key) {
  6250. if (!super.has(key)) {
  6251. super.add(key);
  6252. let n = super.size - this.limit;
  6253. if (n > 0) {
  6254. const iterator = super.values();
  6255. do {
  6256. const firstKey = iterator.next().value; // Get the first (oldest) key
  6257. super.delete(firstKey); // Delete the oldest key
  6258. } while (--n > 0)
  6259. }
  6260. }
  6261. }
  6262.  
  6263. removeAdd(key) {
  6264. super.delete(key);
  6265. super.add(key);
  6266. }
  6267.  
  6268. }
  6269.  
  6270. // const wk3 = new WeakMap();
  6271.  
  6272. // let mtxVideoId = '';
  6273. // let aje3 = [];
  6274. const mfvContinuationRecorded = new LimitedSizeSet(8); // record all success continuation keys
  6275. const mfyContinuationIgnored = new LimitedSizeSet(8); // ignore continuation keys by copying the keys in the past
  6276. let mtzlastAllowedContinuation = ''; // the key stored at the last success; clear when scheduling changes
  6277. let mtzCount = 0; // the key keeps unchanged
  6278. // let mjtNextMainKey = '';
  6279. let mjtRecordedPrevKey = ''; // the key stored at the last success (no clear)
  6280. let mjtLockPreviousKey = ''; // the key before fetch() should be discarded. (uncertain continuation)
  6281. let mbCId322 = 0; // cid for delay fetchUpdatedMetadata
  6282. // let allowNoDelay322=false;
  6283. let mbDelayBelowNCalls = 0; // after N calls, by pass delay; reset when scheduling changes
  6284.  
  6285. let mpKey22 = ''; // last success continutation key & url pair
  6286. let mpUrl22 = ''; // last success continutation key & url pair
  6287. let mpKey21 = ''; // latest requested continutation key & url pair
  6288. let mpUrl21 = ''; // latest requested continutation key & url pair
  6289.  
  6290.  
  6291. async function sha1Hex(message) {
  6292. const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
  6293. const hashBuffer = await crypto.subtle.digest("SHA-1", msgUint8); // hash the message
  6294. const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
  6295. const hashHex = hashArray
  6296. .map((b) => b.toString(16).padStart(2, "0"))
  6297. .join(""); // convert bytes to hex string
  6298. return hashHex;
  6299. }
  6300.  
  6301. async function continuationLog(a, ...args) {
  6302. let b = a;
  6303. try {
  6304. if (advanceLogging) b = await sha1Hex(a);
  6305. let c = args.map(e => {
  6306. return e === a ? b : e
  6307. });
  6308. console.log(...c)
  6309. } catch (e) { console.warn(e) }
  6310. }
  6311.  
  6312. function copyPreviousContiuationToIgnored374(toClearRecorded) {
  6313.  
  6314.  
  6315. if (mfvContinuationRecorded.length > 0) {
  6316. for (const [e, d] of mfvContinuationRecorded) {
  6317. mfyContinuationIgnored.removeAdd(e);
  6318. }
  6319. toClearRecorded && mfvContinuationRecorded.clear();
  6320. }
  6321.  
  6322. }
  6323.  
  6324. function setup_ytTaskEmitterBehavior_TaskMgr374(taskMgr) {
  6325.  
  6326. const tmProto = taskMgr.constructor.prototype;
  6327. if (tmProto && typeof tmProto.addJob === 'function' && tmProto.addJob.length === 3 && typeof tmProto.cancelJob === 'function' && tmProto.cancelJob.length === 1) {
  6328.  
  6329. if (!tmProto.addJob714) {
  6330.  
  6331. tmProto.addJob714 = tmProto.addJob;
  6332.  
  6333. tmProto.addJob = function (a, b, c) {
  6334. const jobId = this.addJob714(a, b, c);
  6335. if (jobId > 0) {
  6336. // const ez = wk3.get(this);
  6337. // const dz = ez ? ez.data?.updatedMetadataEndpoint?.updatedMetadataEndpoint : null;
  6338. // aje3.push({mtx, jobId, a,b,c, element: this, dz, data: (ez?.data || null) })
  6339.  
  6340. this.__lastJobId863__ = jobId;
  6341. }
  6342. return jobId;
  6343. }
  6344.  
  6345. }
  6346.  
  6347. if (!tmProto.cancelJob714) {
  6348.  
  6349. tmProto.cancelJob714 = tmProto.cancelJob;
  6350.  
  6351. tmProto.cancelJob = function (a) {
  6352. const res = this.cancelJob714(a);
  6353. // if (a > 0) {
  6354. // for (const e of aje3) {
  6355. // if (e.jobId === a) e.cancelled = true;
  6356. // }
  6357. // }
  6358. return res;
  6359. }
  6360.  
  6361. }
  6362.  
  6363. }
  6364. }
  6365.  
  6366.  
  6367. const FIX_avoid_incorrect_video_meta_bool = FIX_avoid_incorrect_video_meta && isPrepareCachedV && check_for_set_key_order;
  6368.  
  6369.  
  6370. FIX_avoid_incorrect_video_meta_bool && whenCEDefined('ytd-video-primary-info-renderer').then(() => {
  6371. let dummy;
  6372. let cProto;
  6373. // let mc = 4;
  6374. // dummy = await observablePromise(() => {
  6375. // const r = document.querySelector('ytd-video-primary-info-renderer');
  6376. // if (!r) return;
  6377. // let cProto = insp(r).constructor.prototype;
  6378. // if (cProto.fetchUpdatedMetadata) return r;
  6379. // if (--mc < 0) return -1;
  6380. // return null;
  6381. // }).obtain();
  6382. dummy = document.createElement('ytd-video-primary-info-renderer');
  6383. if (!(dummy instanceof Element)) return;
  6384. // console.log(5022, dummy)
  6385. cProto = insp(dummy).constructor.prototype;
  6386.  
  6387. cProto.__getEmittorTaskMgr859__ = function () {
  6388. let taskMgr_ = null;
  6389. try {
  6390. taskMgr_ = (this.ytTaskEmitterBehavior || 0).getTaskManager() || null;
  6391. } catch (e) { }
  6392. return taskMgr_;
  6393. }
  6394. if (typeof cProto.fetchUpdatedMetadata === 'function' && cProto.fetchUpdatedMetadata.length === 1 && !cProto.fetchUpdatedMetadata717) {
  6395. // console.log(1234, cProto, cProto.is)
  6396. cProto.fetchUpdatedMetadata717 = cProto.fetchUpdatedMetadata;
  6397.  
  6398. let c_;
  6399. cProto.fetchUpdatedMetadata718 = function (a) {
  6400. // delay or immediate call the actual fetchUpdatedMetadata
  6401.  
  6402. let doImmediately = false;
  6403. if (a && typeof a === 'string' && mjtRecordedPrevKey && mjtRecordedPrevKey === mpKey22 && a === mpKey22 && (!pageSetupVideoId || pageSetupVideoId !== mpUrl22)) {
  6404.  
  6405. if (!pageSetupVideoId && videoPlayingY.videoId === mpUrl22) doImmediately = true;
  6406.  
  6407. } else if (typeof a !== 'string' || mbDelayBelowNCalls > 3 || !mpKey22 || (mpKey22 === a && mpKey22 !== mjtLockPreviousKey) || (mjtLockPreviousKey && mjtLockPreviousKey !== a)) {
  6408.  
  6409. doImmediately = true;
  6410.  
  6411. }
  6412.  
  6413. if (mbCId322) {
  6414. clearTimeout(mbCId322);
  6415. mbCId322 = 0;
  6416. }
  6417.  
  6418. if (doImmediately) return this.fetchUpdatedMetadata717(a);
  6419.  
  6420. let delay = mjtLockPreviousKey === a ? 8000 : 800;
  6421.  
  6422. mbCId322 = setTimeout(() => {
  6423. this.fetchUpdatedMetadata717(a);
  6424. }, delay);
  6425.  
  6426. console.log('[yt-js-engine-tamer]', '5190 delayed fetchUpdatedMetadata', delay);
  6427.  
  6428. }
  6429.  
  6430. cProto.fetchUpdatedMetadata = function (a) {
  6431.  
  6432. if (!pageSetupState) {
  6433. if (c_) clearTimeout(c_);
  6434. c_ = setTimeout(() => {
  6435. this.fetchUpdatedMetadata718(a);
  6436. }, 300);
  6437. return;
  6438. }
  6439.  
  6440. // pageSetupState == 0
  6441.  
  6442. try {
  6443.  
  6444. mbDelayBelowNCalls++;
  6445.  
  6446. if (arguments.length > 1 || !(a === undefined || (typeof a === 'string' && a))) {
  6447. console.warn("CAUTION: fetchUpdatedMetadata coding might have to be updated.");
  6448. }
  6449.  
  6450. // console.log('fum377', a)
  6451. if (typeof a === 'string' && mfyContinuationIgnored.has(a)) {
  6452. console.log('[yt-js-engine-tamer]', '5040 skip fetchUpdatedMetadata', a);
  6453. return;
  6454. }
  6455.  
  6456. if (!a && (this.data || 0).updatedMetadataEndpoint) {
  6457. if (mjtRecordedPrevKey && mjtLockPreviousKey !== mjtRecordedPrevKey) {
  6458. mjtLockPreviousKey = mjtRecordedPrevKey;
  6459. LOG_FETCHMETA_UPDATE && continuationLog(mjtLockPreviousKey, '5150 Lock Key', mjtLockPreviousKey);
  6460. }
  6461. // mjtNextMainKey = true;
  6462. mtzlastAllowedContinuation = '';
  6463. mtzCount = 0;
  6464. // allowNoDelay322 = false;
  6465. // fetch new metadata, cancel all previous continuations
  6466. copyPreviousContiuationToIgnored374(true);
  6467. } else if (typeof a === 'string') {
  6468. const videoPlayingId = videoPlayingY.videoId;
  6469.  
  6470. // if(mjtNextMainKey === true) mjtNextMainKey = a;
  6471.  
  6472. let update21 = !!pageSetupVideoId;
  6473. if (mpKey22 === a && mpUrl22 === videoPlayingId && mpUrl22 && videoPlayingId && (!pageSetupVideoId || pageSetupVideoId === videoPlayingId)) {
  6474. update21 = true;
  6475. } else if (mpKey22 === a && mpUrl22 !== pageSetupVideoId) {
  6476. LOG_FETCHMETA_UPDATE && continuationLog(mpKey22, '5060 mpUrl22 mismatched', mpKey22, mpUrl22, pageSetupVideoId || '(null)', videoPlayingId || '(null)');
  6477. return;
  6478. }
  6479. if (update21) {
  6480. mpKey21 = a;
  6481. mpUrl21 = pageSetupVideoId || videoPlayingId;
  6482. }
  6483.  
  6484. if (!mfvContinuationRecorded.has(a)) mfvContinuationRecorded.add(a);
  6485. }
  6486. LOG_FETCHMETA_UPDATE && continuationLog(a, '5180 fetchUpdatedMetadata\t', a, pageSetupVideoId || '(null)', videoPlayingY.videoId || '(null)');
  6487. // if (!pageSetupVideoId && typeof a === 'string' && a.length > 40) return; // ignore incorrect continuation
  6488. // if(a === mjtNextMainKey) allowNoDelay322 = false;
  6489. return this.fetchUpdatedMetadata718(a);
  6490.  
  6491. } catch (e) {
  6492. console.log('Code Error in fetchUpdatedMetadata', e);
  6493. }
  6494. return this.fetchUpdatedMetadata717(a)
  6495. }
  6496. }
  6497.  
  6498.  
  6499. if (typeof cProto.scheduleInitialUpdatedMetadataRequest === 'function' && cProto.scheduleInitialUpdatedMetadataRequest.length === 0 && !cProto.scheduleInitialUpdatedMetadataRequest717) {
  6500. // console.log(1234, cProto, cProto.is)
  6501. cProto.scheduleInitialUpdatedMetadataRequest717 = cProto.scheduleInitialUpdatedMetadataRequest;
  6502. let mJob = null;
  6503.  
  6504. cProto.scheduleInitialUpdatedMetadataRequest = function () {
  6505.  
  6506. try {
  6507.  
  6508. if (arguments.length > 0) {
  6509. console.warn("CAUTION: scheduleInitialUpdatedMetadataRequest coding might have to be updated.");
  6510. }
  6511. // mfy = mfv;
  6512.  
  6513. // mjtNextMainKey = '';
  6514. mtzlastAllowedContinuation = '';
  6515. mtzCount = 0;
  6516. if (mbCId322) {
  6517. clearTimeout(mbCId322);
  6518. mbCId322 = 0;
  6519. }
  6520. mbDelayBelowNCalls = 0;
  6521. // allowNoDelay322 = false;
  6522. copyPreviousContiuationToIgnored374(true);
  6523.  
  6524. const taskMgr = this.__getEmittorTaskMgr859__();
  6525. if (FIX_avoid_incorrect_video_meta_emitterBehavior && taskMgr && !taskMgr.addJob714 && taskMgr.addJob && taskMgr.cancelJob) setup_ytTaskEmitterBehavior_TaskMgr374(taskMgr);
  6526. if (FIX_avoid_incorrect_video_meta_emitterBehavior && taskMgr && !taskMgr.addJob714) {
  6527. console.log('[yt-js-engine-tamer]', 'scheduleInitialUpdatedMetadataRequest error 507');
  6528. }
  6529.  
  6530. // prevent depulicated schedule job by clearing previous JobId
  6531. if (taskMgr && typeof taskMgr.addLowPriorityJob === 'function' && taskMgr.addLowPriorityJob.length === 2 && typeof taskMgr.cancelJob === 'function' && taskMgr.cancelJob.length === 1) {
  6532.  
  6533. let res;
  6534.  
  6535. if (mJob) {
  6536. const job = mJob;
  6537. mJob = null;
  6538. console.log('cancelJob', job)
  6539. taskMgr.cancelJob(job); // clear previous [Interval Meta Update] job
  6540. // p.cancelJob(a,b);
  6541. }
  6542.  
  6543. // const updatedMetadataEndpoint = this.data?.updatedMetadataEndpoint?.updatedMetadataEndpoint
  6544.  
  6545. let pza = taskMgr.__lastJobId863__;
  6546. try { res = this.scheduleInitialUpdatedMetadataRequest717(); } catch (e) { }
  6547. let pzb = taskMgr.__lastJobId863__
  6548. if (pza !== pzb) {
  6549. mJob = pzb; // set [Interval Meta Update] jobId
  6550. }
  6551.  
  6552. // if (updatedMetadataEndpoint && updatedMetadataEndpoint.videoId) {
  6553. // mtxVideoId = updatedMetadataEndpoint.videoId || ''; // set the current target VideoId
  6554. // } else {
  6555. // mtxVideoId = ''; // sometimes updatedMetadataEndpoint is not ready
  6556. // }
  6557.  
  6558. return res;
  6559.  
  6560. } else {
  6561. console.log('[yt-js-engine-tamer]', 'scheduleInitialUpdatedMetadataRequest error 601');
  6562. }
  6563.  
  6564. } catch (e) {
  6565. console.log('Code Error in scheduleInitialUpdatedMetadataRequest', e);
  6566. }
  6567.  
  6568.  
  6569. return this.scheduleInitialUpdatedMetadataRequest717();
  6570. }
  6571. }
  6572.  
  6573.  
  6574. });
  6575.  
  6576. FIX_avoid_incorrect_video_meta_bool && promiseForYtActionCalled.then((ytAppDom) => {
  6577. let dummy;
  6578. let cProto;
  6579. dummy = ytAppDom;
  6580. if (!(dummy instanceof Element)) return;
  6581. cProto = insp(dummy).constructor.prototype;
  6582. if (typeof cProto.sendServiceAjax_ === 'function' && cProto.sendServiceAjax_.length === 4 && !cProto.sendServiceAjax717_) {
  6583. // console.log(1234, cProto, cProto.is);
  6584. // cProto.handleServiceRequest717_ = cProto.handleServiceRequest_;
  6585. // cProto.handleServiceRequest_ = function (a, b, c, d) {
  6586. // console.log(123401, arguments);
  6587. // return this.handleServiceRequest717_(a, b, c, d);
  6588. // }
  6589.  
  6590. // cProto.handleServiceRequest717_ = cProto.handleServiceRequest_;
  6591.  
  6592. // cProto.handleServiceRequest_ = function(a,b,c,d){
  6593. // console.log(59901, a?.is, b?.updatedMetadataEndpoint?.videoId, c?.continuation)
  6594. // if(a?.is === 'ytd-video-primary-info-renderer' && b?.updatedMetadataEndpoint?.videoId && c?.continuation && typeof c?.continuation ==='string'){
  6595. // console.log('mfv', c.continuation);
  6596. // mfv.add( c.continuation);
  6597. // }
  6598. // return this.handleServiceRequest717_(a,b,c,d);
  6599. // }
  6600.  
  6601. function extraArguments322(a, b, c) {
  6602. let is = (a || 0).is;
  6603. let videoId = ((b || 0).updatedMetadataEndpoint || 0).videoId;
  6604. let continuation = (c || 0).continuation;
  6605. if (typeof is !== 'string') is = null;
  6606. if (typeof videoId !== 'string') videoId = null;
  6607. if (typeof continuation !== 'string') continuation = null;
  6608. return { is, videoId, continuation };
  6609. }
  6610.  
  6611. cProto.sendServiceAjax717_ = cProto.sendServiceAjax_;
  6612. cProto.sendServiceAjax_ = function (a, b, c, d) {
  6613.  
  6614. // console.log(8001)
  6615. try {
  6616.  
  6617. const { is, videoId, continuation } = extraArguments322(a, b, c);
  6618.  
  6619. if ((videoId || continuation) && (is !== 'ytd-video-primary-info-renderer')) {
  6620. console.warn("CAUTION: sendServiceAjax_ coding might have to be updated.");
  6621. }
  6622.  
  6623. if (pageSetupVideoId && videoId && continuation) {
  6624. if (mpKey21 && mpUrl21 && mpKey21 === continuation && mpUrl21 !== pageSetupVideoId) {
  6625. mfyContinuationIgnored.removeAdd(continuation);
  6626. mfvContinuationRecorded.delete(continuation);
  6627. return;
  6628. }
  6629. }
  6630.  
  6631. if (mjtLockPreviousKey && mjtLockPreviousKey !== continuation && continuation) {
  6632. copyPreviousContiuationToIgnored374(false);
  6633. mfyContinuationIgnored.delete(continuation);
  6634. mfvContinuationRecorded.removeAdd(continuation);
  6635. mfyContinuationIgnored.removeAdd(mjtLockPreviousKey);
  6636. mfvContinuationRecorded.delete(mjtLockPreviousKey);
  6637. mjtLockPreviousKey = '';
  6638. }
  6639. // if (mjtNextMainKey === continuation) {
  6640. // copyPreviousContiuationToIgnored(false);
  6641. // mfyContinuationIgnored.delete(continuation);
  6642. // mfvContinuationRecorded.add(continuation);
  6643. // }
  6644.  
  6645.  
  6646. if (mfyContinuationIgnored && continuation) {
  6647. if (mfyContinuationIgnored.has(continuation)) {
  6648. LOG_FETCHMETA_UPDATE && continuationLog(continuation, '5260 matched01', continuation)
  6649. return;
  6650. }
  6651. }
  6652.  
  6653. // console.log(59902, a?.is, b,c,d)
  6654. // console.log(59903, a?.is, b?.updatedMetadataEndpoint?.videoId, c?.continuation)
  6655. if (is === 'ytd-video-primary-info-renderer' && videoId && continuation && !mfvContinuationRecorded.has(continuation)) {
  6656. // console.log('mfv377', continuation);
  6657. mfvContinuationRecorded.add(continuation);
  6658. }
  6659.  
  6660. // if (videoId) {
  6661. // if (!pageSetupVideoId) return; // ignore page not ready
  6662. // // if (mtxVideoId && b.updatedMetadataEndpoint.videoId !== mtxVideoId) return; // ignore videoID not matched
  6663. // if (videoId !== pageSetupVideoId) {
  6664. // return;
  6665. // }
  6666. // }
  6667.  
  6668. } catch (e) {
  6669. console.log('Coding Error in sendServiceAjax_', e)
  6670. }
  6671. // console.log(8002)
  6672. // console.log(123402, arguments);
  6673. // console.log(5162, 'a',a?.is,'b',b,'c',c,'d',d);
  6674.  
  6675. // console.log(5211, b?.updatedMetadataEndpoint?.kdkw33);
  6676. // if(b &&b.updatedMetadataEndpoint && !b.updatedMetadataEndpoint.kdkw33){
  6677. // b.updatedMetadataEndpoint = new Proxy(b.updatedMetadataEndpoint, {
  6678. // get(target, prop, receiver){
  6679. // console.log('xxs99', target.videoId, mtx)
  6680. // if(prop ==='kdkw33') return 1;
  6681. // console.log(3322, prop, target)
  6682. // if(prop === 'initialDelayMs') {
  6683. // throw new Error("ABCC");
  6684. // }
  6685. // return target[prop];
  6686. // },
  6687. // set(target, prop, value, receiver){
  6688.  
  6689. // if(prop ==='kdkw33') return true;
  6690. // target[prop]=value;
  6691. // return true;
  6692. // }
  6693. // });
  6694. // }
  6695. // console.log(5533, b?.updatedMetadataEndpoint?.kdkw33)
  6696. return this.sendServiceAjax717_(a, b, c, d);
  6697. }
  6698. }
  6699.  
  6700. function delayClearOtherKeys(lztContinuation) {
  6701. // // schedule delayed removal if mfyContinuationIgnored is not empty
  6702. // getRafPromise().then(() => {
  6703. // // assume the repeat continuation could be only for popstate which is triggered by user interaction
  6704. // // foreground page only
  6705.  
  6706. // });
  6707.  
  6708.  
  6709. if (lztContinuation !== mtzlastAllowedContinuation) return;
  6710. if (lztContinuation !== mpKey21 || lztContinuation !== mpKey22) return;
  6711. if (!mfyContinuationIgnored.size) return;
  6712. if (mfyContinuationIgnored.size > 1) {
  6713. LOG_FETCHMETA_UPDATE && continuationLog(lztContinuation, 'delayClearOtherKeys, current = ', lztContinuation);
  6714. }
  6715. mfyContinuationIgnored.forEach((value, key) => {
  6716. if (key !== lztContinuation) {
  6717. mfyContinuationIgnored.delete(key);
  6718. LOG_FETCHMETA_UPDATE && continuationLog(key, 'previous continuation removed from ignored store', key);
  6719. }
  6720. });
  6721.  
  6722. }
  6723. if (typeof cProto.getCancellableNetworkPromise_ === 'function' && cProto.getCancellableNetworkPromise_.length === 5 && !cProto.getCancellableNetworkPromise717_) {
  6724. cProto.getCancellableNetworkPromise717_ = cProto.getCancellableNetworkPromise_;
  6725. cProto.getCancellableNetworkPromise_ = function (a, b, c, d, e) {
  6726.  
  6727. // console.log(8003)
  6728. try {
  6729.  
  6730.  
  6731. const { is, videoId, continuation } = extraArguments322(b, c, d);
  6732.  
  6733. if ((videoId || continuation) && (is !== 'ytd-video-primary-info-renderer')) {
  6734. console.warn("CAUTION: getCancellableNetworkPromise_ coding might have to be updated.");
  6735. }
  6736.  
  6737. if (pageSetupVideoId && videoId && continuation) {
  6738. if (mpKey21 && mpUrl21 && mpKey21 === continuation && mpUrl21 !== pageSetupVideoId) {
  6739. mfyContinuationIgnored.removeAdd(continuation);
  6740. mfvContinuationRecorded.delete(continuation);
  6741. return;
  6742. }
  6743. }
  6744.  
  6745. if (mjtLockPreviousKey && mjtLockPreviousKey !== continuation && continuation) {
  6746. copyPreviousContiuationToIgnored374(false);
  6747. mfyContinuationIgnored.delete(continuation);
  6748. mfvContinuationRecorded.removeAdd(continuation);
  6749. mfyContinuationIgnored.removeAdd(mjtLockPreviousKey);
  6750. mfvContinuationRecorded.delete(mjtLockPreviousKey);
  6751. mjtLockPreviousKey = '';
  6752. }
  6753.  
  6754. // if (mjtNextMainKey === continuation) {
  6755. // copyPreviousContiuationToIgnored(false);
  6756. // mfyContinuationIgnored.delete(continuation);
  6757. // mfvContinuationRecorded.add(continuation);
  6758. // }
  6759.  
  6760. const lztContinuation = continuation;
  6761.  
  6762. if (mfyContinuationIgnored && lztContinuation && typeof lztContinuation === 'string') {
  6763. if (mfyContinuationIgnored.has(lztContinuation)) {
  6764. LOG_FETCHMETA_UPDATE && continuationLog(lztContinuation, '5360 matched02', lztContinuation)
  6765. return;
  6766. }
  6767. }
  6768.  
  6769. // if (videoId) {
  6770. // if (!pageSetupVideoId) return; // ignore page not ready
  6771. // // if (mtxVideoId && c.updatedMetadataEndpoint.videoId !== mtxVideoId) return; // ignore videoID not matched
  6772. // if (videoId !== pageSetupVideoId) {
  6773. // return;
  6774. // }
  6775. // }
  6776.  
  6777. if (typeof lztContinuation === 'string' && mtzlastAllowedContinuation !== lztContinuation) {
  6778. mtzlastAllowedContinuation = lztContinuation;
  6779. // console.log(70401, lztContinuation, mfyContinuationIgnored.size)
  6780.  
  6781. LOG_FETCHMETA_UPDATE && continuationLog(lztContinuation, '5382 Continuation sets to\t', lztContinuation, `C${mtzCount}.R${mfvContinuationRecorded.size}.I${mfyContinuationIgnored.size}`);
  6782. mjtRecordedPrevKey = lztContinuation;
  6783. if (mjtLockPreviousKey === lztContinuation) mjtLockPreviousKey = '';
  6784. // if (mfyContinuationIgnored.size > 0) {
  6785. // delayClearOtherKeys(lztContinuation);
  6786. // }
  6787. mtzCount = 0;
  6788. // allowNoDelay322 = false;
  6789. } else if (typeof lztContinuation === 'string' && mtzlastAllowedContinuation && mtzlastAllowedContinuation === lztContinuation) {
  6790. // repeated
  6791. if (mtzCount > 1e9) mtzCount = 1e4;
  6792. ++mtzCount;
  6793. LOG_FETCHMETA_UPDATE && continuationLog(lztContinuation, '5386 Same Continuation\t\t', lztContinuation, `C${mtzCount}.R${mfvContinuationRecorded.size}.I${mfyContinuationIgnored.size}`);
  6794.  
  6795. // if (mtzCount >= 3) allowNoDelay322 = true;
  6796. if (mtzCount >= 3 && mfyContinuationIgnored.size > 0) {
  6797. Promise.resolve(lztContinuation).then(delayClearOtherKeys).catch(console.warn);
  6798. }
  6799. if (mtzCount === 5) {
  6800. mfvContinuationRecorded.clear();
  6801. mfvContinuationRecorded.add(lztContinuation);
  6802. }
  6803.  
  6804. }
  6805.  
  6806. if (typeof lztContinuation === 'string' && lztContinuation && (pageSetupVideoId || videoPlayingY.videoId)) {
  6807. mpKey22 = lztContinuation;
  6808. mpUrl22 = pageSetupVideoId || videoPlayingY.videoId;
  6809. }
  6810.  
  6811. if (mbCId322) {
  6812. clearTimeout(mbCId322);
  6813. mbCId322 = 0;
  6814. }
  6815. } catch (e) {
  6816. console.log('Coding Error in getCancellableNetworkPromise_', e)
  6817. }
  6818.  
  6819. // console.log(8004)
  6820. // console.log(123403, arguments);
  6821. // if(c.updatedMetadataEndpoint) console.log(123404, pageSetupVideoId, JSON.stringify(c.updatedMetadataEndpoint))
  6822.  
  6823. // console.log(5163, a?.is,b,c,d,e);
  6824. return this.getCancellableNetworkPromise717_(a, b, c, d, e);
  6825. }
  6826. }
  6827. });
  6828.  
  6829. // ==================================== FIX_avoid_incorrect_video_meta ====================================
  6830.  
  6831.  
  6832. FIX_ytdExpander_childrenChanged && whenCEDefined('ytd-expander').then(() => {
  6833.  
  6834. let dummy;
  6835. let cProto;
  6836.  
  6837. dummy = document.createElement('ytd-expander');
  6838. cProto = insp(dummy).constructor.prototype;
  6839.  
  6840. if (fnIntegrity(cProto.initChildrenObserver, '0.48.21') && fnIntegrity(cProto.childrenChanged, '0.40.22')) {
  6841.  
  6842. cProto.initChildrenObserver14 = cProto.initChildrenObserver;
  6843. cProto.childrenChanged14 = cProto.childrenChanged;
  6844.  
  6845. cProto.initChildrenObserver = function () {
  6846. var a = this;
  6847. this.observer = new MutationObserver(function () {
  6848. a.childrenChanged()
  6849. }
  6850. );
  6851. this.observer.observe(this.content, {
  6852. subtree: !0,
  6853. childList: !0,
  6854. attributes: !0,
  6855. characterData: !0
  6856. });
  6857. this.childrenChanged()
  6858. }
  6859. ;
  6860. cProto.childrenChanged = function () {
  6861. if (this.alwaysToggleable) {
  6862. this.canToggle = this.alwaysToggleable;
  6863. } else if (!this.canToggleJobId) {
  6864. this.canToggleJobId = 1;
  6865. foregroundPromiseFn().then(() => {
  6866. this.canToggleJobId = 0;
  6867. this.calculateCanCollapse()
  6868. })
  6869. }
  6870. }
  6871.  
  6872. // console.log(cProto.initChildrenObserver)
  6873. console.debug('ytd-expander-fix-childrenChanged');
  6874.  
  6875. }
  6876.  
  6877. });
  6878.  
  6879.  
  6880. FIX_paper_ripple_animate && whenCEDefined('paper-ripple').then(() => {
  6881.  
  6882. let dummy;
  6883. let cProto;
  6884. dummy = document.createElement('paper-ripple');
  6885. cProto = insp(dummy).constructor.prototype;
  6886.  
  6887. if (fnIntegrity(cProto.animate, '0.74.5')) {
  6888.  
  6889.  
  6890. cProto.animate34 = cProto.animate;
  6891. cProto.animate = function () {
  6892. if (this._animating) {
  6893. var a;
  6894. const ripples = this.ripples;
  6895. for (a = 0; a < ripples.length; ++a) {
  6896. var b = ripples[a];
  6897. b.draw();
  6898. this.$.background.style.opacity = b.outerOpacity;
  6899. b.isOpacityFullyDecayed && !b.isRestingAtMaxRadius && this.removeRipple(b)
  6900. }
  6901. if ((this.shouldKeepAnimating || 0) !== ripples.length) {
  6902. if (!this._boundAnimate38) this._boundAnimate38 = this.animate.bind(this);
  6903. foregroundPromiseFn().then(this._boundAnimate38);
  6904. } else {
  6905. this.onAnimationComplete();
  6906. }
  6907. }
  6908. }
  6909.  
  6910. console.debug('FIX_paper_ripple_animate')
  6911.  
  6912. // console.log(cProto.animate)
  6913.  
  6914. }
  6915.  
  6916. });
  6917.  
  6918. if (FIX_doIdomRender) {
  6919.  
  6920. const xsetTimeout = function (f, d) {
  6921. if (xsetTimeout.m511 === 1 && !d) {
  6922. xsetTimeout.m511 = 2;
  6923. xsetTimeout.m568 = f;
  6924. } else {
  6925. return setTimeout.apply(window, arguments)
  6926. }
  6927.  
  6928. }
  6929.  
  6930. /**
  6931. *
  6932. IGb = function(a) {
  6933. var b, c = null == (b = a.requestAninmationFrameResolver) ? void 0 : b.promise;
  6934. c || (a.requestAninmationFrameResolver = new Vi,
  6935. c = a.requestAninmationFrameResolver.promise,
  6936. Da.requestAnimationFrame(function() {
  6937. var d;
  6938. null == (d = a.requestAninmationFrameResolver) || d.resolve();
  6939. a.requestAninmationFrameResolver = null
  6940. }));
  6941. return c
  6942. }
  6943.  
  6944. */
  6945.  
  6946. const xrequestAnimationFrame = function (f) {
  6947. const h = f + "";
  6948. if (h.startsWith("function(){setTimeout(function(){") && h.endsWith("})}") ) {
  6949. let t = null;
  6950. xsetTimeout.m511 = 1;
  6951. f();
  6952. if (xsetTimeout.m511 === 2) {
  6953. t = xsetTimeout.m568;
  6954. xsetTimeout.m568 = null;
  6955. }
  6956. xsetTimeout.m511 = 0;
  6957. if (typeof t === 'function') {
  6958. foregroundPromiseFn().then(t);
  6959. }
  6960. } else if (h.includes("requestAninmationFrameResolver")) {
  6961. foregroundPromiseFn().then(f);
  6962. } else {
  6963. return requestAnimationFrame.apply(window, arguments);
  6964. }
  6965. }
  6966.  
  6967. let busy = false;
  6968. const doIdomRender = function () {
  6969. if (busy) {
  6970. return this.doIdomRender13.apply(this, arguments);
  6971. }
  6972. busy = true;
  6973. const { requestAnimationFrame, setTimeout } = window;
  6974. window.requestAnimationFrame = xrequestAnimationFrame;
  6975. window.setTimeout = xsetTimeout;
  6976. let r = this.doIdomRender13.apply(this, arguments);
  6977. window.requestAnimationFrame = requestAnimationFrame;
  6978. window.setTimeout = setTimeout;
  6979. busy = false;
  6980. return r;
  6981. };
  6982. for (const ytTag of ['ytd-lottie-player', 'yt-attributed-string', 'yt-image', 'yt-icon-shape', 'yt-button-shape', 'yt-button-view-model', 'yt-icon-badge-shape']) {
  6983.  
  6984.  
  6985. whenCEDefined(ytTag).then(() => {
  6986.  
  6987. let dummy;
  6988. let cProto;
  6989. dummy = document.createElement(ytTag);
  6990. cProto = insp(dummy).constructor.prototype;
  6991.  
  6992. cProto.doIdomRender13 = cProto.doIdomRender;
  6993. cProto.doIdomRender = doIdomRender;
  6994.  
  6995. if (cProto.doIdomRender13 === cProto.templatingFn) cProto.templatingFn = doIdomRender;
  6996.  
  6997. console.debug('[yt-js-engine-tamer] FIX_doIdomRender', ytTag)
  6998.  
  6999.  
  7000.  
  7001. });
  7002.  
  7003. }
  7004.  
  7005. }
  7006.  
  7007.  
  7008.  
  7009. });
  7010.  
  7011. });
  7012.  
  7013.  
  7014.  
  7015.  
  7016. if (isMainWindow) {
  7017.  
  7018. console.groupCollapsed(
  7019. "%cYouTube JS Engine Tamer",
  7020. "background-color: #EDE43B ; color: #000 ; font-weight: bold ; padding: 4px ;"
  7021. );
  7022.  
  7023.  
  7024.  
  7025. console.log("Script is loaded.");
  7026. console.log("This script changes the core mechanisms of the YouTube JS engine.");
  7027.  
  7028. console.log("This script is experimental and subject to further changes.");
  7029.  
  7030. console.log("This might boost your YouTube performance.");
  7031.  
  7032. console.log("CAUTION: This might break your YouTube.");
  7033.  
  7034.  
  7035. if (prepareLogs.length >= 1) {
  7036. console.log(" =========================================================================== ");
  7037.  
  7038. for (const msg of prepareLogs) {
  7039. console.log(msg)
  7040. }
  7041.  
  7042. console.log(" =========================================================================== ");
  7043. }
  7044.  
  7045. console.groupEnd();
  7046.  
  7047. }
  7048.  
  7049.  
  7050.  
  7051. })();