From 69cfb52837657e98fdbdd038d385faaf910ec465 Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Wed, 17 Apr 2024 14:11:25 +0300 Subject: [PATCH 01/55] hls clappr & dplayer --- packages/p2p-media-loader-demo/package.json | 1 + .../src/components/P2PVideoDemo.tsx | 24 +++++ .../components/players/HlsjsClapprPlayer.tsx | 86 +++++++++++++++++ .../src/components/players/HlsjsDPLayer.tsx | 92 +++++++++++++++++++ .../p2p-media-loader-demo/src/constants.ts | 2 +- .../src/declaration.d.ts | 9 ++ pnpm-lock.yaml | 3 + 7 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 packages/p2p-media-loader-demo/src/components/players/HlsjsClapprPlayer.tsx create mode 100644 packages/p2p-media-loader-demo/src/components/players/HlsjsDPLayer.tsx create mode 100644 packages/p2p-media-loader-demo/src/declaration.d.ts diff --git a/packages/p2p-media-loader-demo/package.json b/packages/p2p-media-loader-demo/package.json index fe4d1e20..62a567c7 100644 --- a/packages/p2p-media-loader-demo/package.json +++ b/packages/p2p-media-loader-demo/package.json @@ -46,6 +46,7 @@ }, "dependencies": { "d3": "^7.9.0", + "dplayer": "^1.27.1", "hls.js": "^1.5.7", "p2p-media-loader-core": "workspace:*", "p2p-media-loader-hlsjs": "workspace:*" diff --git a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx index a32fb56c..2d72dfbf 100644 --- a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx +++ b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx @@ -9,6 +9,8 @@ import { DownloadStatsChart } from "./chart/DownloadStatsChart"; import { NodeNetwork } from "./nodeNetwork/NodeNetwork"; import { DebugTools } from "./debugTools/DebugTools"; import { DownloadStats } from "../types"; +import { HlsjsDPlayer } from "./players/HlsjsDPLayer"; +import { HlsjsClapprPlayer } from "./players/HlsjsClapprPlayer"; declare global { interface Window { @@ -78,6 +80,28 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => { const renderPlayer = () => { switch (queryParams.player) { + case "hlsjs-clappr": + return ( + + ); + case "hlsjs-dplayer": + return ( + + ); case "hlsjs": return ( void; + onPeerDisconnect?: (peerId: string) => void; + onChunkDownloaded?: (bytesLength: number, downloadSource: string) => void; + onChunkUploaded?: (bytesLength: number) => void; +}; + +export const HlsjsClapprPlayer = ({ + streamUrl, + announceTrackers, + onPeerConnect, + onPeerDisconnect, + onChunkDownloaded, + onChunkUploaded, +}: HlsjsClapprProps) => { + const containerRef = useRef(null); + + useEffect(() => { + const hls = new HlsWithP2P({ + p2p: { + core: { + announceTrackers, + }, + }, + }); + + if (onPeerConnect) { + hls.p2pEngine.addEventListener("onPeerConnect", onPeerConnect); + } + if (onPeerDisconnect) { + hls.p2pEngine.addEventListener("onPeerClose", onPeerDisconnect); + } + if (onChunkDownloaded) { + hls.p2pEngine.addEventListener("onChunkDownloaded", onChunkDownloaded); + } + if (onChunkUploaded) { + hls.p2pEngine.addEventListener("onChunkUploaded", onChunkUploaded); + } + + /* eslint-disable */ + const clapprPlayer = new window.Clappr.Player({ + parentId: `#${containerRef.current?.id}`, + source: streamUrl, + playback: { + hlsjsConfig: { + ...hls.p2pEngine.getHlsJsConfig(), + }, + }, + plugins: [window.LevelSelector], + width: "100%", + height: "100%", + }); + + hls.p2pEngine.initClapprPlayer(clapprPlayer); + + window.videoPlayer = clapprPlayer; + return () => { + clapprPlayer.destroy(); + hls.destroy(); + }; + /* eslint-enable */ + }, [ + announceTrackers, + onChunkDownloaded, + onChunkUploaded, + onPeerConnect, + onPeerDisconnect, + streamUrl, + ]); + + return ( +
+ ); +}; diff --git a/packages/p2p-media-loader-demo/src/components/players/HlsjsDPLayer.tsx b/packages/p2p-media-loader-demo/src/components/players/HlsjsDPLayer.tsx new file mode 100644 index 00000000..80ae1b7c --- /dev/null +++ b/packages/p2p-media-loader-demo/src/components/players/HlsjsDPLayer.tsx @@ -0,0 +1,92 @@ +import { useEffect, useRef } from "react"; +import { HlsJsP2PEngine } from "p2p-media-loader-hlsjs"; +import Hls from "hls.js"; +import DPlayer from "dplayer"; + +const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hls); + +type HlsjsPlayerProps = { + streamUrl: string; + announceTrackers: string[]; + onPeerConnect?: (peerId: string) => void; + onPeerDisconnect?: (peerId: string) => void; + onChunkDownloaded?: (bytesLength: number, downloadSource: string) => void; + onChunkUploaded?: (bytesLength: number) => void; +}; + +export const HlsjsDPlayer = ({ + streamUrl, + announceTrackers, + onPeerConnect, + onPeerDisconnect, + onChunkDownloaded, + onChunkUploaded, +}: HlsjsPlayerProps) => { + const videoRef = useRef(null); + const containerRef = useRef(null); + + useEffect(() => { + if (!videoRef.current) return; + + const hls = new HlsWithP2P({ + p2p: { + core: { + announceTrackers, + }, + }, + }); + + const player = new DPlayer({ + container: containerRef.current, + video: { + url: "", + type: "customHls", + customType: { + customHls: (video: HTMLVideoElement) => { + if (onPeerConnect) { + hls.p2pEngine.addEventListener("onPeerConnect", onPeerConnect); + } + if (onPeerDisconnect) { + hls.p2pEngine.addEventListener("onPeerClose", onPeerDisconnect); + } + if (onChunkDownloaded) { + hls.p2pEngine.addEventListener( + "onChunkDownloaded", + onChunkDownloaded, + ); + } + if (onChunkUploaded) { + hls.p2pEngine.addEventListener( + "onChunkUploaded", + onChunkUploaded, + ); + } + + hls.attachMedia(video); + hls.loadSource(streamUrl); + }, + }, + }, + }); + + player.play(); + + return () => { + player.destroy(); + hls.destroy(); + }; + }, [ + streamUrl, + announceTrackers, + onPeerConnect, + onPeerDisconnect, + onChunkDownloaded, + onChunkUploaded, + ]); + + return ( +
+
+ ); +}; diff --git a/packages/p2p-media-loader-demo/src/constants.ts b/packages/p2p-media-loader-demo/src/constants.ts index 0d09dcaa..fbab90cf 100644 --- a/packages/p2p-media-loader-demo/src/constants.ts +++ b/packages/p2p-media-loader-demo/src/constants.ts @@ -1,4 +1,4 @@ -export const PLAYERS = ["hlsjs", "hlsjs-dplayer"] as const; +export const PLAYERS = ["hlsjs", "hlsjs-dplayer", "hlsjs-clappr"] as const; export const DEFAULT_STREAM = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; export const COLORS = { diff --git a/packages/p2p-media-loader-demo/src/declaration.d.ts b/packages/p2p-media-loader-demo/src/declaration.d.ts new file mode 100644 index 00000000..755b3a26 --- /dev/null +++ b/packages/p2p-media-loader-demo/src/declaration.d.ts @@ -0,0 +1,9 @@ +declare global { + interface Window { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Clappr: any; + LevelSelector: unknown; + } +} + +export {}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index edddce2c..76b96445 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,6 +109,9 @@ importers: d3: specifier: ^7.9.0 version: 7.9.0 + dplayer: + specifier: ^1.27.1 + version: 1.27.1 hls.js: specifier: ^1.5.7 version: 1.5.7 From 9bd174f496517a0d96961f3f4cf8105b41523ed8 Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Thu, 18 Apr 2024 09:14:52 +0300 Subject: [PATCH 02/55] vime player --- packages/p2p-media-loader-demo/package.json | 1 + .../src/components/P2PVideoDemo.tsx | 13 +++ .../src/components/players/HlsjsVime.tsx | 84 +++++++++++++++++++ .../p2p-media-loader-demo/src/constants.ts | 7 +- pnpm-lock.yaml | 60 +++++++++++++ 5 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 packages/p2p-media-loader-demo/src/components/players/HlsjsVime.tsx diff --git a/packages/p2p-media-loader-demo/package.json b/packages/p2p-media-loader-demo/package.json index 62a567c7..f540a5de 100644 --- a/packages/p2p-media-loader-demo/package.json +++ b/packages/p2p-media-loader-demo/package.json @@ -45,6 +45,7 @@ "clean-with-modules": "rimraf node_modules && pnpm clean" }, "dependencies": { + "@vime/react": "^5.4.1", "d3": "^7.9.0", "dplayer": "^1.27.1", "hls.js": "^1.5.7", diff --git a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx index 2d72dfbf..48582b9c 100644 --- a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx +++ b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx @@ -11,6 +11,7 @@ import { DebugTools } from "./debugTools/DebugTools"; import { DownloadStats } from "../types"; import { HlsjsDPlayer } from "./players/HlsjsDPLayer"; import { HlsjsClapprPlayer } from "./players/HlsjsClapprPlayer"; +import { HlsjsVime } from "./players/HlsjsVime"; declare global { interface Window { @@ -80,6 +81,18 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => { const renderPlayer = () => { switch (queryParams.player) { + case "hlsjs-vime": + return ( + + ); + case "hlsjs-clappr": return ( void; + onPeerDisconnect?: (peerId: string) => void; + onChunkDownloaded?: (bytesLength: number, downloadSource: string) => void; + onChunkUploaded?: (bytesLength: number) => void; +}; + +interface CustomHlsWithP2P extends Hls { + p2pEngine: HlsJsP2PEngine; +} + +const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hls); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access +(window as any).Hls = HlsWithP2P; + +export const HlsjsVime = ({ + streamUrl, + announceTrackers, + onPeerConnect, + onPeerDisconnect, + onChunkDownloaded, + onChunkUploaded, +}: HlsjsVimeProps) => { + const vimeRef = useRef(null); + + useEffect(() => { + if (!vimeRef.current) return; + const vimeHlsElement = vimeRef.current; + + vimeHlsElement.config = { + p2p: { + onHlsJsCreated: (hls: CustomHlsWithP2P) => { + if (onPeerConnect) { + hls.p2pEngine.addEventListener("onPeerConnect", onPeerConnect); + } + if (onPeerDisconnect) { + hls.p2pEngine.addEventListener("onPeerClose", onPeerDisconnect); + } + if (onChunkDownloaded) { + hls.p2pEngine.addEventListener( + "onChunkDownloaded", + onChunkDownloaded, + ); + } + if (onChunkUploaded) { + hls.p2pEngine.addEventListener("onChunkUploaded", onChunkUploaded); + } + }, + core: { + announceTrackers, + }, + }, + }; + }, [ + announceTrackers, + onChunkDownloaded, + onChunkUploaded, + onPeerConnect, + onPeerDisconnect, + ]); + + return ( +
+ + + + + + + +
+ ); +}; diff --git a/packages/p2p-media-loader-demo/src/constants.ts b/packages/p2p-media-loader-demo/src/constants.ts index fbab90cf..83bdba68 100644 --- a/packages/p2p-media-loader-demo/src/constants.ts +++ b/packages/p2p-media-loader-demo/src/constants.ts @@ -1,4 +1,9 @@ -export const PLAYERS = ["hlsjs", "hlsjs-dplayer", "hlsjs-clappr"] as const; +export const PLAYERS = [ + "hlsjs", + "hlsjs-dplayer", + "hlsjs-clappr", + "hlsjs-vime", +] as const; export const DEFAULT_STREAM = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; export const COLORS = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76b96445..517927ad 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -106,6 +106,9 @@ importers: packages/p2p-media-loader-demo: dependencies: + '@vime/react': + specifier: ^5.4.1 + version: 5.4.1(@vime/core@5.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) d3: specifier: ^7.9.0 version: 7.9.0 @@ -582,6 +585,14 @@ packages: cpu: [x64] os: [win32] + '@seznam/compose-react-refs@1.0.6': + resolution: {integrity: sha512-izzOXQfeQLonzrIQb8u6LQ8dk+ymz3WXTIXjvOlTXHq6sbzROg3NWU+9TTAOpEoK9Bth24/6F/XrfHJ5yR5n6Q==} + + '@stencil/core@2.5.2': + resolution: {integrity: sha512-bgjPXkSzzg1WnTgVUm6m5ZzpKt602WmA/QljODAW1xVN40OHJdbGblzF/F6MFzqv2c5Cy30CB41arc8qADIdcQ==} + engines: {node: '>=12.10.0', npm: '>=6.0.0'} + hasBin: true + '@thaunknown/simple-peer@9.12.1': resolution: {integrity: sha512-IS5BXvXx7cvBAzaxqotJf4s4rJCPk5JABLK6Gbnn7oAmWVcH4hYABabBBrvvJtv/xyUqR4v/H3LalnGRJJfEog==} @@ -702,6 +713,9 @@ packages: '@types/estree@1.0.5': resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + '@types/fscreen@1.0.4': + resolution: {integrity: sha512-TsjxyAUvlvuQyao9vNk0yES4nY07K9xoAbkhgXU948JG39EqlLxniWuW9OiZde9Q8ACSpu3fmbXXRAfb/l/HqQ==} + '@types/geojson@7946.0.14': resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==} @@ -787,6 +801,16 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + '@vime/core@5.4.1': + resolution: {integrity: sha512-ZFpV3xqZJ5tvh5rZOYKRh8zFzNIKr2ZcK6L75nJjFjbWt/ZmFF2nMBxtD9/hC4Xjk9v7hp1+P9cmctL674VFgA==} + + '@vime/react@5.4.1': + resolution: {integrity: sha512-cwZDp6d+gGTfXiYhZlZ5QF7GvmJZfATcJG5Hdc1TulCnbxpw7zJsE5zH0p9d2YCkKKSE3/r64gG16a0kqZTaMg==} + peerDependencies: + '@vime/core': 5.4.1 + react: ^17.0.0 + react-dom: ^17.0.0 + '@vitejs/plugin-react@4.2.1': resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -1500,6 +1524,9 @@ packages: fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fscreen@1.2.0: + resolution: {integrity: sha512-hlq4+BU0hlPmwsFjwGGzZ+OZ9N/wq9Ljg/sq3pX+2CD7hrJsX9tJgWWK/wiNTFM212CLHWhicOoqwXyZGGetJg==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1932,6 +1959,9 @@ packages: resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} engines: {node: '>=16 || 14 >=14.17'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -2329,6 +2359,9 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + stencil-wormhole@3.4.1: + resolution: {integrity: sha512-ppYTcWTJnIl4ZAKwF39LTA9f/ypHfbVefsHdN2hpMQGrR57wt1TieZo9tlCM/r1Y4SFiZ5yz/cjho564C921Xw==} + stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} @@ -2942,6 +2975,10 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.13.0': optional: true + '@seznam/compose-react-refs@1.0.6': {} + + '@stencil/core@2.5.2': {} + '@thaunknown/simple-peer@9.12.1': dependencies: debug: 4.3.4 @@ -3111,6 +3148,8 @@ snapshots: '@types/estree@1.0.5': {} + '@types/fscreen@1.0.4': {} + '@types/geojson@7946.0.14': {} '@types/json-schema@7.0.15': {} @@ -3221,6 +3260,21 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vime/core@5.4.1': + dependencies: + '@stencil/core': 2.5.2 + '@types/fscreen': 1.0.4 + fscreen: 1.2.0 + mitt: 3.0.1 + stencil-wormhole: 3.4.1 + + '@vime/react@5.4.1(@vime/core@5.4.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + dependencies: + '@seznam/compose-react-refs': 1.0.6 + '@vime/core': 5.4.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + '@vitejs/plugin-react@4.2.1(vite@5.1.6)': dependencies: '@babel/core': 7.24.0 @@ -4245,6 +4299,8 @@ snapshots: fs.realpath@1.0.0: {} + fscreen@1.2.0: {} + fsevents@2.3.3: optional: true @@ -4667,6 +4723,8 @@ snapshots: minipass@7.0.4: {} + mitt@3.0.1: {} + ms@2.1.2: {} mux.js@6.3.0: @@ -5106,6 +5164,8 @@ snapshots: sprintf-js@1.1.3: {} + stencil-wormhole@3.4.1: {} + stream-browserify@3.0.0: dependencies: inherits: 2.0.4 From 00d2c349d7c8a73b5755e2ad2109160e6eade706 Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Thu, 18 Apr 2024 12:17:15 +0300 Subject: [PATCH 03/55] plyr player --- packages/p2p-media-loader-demo/package.json | 3 +- .../src/components/P2PVideoDemo.tsx | 13 + .../src/components/players/HlsjsPlyr.tsx | 96 ++ .../src/components/players/plyr.css | 1463 +++++++++++++++++ .../p2p-media-loader-demo/src/constants.ts | 1 + pnpm-lock.yaml | 39 + 6 files changed, 1614 insertions(+), 1 deletion(-) create mode 100644 packages/p2p-media-loader-demo/src/components/players/HlsjsPlyr.tsx create mode 100644 packages/p2p-media-loader-demo/src/components/players/plyr.css diff --git a/packages/p2p-media-loader-demo/package.json b/packages/p2p-media-loader-demo/package.json index f540a5de..f4993cde 100644 --- a/packages/p2p-media-loader-demo/package.json +++ b/packages/p2p-media-loader-demo/package.json @@ -50,7 +50,8 @@ "dplayer": "^1.27.1", "hls.js": "^1.5.7", "p2p-media-loader-core": "workspace:*", - "p2p-media-loader-hlsjs": "workspace:*" + "p2p-media-loader-hlsjs": "workspace:*", + "plyr": "^3.7.8" }, "devDependencies": { "@types/d3": "^7.4.3", diff --git a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx index 48582b9c..567eac14 100644 --- a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx +++ b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx @@ -12,6 +12,7 @@ import { DownloadStats } from "../types"; import { HlsjsDPlayer } from "./players/HlsjsDPLayer"; import { HlsjsClapprPlayer } from "./players/HlsjsClapprPlayer"; import { HlsjsVime } from "./players/HlsjsVime"; +import { HlsjsPlyr } from "./players/HlsjsPlyr"; declare global { interface Window { @@ -81,6 +82,18 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => { const renderPlayer = () => { switch (queryParams.player) { + case "hlsjs-plyr": + return ( + + ); + case "hlsjs-vime": return ( void; + onPeerDisconnect?: (peerId: string) => void; + onChunkDownloaded?: (bytesLength: number, downloadSource: string) => void; + onChunkUploaded?: (bytesLength: number) => void; +}; +const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hls); + +export const HlsjsPlyr = ({ + streamUrl, + announceTrackers, + onPeerConnect, + onPeerDisconnect, + onChunkDownloaded, + onChunkUploaded, +}: HlsjsPlayerProps) => { + const videoRef = useRef(null); + const playerRef = useRef(null); + + useEffect(() => { + if (!videoRef.current) return; + + const hls = new HlsWithP2P({ + p2p: { + core: { + announceTrackers, + }, + }, + }); + + if (onPeerConnect) { + hls.p2pEngine.addEventListener("onPeerConnect", onPeerConnect); + } + if (onPeerDisconnect) { + hls.p2pEngine.addEventListener("onPeerClose", onPeerDisconnect); + } + if (onChunkDownloaded) { + hls.p2pEngine.addEventListener("onChunkDownloaded", onChunkDownloaded); + } + if (onChunkUploaded) { + hls.p2pEngine.addEventListener("onChunkUploaded", onChunkUploaded); + } + + hls.on(Hls.Events.MANIFEST_PARSED, () => { + if (!videoRef.current) return; + + const levels = hls.levels; + + const quality: Options["quality"] = { + default: levels[levels.length - 1].height, + options: levels.map((level) => level.height), + forced: true, + onChange: (newQuality: number) => { + levels.forEach((level, levelIndex) => { + if (level.height === newQuality) { + hls.currentLevel = levelIndex; + } + }); + }, + }; + + if (!playerRef.current) { + playerRef.current = new Plyr(videoRef.current, { + quality, + autoplay: true, + }); + } + }); + + hls.attachMedia(videoRef.current); + hls.loadSource(streamUrl); + + return () => hls.destroy(); + }, [ + announceTrackers, + onChunkDownloaded, + onChunkUploaded, + onPeerConnect, + onPeerDisconnect, + streamUrl, + ]); + + return ( +
+
+ ); +}; diff --git a/packages/p2p-media-loader-demo/src/components/players/plyr.css b/packages/p2p-media-loader-demo/src/components/players/plyr.css new file mode 100644 index 00000000..c246c6d0 --- /dev/null +++ b/packages/p2p-media-loader-demo/src/components/players/plyr.css @@ -0,0 +1,1463 @@ +@charset "UTF-8"; +@keyframes plyr-progress { + to { + background-position: 25px 0; + background-position: var(--plyr-progress-loading-size, 25px) 0; + } +} +@keyframes plyr-popup { + 0% { + opacity: 0.5; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} +@keyframes plyr-fade-in { + 0% { + opacity: 0; + } + to { + opacity: 1; + } +} +.plyr { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + align-items: center; + direction: ltr; + display: flex; + flex-direction: column; + font-family: inherit; + font-family: var(--plyr-font-family, inherit); + font-variant-numeric: tabular-nums; + font-weight: 400; + font-weight: var(--plyr-font-weight-regular, 400); + line-height: 1.7; + line-height: var(--plyr-line-height, 1.7); + max-width: 100%; + min-width: 200px; + position: relative; + text-shadow: none; + transition: box-shadow 0.3s ease; + z-index: 0; +} +.plyr audio, +.plyr iframe, +.plyr video { + display: block; + height: 100%; + width: 100%; +} +.plyr button { + font: inherit; + line-height: inherit; + width: auto; +} +.plyr:focus { + outline: 0; +} +.plyr--full-ui { + box-sizing: border-box; +} +.plyr--full-ui *, +.plyr--full-ui :after, +.plyr--full-ui :before { + box-sizing: inherit; +} +.plyr--full-ui a, +.plyr--full-ui button, +.plyr--full-ui input, +.plyr--full-ui label { + touch-action: manipulation; +} +.plyr__badge { + background: #4a5464; + background: var(--plyr-badge-background, #4a5464); + border-radius: 2px; + border-radius: var(--plyr-badge-border-radius, 2px); + color: #fff; + color: var(--plyr-badge-text-color, #fff); + font-size: 9px; + font-size: var(--plyr-font-size-badge, 9px); + line-height: 1; + padding: 3px 4px; +} +.plyr--full-ui ::-webkit-media-text-track-container { + display: none; +} +.plyr__captions { + animation: plyr-fade-in 0.3s ease; + bottom: 0; + display: none; + font-size: 13px; + font-size: var(--plyr-font-size-small, 13px); + left: 0; + padding: 10px; + padding: var(--plyr-control-spacing, 10px); + position: absolute; + text-align: center; + transition: transform 0.4s ease-in-out; + width: 100%; +} +.plyr__captions span:empty { + display: none; +} +@media (min-width: 480px) { + .plyr__captions { + font-size: 15px; + font-size: var(--plyr-font-size-base, 15px); + padding: 20px; + padding: calc(var(--plyr-control-spacing, 10px) * 2); + } +} +@media (min-width: 768px) { + .plyr__captions { + font-size: 18px; + font-size: var(--plyr-font-size-large, 18px); + } +} +.plyr--captions-active .plyr__captions { + display: block; +} +.plyr:not(.plyr--hide-controls) .plyr__controls:not(:empty) ~ .plyr__captions { + transform: translateY(-40px); + transform: translateY(calc(var(--plyr-control-spacing, 10px) * -4)); +} +.plyr__caption { + background: rgba(0, 0, 0, 0.8); + background: var(--plyr-captions-background, rgba(0, 0, 0, 0.8)); + border-radius: 2px; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + color: #fff; + color: var(--plyr-captions-text-color, #fff); + line-height: 185%; + padding: 0.2em 0.5em; + white-space: pre-wrap; +} +.plyr__caption div { + display: inline; +} +.plyr__control { + background: transparent; + border: 0; + border-radius: 3px; + border-radius: var(--plyr-control-radius, 3px); + color: inherit; + cursor: pointer; + flex-shrink: 0; + overflow: visible; + padding: 7px; + padding: calc(var(--plyr-control-spacing, 10px) * 0.7); + position: relative; + transition: all 0.3s ease; +} +.plyr__control svg { + fill: currentColor; + display: block; + height: 18px; + height: var(--plyr-control-icon-size, 18px); + pointer-events: none; + width: 18px; + width: var(--plyr-control-icon-size, 18px); +} +.plyr__control:focus { + outline: 0; +} +.plyr__control.plyr__tab-focus { + outline: 3px dotted #00b2ff; + outline: var( + --plyr-tab-focus-color, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ) + dotted 3px; + outline-offset: 2px; +} +a.plyr__control { + text-decoration: none; +} +.plyr__control.plyr__control--pressed .icon--not-pressed, +.plyr__control.plyr__control--pressed .label--not-pressed, +.plyr__control:not(.plyr__control--pressed) .icon--pressed, +.plyr__control:not(.plyr__control--pressed) .label--pressed, +a.plyr__control:after, +a.plyr__control:before { + display: none; +} +.plyr--full-ui ::-webkit-media-controls { + display: none; +} +.plyr__controls { + align-items: center; + display: flex; + justify-content: flex-end; + text-align: center; +} +.plyr__controls .plyr__progress__container { + flex: 1; + min-width: 0; +} +.plyr__controls .plyr__controls__item { + margin-left: 2.5px; + margin-left: calc(var(--plyr-control-spacing, 10px) / 4); +} +.plyr__controls .plyr__controls__item:first-child { + margin-left: 0; + margin-right: auto; +} +.plyr__controls .plyr__controls__item.plyr__progress__container { + padding-left: 2.5px; + padding-left: calc(var(--plyr-control-spacing, 10px) / 4); +} +.plyr__controls .plyr__controls__item.plyr__time { + padding: 0 5px; + padding: 0 calc(var(--plyr-control-spacing, 10px) / 2); +} +.plyr__controls .plyr__controls__item.plyr__progress__container:first-child, +.plyr__controls .plyr__controls__item.plyr__time + .plyr__time, +.plyr__controls .plyr__controls__item.plyr__time:first-child { + padding-left: 0; +} +.plyr [data-plyr="airplay"], +.plyr [data-plyr="captions"], +.plyr [data-plyr="fullscreen"], +.plyr [data-plyr="pip"], +.plyr__controls:empty { + display: none; +} +.plyr--airplay-supported [data-plyr="airplay"], +.plyr--captions-enabled [data-plyr="captions"], +.plyr--fullscreen-enabled [data-plyr="fullscreen"], +.plyr--pip-supported [data-plyr="pip"] { + display: inline-block; +} +.plyr__menu { + display: flex; + position: relative; +} +.plyr__menu .plyr__control svg { + transition: transform 0.3s ease; +} +.plyr__menu .plyr__control[aria-expanded="true"] svg { + transform: rotate(90deg); +} +.plyr__menu .plyr__control[aria-expanded="true"] .plyr__tooltip { + display: none; +} +.plyr__menu__container { + animation: plyr-popup 0.2s ease; + background: hsla(0, 0%, 100%, 0.9); + background: var(--plyr-menu-background, hsla(0, 0%, 100%, 0.9)); + border-radius: 4px; + bottom: 100%; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: var(--plyr-menu-shadow, 0 1px 2px rgba(0, 0, 0, 0.15)); + color: #4a5464; + color: var(--plyr-menu-color, #4a5464); + font-size: 15px; + font-size: var(--plyr-font-size-base, 15px); + margin-bottom: 10px; + position: absolute; + right: -3px; + text-align: left; + white-space: nowrap; + z-index: 3; +} +.plyr__menu__container > div { + overflow: hidden; + transition: + height 0.35s cubic-bezier(0.4, 0, 0.2, 1), + width 0.35s cubic-bezier(0.4, 0, 0.2, 1); +} +.plyr__menu__container:after { + border: 4px solid transparent; + border-top-color: hsla(0, 0%, 100%, 0.9); + border: var(--plyr-menu-arrow-size, 4px) solid transparent; + border-top-color: var(--plyr-menu-background, hsla(0, 0%, 100%, 0.9)); + content: ""; + height: 0; + position: absolute; + right: 14px; + right: calc( + var(--plyr-control-icon-size, 18px) / 2 + var(--plyr-control-spacing, 10px) * + 0.7 - var(--plyr-menu-arrow-size, 4px) / 2 + ); + top: 100%; + width: 0; +} +.plyr__menu__container [role="menu"] { + padding: 7px; + padding: calc(var(--plyr-control-spacing, 10px) * 0.7); +} +.plyr__menu__container [role="menuitem"], +.plyr__menu__container [role="menuitemradio"] { + margin-top: 2px; +} +.plyr__menu__container [role="menuitem"]:first-child, +.plyr__menu__container [role="menuitemradio"]:first-child { + margin-top: 0; +} +.plyr__menu__container .plyr__control { + align-items: center; + color: #4a5464; + color: var(--plyr-menu-color, #4a5464); + display: flex; + font-size: 13px; + font-size: var(--plyr-font-size-menu, var(--plyr-font-size-small, 13px)); + padding: 4.66667px 10.5px; + padding: calc(var(--plyr-control-spacing, 10px) * 0.7/1.5) + calc(var(--plyr-control-spacing, 10px) * 0.7 * 1.5); + -webkit-user-select: none; + user-select: none; + width: 100%; +} +.plyr__menu__container .plyr__control > span { + align-items: inherit; + display: flex; + width: 100%; +} +.plyr__menu__container .plyr__control:after { + border: 4px solid transparent; + border: var(--plyr-menu-item-arrow-size, 4px) solid transparent; + content: ""; + position: absolute; + top: 50%; + transform: translateY(-50%); +} +.plyr__menu__container .plyr__control--forward { + padding-right: 28px; + padding-right: calc(var(--plyr-control-spacing, 10px) * 0.7 * 4); +} +.plyr__menu__container .plyr__control--forward:after { + border-left-color: #728197; + border-left-color: var(--plyr-menu-arrow-color, #728197); + right: 6.5px; + right: calc( + var(--plyr-control-spacing, 10px) * 0.7 * 1.5 - + var(--plyr-menu-item-arrow-size, 4px) + ); +} +.plyr__menu__container .plyr__control--forward.plyr__tab-focus:after, +.plyr__menu__container .plyr__control--forward:hover:after { + border-left-color: currentColor; +} +.plyr__menu__container .plyr__control--back { + font-weight: 400; + font-weight: var(--plyr-font-weight-regular, 400); + margin: 7px; + margin: calc(var(--plyr-control-spacing, 10px) * 0.7); + margin-bottom: 3.5px; + margin-bottom: calc(var(--plyr-control-spacing, 10px) * 0.7/2); + padding-left: 28px; + padding-left: calc(var(--plyr-control-spacing, 10px) * 0.7 * 4); + position: relative; + width: calc(100% - 14px); + width: calc(100% - var(--plyr-control-spacing, 10px) * 0.7 * 2); +} +.plyr__menu__container .plyr__control--back:after { + border-right-color: #728197; + border-right-color: var(--plyr-menu-arrow-color, #728197); + left: 6.5px; + left: calc( + var(--plyr-control-spacing, 10px) * 0.7 * 1.5 - + var(--plyr-menu-item-arrow-size, 4px) + ); +} +.plyr__menu__container .plyr__control--back:before { + background: #dcdfe5; + background: var(--plyr-menu-back-border-color, #dcdfe5); + box-shadow: 0 1px 0 #fff; + box-shadow: 0 1px 0 var(--plyr-menu-back-border-shadow-color, #fff); + content: ""; + height: 1px; + left: 0; + margin-top: 3.5px; + margin-top: calc(var(--plyr-control-spacing, 10px) * 0.7/2); + overflow: hidden; + position: absolute; + right: 0; + top: 100%; +} +.plyr__menu__container .plyr__control--back.plyr__tab-focus:after, +.plyr__menu__container .plyr__control--back:hover:after { + border-right-color: currentColor; +} +.plyr__menu__container .plyr__control[role="menuitemradio"] { + padding-left: 7px; + padding-left: calc(var(--plyr-control-spacing, 10px) * 0.7); +} +.plyr__menu__container .plyr__control[role="menuitemradio"]:after, +.plyr__menu__container .plyr__control[role="menuitemradio"]:before { + border-radius: 100%; +} +.plyr__menu__container .plyr__control[role="menuitemradio"]:before { + background: rgba(0, 0, 0, 0.1); + content: ""; + display: block; + flex-shrink: 0; + height: 16px; + margin-right: 10px; + margin-right: var(--plyr-control-spacing, 10px); + transition: all 0.3s ease; + width: 16px; +} +.plyr__menu__container .plyr__control[role="menuitemradio"]:after { + background: #fff; + border: 0; + height: 6px; + left: 12px; + opacity: 0; + top: 50%; + transform: translateY(-50%) scale(0); + transition: + transform 0.3s ease, + opacity 0.3s ease; + width: 6px; +} +.plyr__menu__container + .plyr__control[role="menuitemradio"][aria-checked="true"]:before { + background: #00b2ff; + background: var( + --plyr-control-toggle-checked-background, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ); +} +.plyr__menu__container + .plyr__control[role="menuitemradio"][aria-checked="true"]:after { + opacity: 1; + transform: translateY(-50%) scale(1); +} +.plyr__menu__container + .plyr__control[role="menuitemradio"].plyr__tab-focus:before, +.plyr__menu__container .plyr__control[role="menuitemradio"]:hover:before { + background: rgba(35, 40, 47, 0.1); +} +.plyr__menu__container .plyr__menu__value { + align-items: center; + display: flex; + margin-left: auto; + margin-right: calc(-7px - -2); + margin-right: calc(var(--plyr-control-spacing, 10px) * 0.7 * -1 - -2); + overflow: hidden; + padding-left: 24.5px; + padding-left: calc(var(--plyr-control-spacing, 10px) * 0.7 * 3.5); + pointer-events: none; +} +.plyr--full-ui input[type="range"] { + -webkit-appearance: none; + appearance: none; + background: transparent; + border: 0; + border-radius: 26px; + border-radius: calc(var(--plyr-range-thumb-height, 13px) * 2); + color: #00b2ff; + color: var( + --plyr-range-fill-background, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ); + display: block; + height: 19px; + height: calc( + var(--plyr-range-thumb-active-shadow-width, 3px) * 2 + + var(--plyr-range-thumb-height, 13px) + ); + margin: 0; + min-width: 0; + padding: 0; + transition: box-shadow 0.3s ease; + width: 100%; +} +.plyr--full-ui input[type="range"]::-webkit-slider-runnable-track { + background: transparent; + background-image: linear-gradient(90deg, currentColor 0, transparent 0); + background-image: linear-gradient( + to right, + currentColor var(--value, 0), + transparent var(--value, 0) + ); + border: 0; + border-radius: 2.5px; + border-radius: calc(var(--plyr-range-track-height, 5px) / 2); + height: 5px; + height: var(--plyr-range-track-height, 5px); + -webkit-transition: box-shadow 0.3s ease; + transition: box-shadow 0.3s ease; + -webkit-user-select: none; + user-select: none; +} +.plyr--full-ui input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + background: #fff; + background: var(--plyr-range-thumb-background, #fff); + border: 0; + border-radius: 100%; + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2); + box-shadow: var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ); + height: 13px; + height: var(--plyr-range-thumb-height, 13px); + margin-top: -4px; + margin-top: calc( + (var(--plyr-range-thumb-height, 13px) - var(--plyr-range-track-height, 5px)) / + 2 * -1 + ); + position: relative; + -webkit-transition: all 0.2s ease; + transition: all 0.2s ease; + width: 13px; + width: var(--plyr-range-thumb-height, 13px); +} +.plyr--full-ui input[type="range"]::-moz-range-track { + background: transparent; + border: 0; + border-radius: 2.5px; + border-radius: calc(var(--plyr-range-track-height, 5px) / 2); + height: 5px; + height: var(--plyr-range-track-height, 5px); + -moz-transition: box-shadow 0.3s ease; + transition: box-shadow 0.3s ease; + user-select: none; +} +.plyr--full-ui input[type="range"]::-moz-range-thumb { + background: #fff; + background: var(--plyr-range-thumb-background, #fff); + border: 0; + border-radius: 100%; + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2); + box-shadow: var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ); + height: 13px; + height: var(--plyr-range-thumb-height, 13px); + position: relative; + -moz-transition: all 0.2s ease; + transition: all 0.2s ease; + width: 13px; + width: var(--plyr-range-thumb-height, 13px); +} +.plyr--full-ui input[type="range"]::-moz-range-progress { + background: currentColor; + border-radius: 2.5px; + border-radius: calc(var(--plyr-range-track-height, 5px) / 2); + height: 5px; + height: var(--plyr-range-track-height, 5px); +} +.plyr--full-ui input[type="range"]::-ms-track { + color: transparent; +} +.plyr--full-ui input[type="range"]::-ms-fill-upper, +.plyr--full-ui input[type="range"]::-ms-track { + background: transparent; + border: 0; + border-radius: 2.5px; + border-radius: calc(var(--plyr-range-track-height, 5px) / 2); + height: 5px; + height: var(--plyr-range-track-height, 5px); + -ms-transition: box-shadow 0.3s ease; + transition: box-shadow 0.3s ease; + user-select: none; +} +.plyr--full-ui input[type="range"]::-ms-fill-lower { + background: transparent; + background: currentColor; + border: 0; + border-radius: 2.5px; + border-radius: calc(var(--plyr-range-track-height, 5px) / 2); + height: 5px; + height: var(--plyr-range-track-height, 5px); + -ms-transition: box-shadow 0.3s ease; + transition: box-shadow 0.3s ease; + user-select: none; +} +.plyr--full-ui input[type="range"]::-ms-thumb { + background: #fff; + background: var(--plyr-range-thumb-background, #fff); + border: 0; + border-radius: 100%; + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2); + box-shadow: var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ); + height: 13px; + height: var(--plyr-range-thumb-height, 13px); + margin-top: 0; + position: relative; + -ms-transition: all 0.2s ease; + transition: all 0.2s ease; + width: 13px; + width: var(--plyr-range-thumb-height, 13px); +} +.plyr--full-ui input[type="range"]::-ms-tooltip { + display: none; +} +.plyr--full-ui input[type="range"]::-moz-focus-outer { + border: 0; +} +.plyr--full-ui input[type="range"]:focus { + outline: 0; +} +.plyr--full-ui + input[type="range"].plyr__tab-focus::-webkit-slider-runnable-track { + outline: 3px dotted #00b2ff; + outline: var( + --plyr-tab-focus-color, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ) + dotted 3px; + outline-offset: 2px; +} +.plyr--full-ui input[type="range"].plyr__tab-focus::-moz-range-track { + outline: 3px dotted #00b2ff; + outline: var( + --plyr-tab-focus-color, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ) + dotted 3px; + outline-offset: 2px; +} +.plyr--full-ui input[type="range"].plyr__tab-focus::-ms-track { + outline: 3px dotted #00b2ff; + outline: var( + --plyr-tab-focus-color, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ) + dotted 3px; + outline-offset: 2px; +} +.plyr__poster { + background-color: #000; + background-color: var( + --plyr-video-background, + var(--plyr-video-background, #000) + ); + background-position: 50% 50%; + background-repeat: no-repeat; + background-size: contain; + height: 100%; + left: 0; + opacity: 0; + position: absolute; + top: 0; + transition: opacity 0.2s ease; + width: 100%; + z-index: 1; +} +.plyr--stopped.plyr__poster-enabled .plyr__poster { + opacity: 1; +} +.plyr--youtube.plyr--paused.plyr__poster-enabled:not(.plyr--stopped) + .plyr__poster { + display: none; +} +.plyr__time { + font-size: 13px; + font-size: var(--plyr-font-size-time, var(--plyr-font-size-small, 13px)); +} +.plyr__time + .plyr__time:before { + content: "⁄"; + margin-right: 10px; + margin-right: var(--plyr-control-spacing, 10px); +} +@media (max-width: 767px) { + .plyr__time + .plyr__time { + display: none; + } +} +.plyr__tooltip { + background: hsla(0, 0%, 100%, 0.9); + background: var(--plyr-tooltip-background, hsla(0, 0%, 100%, 0.9)); + border-radius: 5px; + border-radius: var(--plyr-tooltip-radius, 5px); + bottom: 100%; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: var(--plyr-tooltip-shadow, 0 1px 2px rgba(0, 0, 0, 0.15)); + color: #4a5464; + color: var(--plyr-tooltip-color, #4a5464); + font-size: 13px; + font-size: var(--plyr-font-size-small, 13px); + font-weight: 400; + font-weight: var(--plyr-font-weight-regular, 400); + left: 50%; + line-height: 1.3; + margin-bottom: 10px; + margin-bottom: calc(var(--plyr-control-spacing, 10px) / 2 * 2); + opacity: 0; + padding: 5px 7.5px; + padding: calc(var(--plyr-control-spacing, 10px) / 2) + calc(var(--plyr-control-spacing, 10px) / 2 * 1.5); + pointer-events: none; + position: absolute; + transform: translate(-50%, 10px) scale(0.8); + transform-origin: 50% 100%; + transition: + transform 0.2s ease 0.1s, + opacity 0.2s ease 0.1s; + white-space: nowrap; + z-index: 2; +} +.plyr__tooltip:before { + border-left: 4px solid transparent; + border-left: var(--plyr-tooltip-arrow-size, 4px) solid transparent; + border-right: 4px solid transparent; + border-right: var(--plyr-tooltip-arrow-size, 4px) solid transparent; + border-top: 4px solid hsla(0, 0%, 100%, 0.9); + border-top: var(--plyr-tooltip-arrow-size, 4px) solid + var(--plyr-tooltip-background, hsla(0, 0%, 100%, 0.9)); + bottom: -4px; + bottom: calc(var(--plyr-tooltip-arrow-size, 4px) * -1); + content: ""; + height: 0; + left: 50%; + position: absolute; + transform: translateX(-50%); + width: 0; + z-index: 2; +} +.plyr .plyr__control.plyr__tab-focus .plyr__tooltip, +.plyr .plyr__control:hover .plyr__tooltip, +.plyr__tooltip--visible { + opacity: 1; + transform: translate(-50%) scale(1); +} +.plyr .plyr__control:hover .plyr__tooltip { + z-index: 3; +} +.plyr__controls > .plyr__control:first-child .plyr__tooltip, +.plyr__controls > .plyr__control:first-child + .plyr__control .plyr__tooltip { + left: 0; + transform: translateY(10px) scale(0.8); + transform-origin: 0 100%; +} +.plyr__controls > .plyr__control:first-child .plyr__tooltip:before, +.plyr__controls + > .plyr__control:first-child + + .plyr__control + .plyr__tooltip:before { + left: 16px; + left: calc( + var(--plyr-control-icon-size, 18px) / 2 + var(--plyr-control-spacing, 10px) * + 0.7 + ); +} +.plyr__controls > .plyr__control:last-child .plyr__tooltip { + left: auto; + right: 0; + transform: translateY(10px) scale(0.8); + transform-origin: 100% 100%; +} +.plyr__controls > .plyr__control:last-child .plyr__tooltip:before { + left: auto; + right: 16px; + right: calc( + var(--plyr-control-icon-size, 18px) / 2 + var(--plyr-control-spacing, 10px) * + 0.7 + ); + transform: translateX(50%); +} +.plyr__controls > .plyr__control:first-child .plyr__tooltip--visible, +.plyr__controls + > .plyr__control:first-child + + .plyr__control + .plyr__tooltip--visible, +.plyr__controls + > .plyr__control:first-child + + .plyr__control.plyr__tab-focus + .plyr__tooltip, +.plyr__controls + > .plyr__control:first-child + + .plyr__control:hover + .plyr__tooltip, +.plyr__controls > .plyr__control:first-child.plyr__tab-focus .plyr__tooltip, +.plyr__controls > .plyr__control:first-child:hover .plyr__tooltip, +.plyr__controls > .plyr__control:last-child .plyr__tooltip--visible, +.plyr__controls > .plyr__control:last-child.plyr__tab-focus .plyr__tooltip, +.plyr__controls > .plyr__control:last-child:hover .plyr__tooltip { + transform: translate(0) scale(1); +} +.plyr__progress { + left: 6.5px; + left: calc(var(--plyr-range-thumb-height, 13px) * 0.5); + margin-right: 13px; + margin-right: var(--plyr-range-thumb-height, 13px); + position: relative; +} +.plyr__progress input[type="range"], +.plyr__progress__buffer { + margin-left: -6.5px; + margin-left: calc(var(--plyr-range-thumb-height, 13px) * -0.5); + margin-right: -6.5px; + margin-right: calc(var(--plyr-range-thumb-height, 13px) * -0.5); + width: calc(100% + 13px); + width: calc(100% + var(--plyr-range-thumb-height, 13px)); +} +.plyr__progress input[type="range"] { + position: relative; + z-index: 2; +} +.plyr__progress .plyr__tooltip { + left: 0; + max-width: 120px; + overflow-wrap: break-word; + white-space: normal; +} +.plyr__progress__buffer { + -webkit-appearance: none; + background: transparent; + border: 0; + border-radius: 100px; + height: 5px; + height: var(--plyr-range-track-height, 5px); + left: 0; + margin-top: -2.5px; + margin-top: calc((var(--plyr-range-track-height, 5px) / 2) * -1); + padding: 0; + position: absolute; + top: 50%; +} +.plyr__progress__buffer::-webkit-progress-bar { + background: transparent; +} +.plyr__progress__buffer::-webkit-progress-value { + background: currentColor; + border-radius: 100px; + min-width: 5px; + min-width: var(--plyr-range-track-height, 5px); + -webkit-transition: width 0.2s ease; + transition: width 0.2s ease; +} +.plyr__progress__buffer::-moz-progress-bar { + background: currentColor; + border-radius: 100px; + min-width: 5px; + min-width: var(--plyr-range-track-height, 5px); + -moz-transition: width 0.2s ease; + transition: width 0.2s ease; +} +.plyr__progress__buffer::-ms-fill { + border-radius: 100px; + -ms-transition: width 0.2s ease; + transition: width 0.2s ease; +} +.plyr--loading .plyr__progress__buffer { + animation: plyr-progress 1s linear infinite; + background-image: linear-gradient( + -45deg, + rgba(35, 40, 47, 0.6) 25%, + transparent 0, + transparent 50%, + rgba(35, 40, 47, 0.6) 0, + rgba(35, 40, 47, 0.6) 75%, + transparent 0, + transparent + ); + background-image: linear-gradient( + -45deg, + var(--plyr-progress-loading-background, rgba(35, 40, 47, 0.6)) 25%, + transparent 25%, + transparent 50%, + var(--plyr-progress-loading-background, rgba(35, 40, 47, 0.6)) 50%, + var(--plyr-progress-loading-background, rgba(35, 40, 47, 0.6)) 75%, + transparent 75%, + transparent + ); + background-repeat: repeat-x; + background-size: 25px 25px; + background-size: var(--plyr-progress-loading-size, 25px) + var(--plyr-progress-loading-size, 25px); + color: transparent; +} +.plyr--video.plyr--loading .plyr__progress__buffer { + background-color: hsla(0, 0%, 100%, 0.25); + background-color: var( + --plyr-video-progress-buffered-background, + hsla(0, 0%, 100%, 0.25) + ); +} +.plyr--audio.plyr--loading .plyr__progress__buffer { + background-color: rgba(193, 200, 209, 0.6); + background-color: var( + --plyr-audio-progress-buffered-background, + rgba(193, 200, 209, 0.6) + ); +} +.plyr__progress__marker { + background-color: #fff; + background-color: var(--plyr-progress-marker-background, #fff); + border-radius: 1px; + height: 5px; + height: var(--plyr-range-track-height, 5px); + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: 3px; + width: var(--plyr-progress-marker-width, 3px); + z-index: 3; +} +.plyr__volume { + align-items: center; + display: flex; + max-width: 110px; + min-width: 80px; + position: relative; + width: 20%; +} +.plyr__volume input[type="range"] { + margin-left: 5px; + margin-left: calc(var(--plyr-control-spacing, 10px) / 2); + margin-right: 5px; + margin-right: calc(var(--plyr-control-spacing, 10px) / 2); + position: relative; + z-index: 2; +} +.plyr--is-ios .plyr__volume { + min-width: 0; + width: auto; +} +.plyr--audio { + display: block; +} +.plyr--audio .plyr__controls { + background: #fff; + background: var(--plyr-audio-controls-background, #fff); + border-radius: inherit; + color: #4a5464; + color: var(--plyr-audio-control-color, #4a5464); + padding: 10px; + padding: var(--plyr-control-spacing, 10px); +} +.plyr--audio .plyr__control.plyr__tab-focus, +.plyr--audio .plyr__control:hover, +.plyr--audio .plyr__control[aria-expanded="true"] { + background: #00b2ff; + background: var( + --plyr-audio-control-background-hover, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ); + color: #fff; + color: var(--plyr-audio-control-color-hover, #fff); +} +.plyr--full-ui.plyr--audio input[type="range"]::-webkit-slider-runnable-track { + background-color: rgba(193, 200, 209, 0.6); + background-color: var( + --plyr-audio-range-track-background, + var(--plyr-audio-progress-buffered-background, rgba(193, 200, 209, 0.6)) + ); +} +.plyr--full-ui.plyr--audio input[type="range"]::-moz-range-track { + background-color: rgba(193, 200, 209, 0.6); + background-color: var( + --plyr-audio-range-track-background, + var(--plyr-audio-progress-buffered-background, rgba(193, 200, 209, 0.6)) + ); +} +.plyr--full-ui.plyr--audio input[type="range"]::-ms-track { + background-color: rgba(193, 200, 209, 0.6); + background-color: var( + --plyr-audio-range-track-background, + var(--plyr-audio-progress-buffered-background, rgba(193, 200, 209, 0.6)) + ); +} +.plyr--full-ui.plyr--audio input[type="range"]:active::-webkit-slider-thumb { + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2), + 0 0 0 3px rgba(35, 40, 47, 0.1); + box-shadow: + var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ), + 0 0 0 var(--plyr-range-thumb-active-shadow-width, 3px) + var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1)); +} +.plyr--full-ui.plyr--audio input[type="range"]:active::-moz-range-thumb { + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2), + 0 0 0 3px rgba(35, 40, 47, 0.1); + box-shadow: + var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ), + 0 0 0 var(--plyr-range-thumb-active-shadow-width, 3px) + var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1)); +} +.plyr--full-ui.plyr--audio input[type="range"]:active::-ms-thumb { + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2), + 0 0 0 3px rgba(35, 40, 47, 0.1); + box-shadow: + var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ), + 0 0 0 var(--plyr-range-thumb-active-shadow-width, 3px) + var(--plyr-audio-range-thumb-active-shadow-color, rgba(35, 40, 47, 0.1)); +} +.plyr--audio .plyr__progress__buffer { + color: rgba(193, 200, 209, 0.6); + color: var( + --plyr-audio-progress-buffered-background, + rgba(193, 200, 209, 0.6) + ); +} +.plyr--video { + background: #000; + background: var(--plyr-video-background, var(--plyr-video-background, #000)); + overflow: hidden; +} +.plyr--video.plyr--menu-open { + overflow: visible; +} +.plyr__video-wrapper { + background: #000; + background: var(--plyr-video-background, var(--plyr-video-background, #000)); + height: 100%; + margin: auto; + overflow: hidden; + position: relative; + width: 100%; +} +.plyr__video-embed, +.plyr__video-wrapper--fixed-ratio { + aspect-ratio: 16/9; +} +@supports not (aspect-ratio: 16/9) { + .plyr__video-embed, + .plyr__video-wrapper--fixed-ratio { + height: 0; + padding-bottom: 56.25%; + position: relative; + } +} +.plyr__video-embed iframe, +.plyr__video-wrapper--fixed-ratio video { + border: 0; + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; +} +.plyr--full-ui .plyr__video-embed > .plyr__video-embed__container { + padding-bottom: 240%; + position: relative; + transform: translateY(-38.28125%); +} +.plyr--video .plyr__controls { + background: linear-gradient(transparent, rgba(0, 0, 0, 0.75)); + background: var( + --plyr-video-controls-background, + linear-gradient(transparent, rgba(0, 0, 0, 0.75)) + ); + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; + bottom: 0; + color: #fff; + color: var(--plyr-video-control-color, #fff); + left: 0; + padding: 5px; + padding: calc(var(--plyr-control-spacing, 10px) / 2); + padding-top: 20px; + padding-top: calc(var(--plyr-control-spacing, 10px) * 2); + position: absolute; + right: 0; + transition: + opacity 0.4s ease-in-out, + transform 0.4s ease-in-out; + z-index: 3; +} +@media (min-width: 480px) { + .plyr--video .plyr__controls { + padding: 10px; + padding: var(--plyr-control-spacing, 10px); + padding-top: 35px; + padding-top: calc(var(--plyr-control-spacing, 10px) * 3.5); + } +} +.plyr--video.plyr--hide-controls .plyr__controls { + opacity: 0; + pointer-events: none; + transform: translateY(100%); +} +.plyr--video .plyr__control.plyr__tab-focus, +.plyr--video .plyr__control:hover, +.plyr--video .plyr__control[aria-expanded="true"] { + background: #00b2ff; + background: var( + --plyr-video-control-background-hover, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ); + color: #fff; + color: var(--plyr-video-control-color-hover, #fff); +} +.plyr__control--overlaid { + background: #00b2ff; + background: var( + --plyr-video-control-background-hover, + var(--plyr-color-main, var(--plyr-color-main, #00b2ff)) + ); + border: 0; + border-radius: 100%; + color: #fff; + color: var(--plyr-video-control-color, #fff); + display: none; + left: 50%; + opacity: 0.9; + padding: 15px; + padding: calc(var(--plyr-control-spacing, 10px) * 1.5); + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + transition: 0.3s; + z-index: 2; +} +.plyr__control--overlaid svg { + left: 2px; + position: relative; +} +.plyr__control--overlaid:focus, +.plyr__control--overlaid:hover { + opacity: 1; +} +.plyr--playing .plyr__control--overlaid { + opacity: 0; + visibility: hidden; +} +.plyr--full-ui.plyr--video .plyr__control--overlaid { + display: block; +} +.plyr--full-ui.plyr--video input[type="range"]::-webkit-slider-runnable-track { + background-color: hsla(0, 0%, 100%, 0.25); + background-color: var( + --plyr-video-range-track-background, + var(--plyr-video-progress-buffered-background, hsla(0, 0%, 100%, 0.25)) + ); +} +.plyr--full-ui.plyr--video input[type="range"]::-moz-range-track { + background-color: hsla(0, 0%, 100%, 0.25); + background-color: var( + --plyr-video-range-track-background, + var(--plyr-video-progress-buffered-background, hsla(0, 0%, 100%, 0.25)) + ); +} +.plyr--full-ui.plyr--video input[type="range"]::-ms-track { + background-color: hsla(0, 0%, 100%, 0.25); + background-color: var( + --plyr-video-range-track-background, + var(--plyr-video-progress-buffered-background, hsla(0, 0%, 100%, 0.25)) + ); +} +.plyr--full-ui.plyr--video input[type="range"]:active::-webkit-slider-thumb { + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2), + 0 0 0 3px hsla(0, 0%, 100%, 0.5); + box-shadow: + var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ), + 0 0 0 var(--plyr-range-thumb-active-shadow-width, 3px) + var(--plyr-audio-range-thumb-active-shadow-color, hsla(0, 0%, 100%, 0.5)); +} +.plyr--full-ui.plyr--video input[type="range"]:active::-moz-range-thumb { + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2), + 0 0 0 3px hsla(0, 0%, 100%, 0.5); + box-shadow: + var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ), + 0 0 0 var(--plyr-range-thumb-active-shadow-width, 3px) + var(--plyr-audio-range-thumb-active-shadow-color, hsla(0, 0%, 100%, 0.5)); +} +.plyr--full-ui.plyr--video input[type="range"]:active::-ms-thumb { + box-shadow: + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2), + 0 0 0 3px hsla(0, 0%, 100%, 0.5); + box-shadow: + var( + --plyr-range-thumb-shadow, + 0 1px 1px rgba(35, 40, 47, 0.15), + 0 0 0 1px rgba(35, 40, 47, 0.2) + ), + 0 0 0 var(--plyr-range-thumb-active-shadow-width, 3px) + var(--plyr-audio-range-thumb-active-shadow-color, hsla(0, 0%, 100%, 0.5)); +} +.plyr--video .plyr__progress__buffer { + color: hsla(0, 0%, 100%, 0.25); + color: var( + --plyr-video-progress-buffered-background, + hsla(0, 0%, 100%, 0.25) + ); +} +.plyr:fullscreen { + background: #000; + border-radius: 0 !important; + height: 100%; + margin: 0; + width: 100%; +} +.plyr:fullscreen video { + height: 100%; +} +.plyr:fullscreen .plyr__control .icon--exit-fullscreen { + display: block; +} +.plyr:fullscreen .plyr__control .icon--exit-fullscreen + svg { + display: none; +} +.plyr:fullscreen.plyr--hide-controls { + cursor: none; +} +@media (min-width: 1024px) { + .plyr:fullscreen .plyr__captions { + font-size: 21px; + font-size: var(--plyr-font-size-xlarge, 21px); + } +} +.plyr--fullscreen-fallback { + background: #000; + border-radius: 0 !important; + bottom: 0; + display: block; + height: 100%; + left: 0; + margin: 0; + position: fixed; + right: 0; + top: 0; + width: 100%; + z-index: 10000000; +} +.plyr--fullscreen-fallback video { + height: 100%; +} +.plyr--fullscreen-fallback .plyr__control .icon--exit-fullscreen { + display: block; +} +.plyr--fullscreen-fallback .plyr__control .icon--exit-fullscreen + svg { + display: none; +} +.plyr--fullscreen-fallback.plyr--hide-controls { + cursor: none; +} +@media (min-width: 1024px) { + .plyr--fullscreen-fallback .plyr__captions { + font-size: 21px; + font-size: var(--plyr-font-size-xlarge, 21px); + } +} +.plyr__ads { + border-radius: inherit; + bottom: 0; + cursor: pointer; + left: 0; + overflow: hidden; + position: absolute; + right: 0; + top: 0; + z-index: -1; +} +.plyr__ads > div, +.plyr__ads > div iframe { + height: 100%; + position: absolute; + width: 100%; +} +.plyr__ads:after { + background: #23282f; + border-radius: 2px; + bottom: 10px; + bottom: var(--plyr-control-spacing, 10px); + color: #fff; + content: attr(data-badge-text); + font-size: 11px; + padding: 2px 6px; + pointer-events: none; + position: absolute; + right: 10px; + right: var(--plyr-control-spacing, 10px); + z-index: 3; +} +.plyr__ads:empty:after { + display: none; +} +.plyr__cues { + background: currentColor; + display: block; + height: 5px; + height: var(--plyr-range-track-height, 5px); + left: 0; + opacity: 0.8; + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 3px; + z-index: 3; +} +.plyr__preview-thumb { + background-color: hsla(0, 0%, 100%, 0.9); + background-color: var(--plyr-tooltip-background, hsla(0, 0%, 100%, 0.9)); + border-radius: 5px; + border-radius: var(--plyr-tooltip-radius, 5px); + bottom: 100%; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15); + box-shadow: var(--plyr-tooltip-shadow, 0 1px 2px rgba(0, 0, 0, 0.15)); + margin-bottom: 10px; + margin-bottom: calc(var(--plyr-control-spacing, 10px) / 2 * 2); + opacity: 0; + padding: 3px; + pointer-events: none; + position: absolute; + transform: translateY(10px) scale(0.8); + transform-origin: 50% 100%; + transition: + transform 0.2s ease 0.1s, + opacity 0.2s ease 0.1s; + z-index: 2; +} +.plyr__preview-thumb--is-shown { + opacity: 1; + transform: translate(0) scale(1); +} +.plyr__preview-thumb:before { + border-left: 4px solid transparent; + border-left: var(--plyr-tooltip-arrow-size, 4px) solid transparent; + border-right: 4px solid transparent; + border-right: var(--plyr-tooltip-arrow-size, 4px) solid transparent; + border-top: 4px solid hsla(0, 0%, 100%, 0.9); + border-top: var(--plyr-tooltip-arrow-size, 4px) solid + var(--plyr-tooltip-background, hsla(0, 0%, 100%, 0.9)); + bottom: -4px; + bottom: calc(var(--plyr-tooltip-arrow-size, 4px) * -1); + content: ""; + height: 0; + left: calc(50% + var(--preview-arrow-offset)); + position: absolute; + transform: translateX(-50%); + width: 0; + z-index: 2; +} +.plyr__preview-thumb__image-container { + background: #c1c8d1; + border-radius: 4px; + border-radius: calc(var(--plyr-tooltip-radius, 5px) - 1px); + overflow: hidden; + position: relative; + z-index: 0; +} +.plyr__preview-thumb__image-container img, +.plyr__preview-thumb__image-container:after { + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; +} +.plyr__preview-thumb__image-container:after { + border-radius: inherit; + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15); + content: ""; + pointer-events: none; +} +.plyr__preview-thumb__image-container img { + max-height: none; + max-width: none; +} +.plyr__preview-thumb__time-container { + background: linear-gradient(transparent, rgba(0, 0, 0, 0.75)); + background: var( + --plyr-video-controls-background, + linear-gradient(transparent, rgba(0, 0, 0, 0.75)) + ); + border-bottom-left-radius: 4px; + border-bottom-left-radius: calc(var(--plyr-tooltip-radius, 5px) - 1px); + border-bottom-right-radius: 4px; + border-bottom-right-radius: calc(var(--plyr-tooltip-radius, 5px) - 1px); + bottom: 0; + left: 0; + line-height: 1.1; + padding: 20px 6px 6px; + position: absolute; + right: 0; + z-index: 3; +} +.plyr__preview-thumb__time-container span { + color: #fff; + font-size: 13px; + font-size: var(--plyr-font-size-time, var(--plyr-font-size-small, 13px)); +} +.plyr__preview-scrubbing { + bottom: 0; + filter: blur(1px); + height: 100%; + left: 0; + margin: auto; + opacity: 0; + overflow: hidden; + pointer-events: none; + position: absolute; + right: 0; + top: 0; + transition: opacity 0.3s ease; + width: 100%; + z-index: 1; +} +.plyr__preview-scrubbing--is-shown { + opacity: 1; +} +.plyr__preview-scrubbing img { + height: 100%; + left: 0; + max-height: none; + max-width: none; + -o-object-fit: contain; + object-fit: contain; + position: absolute; + top: 0; + width: 100%; +} +.plyr--no-transition { + transition: none !important; +} +.plyr__sr-only { + clip: rect(1px, 1px, 1px, 1px); + border: 0 !important; + height: 1px !important; + overflow: hidden; + padding: 0 !important; + position: absolute !important; + width: 1px !important; +} +.plyr [hidden] { + display: none !important; +} diff --git a/packages/p2p-media-loader-demo/src/constants.ts b/packages/p2p-media-loader-demo/src/constants.ts index 83bdba68..091d31fc 100644 --- a/packages/p2p-media-loader-demo/src/constants.ts +++ b/packages/p2p-media-loader-demo/src/constants.ts @@ -3,6 +3,7 @@ export const PLAYERS = [ "hlsjs-dplayer", "hlsjs-clappr", "hlsjs-vime", + "hlsjs-plyr", ] as const; export const DEFAULT_STREAM = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 517927ad..91bd304b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -124,6 +124,9 @@ importers: p2p-media-loader-hlsjs: specifier: workspace:* version: link:../p2p-media-loader-hlsjs + plyr: + specifier: ^3.7.8 + version: 3.7.8 devDependencies: '@types/d3': specifier: ^7.4.3 @@ -1075,6 +1078,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + core-js@3.37.0: + resolution: {integrity: sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==} + core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -1116,6 +1122,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + custom-event-polyfill@1.0.7: + resolution: {integrity: sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==} + d3-array@3.2.4: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} @@ -1879,6 +1888,9 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + loadjs@4.3.0: + resolution: {integrity: sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -2127,6 +2139,9 @@ packages: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} + plyr@3.7.8: + resolution: {integrity: sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==} + possible-typed-array-names@1.0.0: resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} engines: {node: '>= 0.4'} @@ -2193,6 +2208,9 @@ packages: randomfill@1.0.4: resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + rangetouch@2.0.1: + resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==} + react-dom@18.2.0: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: @@ -2515,6 +2533,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-polyfill@1.1.12: + resolution: {integrity: sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==} + url@0.11.3: resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==} @@ -3623,6 +3644,8 @@ snapshots: convert-source-map@2.0.0: {} + core-js@3.37.0: {} + core-util-is@1.0.3: {} cp-file@10.0.0: @@ -3698,6 +3721,8 @@ snapshots: csstype@3.1.3: {} + custom-event-polyfill@1.0.7: {} + d3-array@3.2.4: dependencies: internmap: 2.0.3 @@ -4649,6 +4674,8 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + loadjs@4.3.0: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -4911,6 +4938,14 @@ snapshots: dependencies: find-up: 5.0.0 + plyr@3.7.8: + dependencies: + core-js: 3.37.0 + custom-event-polyfill: 1.0.7 + loadjs: 4.3.0 + rangetouch: 2.0.1 + url-polyfill: 1.1.12 + possible-typed-array-names@1.0.0: {} postcss@8.4.36: @@ -4971,6 +5006,8 @@ snapshots: randombytes: 2.1.0 safe-buffer: 5.2.1 + rangetouch@2.0.1: {} + react-dom@18.2.0(react@18.2.0): dependencies: loose-envify: 1.4.0 @@ -5356,6 +5393,8 @@ snapshots: dependencies: punycode: 2.3.1 + url-polyfill@1.1.12: {} + url@0.11.3: dependencies: punycode: 1.4.1 From 1e71cfef81fe931e9cbacc128f97d27ff3c4818f Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Thu, 18 Apr 2024 13:17:23 +0300 Subject: [PATCH 04/55] plyr instance --- .../src/components/players/HlsjsPlyr.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/p2p-media-loader-demo/src/components/players/HlsjsPlyr.tsx b/packages/p2p-media-loader-demo/src/components/players/HlsjsPlyr.tsx index 583c703b..4cdc7385 100644 --- a/packages/p2p-media-loader-demo/src/components/players/HlsjsPlyr.tsx +++ b/packages/p2p-media-loader-demo/src/components/players/HlsjsPlyr.tsx @@ -67,12 +67,10 @@ export const HlsjsPlyr = ({ }, }; - if (!playerRef.current) { - playerRef.current = new Plyr(videoRef.current, { - quality, - autoplay: true, - }); - } + playerRef.current = new Plyr(videoRef.current, { + quality, + autoplay: true, + }); }); hls.attachMedia(videoRef.current); From 7ed3c224bcdc84c69bd1d756ec885a7f1157283f Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Thu, 18 Apr 2024 16:07:05 +0300 Subject: [PATCH 05/55] openPlayer --- packages/p2p-media-loader-demo/package.json | 1 + .../src/components/P2PVideoDemo.tsx | 16 + .../components/players/HlsjsOpenPlayer.tsx | 86 ++ .../src/components/players/openPlayer.css | 931 ++++++++++++++++++ .../p2p-media-loader-demo/src/constants.ts | 1 + pnpm-lock.yaml | 105 ++ 6 files changed, 1140 insertions(+) create mode 100644 packages/p2p-media-loader-demo/src/components/players/HlsjsOpenPlayer.tsx create mode 100644 packages/p2p-media-loader-demo/src/components/players/openPlayer.css diff --git a/packages/p2p-media-loader-demo/package.json b/packages/p2p-media-loader-demo/package.json index f4993cde..ff376979 100644 --- a/packages/p2p-media-loader-demo/package.json +++ b/packages/p2p-media-loader-demo/package.json @@ -49,6 +49,7 @@ "d3": "^7.9.0", "dplayer": "^1.27.1", "hls.js": "^1.5.7", + "openplayerjs": "^2.14.3", "p2p-media-loader-core": "workspace:*", "p2p-media-loader-hlsjs": "workspace:*", "plyr": "^3.7.8" diff --git a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx index 567eac14..d7a40909 100644 --- a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx +++ b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx @@ -13,6 +13,7 @@ import { HlsjsDPlayer } from "./players/HlsjsDPLayer"; import { HlsjsClapprPlayer } from "./players/HlsjsClapprPlayer"; import { HlsjsVime } from "./players/HlsjsVime"; import { HlsjsPlyr } from "./players/HlsjsPlyr"; +import { HlsjsOpenPlayer } from "./players/HlsjsOpenPlayer"; declare global { interface Window { @@ -82,6 +83,18 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => { const renderPlayer = () => { switch (queryParams.player) { + case "hlsjs-openplayer": + return ( + + ); + case "hlsjs-plyr": return ( { onChunkUploaded={onChunkUploaded} /> ); + case "hlsjs-dplayer": return ( { onChunkUploaded={onChunkUploaded} /> ); + case "hlsjs": return ( { onChunkUploaded={onChunkUploaded} /> ); + default: return null; } diff --git a/packages/p2p-media-loader-demo/src/components/players/HlsjsOpenPlayer.tsx b/packages/p2p-media-loader-demo/src/components/players/HlsjsOpenPlayer.tsx new file mode 100644 index 00000000..6da183ab --- /dev/null +++ b/packages/p2p-media-loader-demo/src/components/players/HlsjsOpenPlayer.tsx @@ -0,0 +1,86 @@ +import "./openPlayer.css"; +import { useEffect, useRef } from "react"; +import OpenPlayerJS from "openplayerjs"; +import { HlsJsP2PEngine } from "p2p-media-loader-hlsjs"; +import Hls from "hls.js"; + +type HlsjsOpenPlayer = { + streamUrl: string; + announceTrackers: string[]; + onPeerConnect?: (peerId: string) => void; + onPeerDisconnect?: (peerId: string) => void; + onChunkDownloaded?: (bytesLength: number, downloadSource: string) => void; + onChunkUploaded?: (bytesLength: number) => void; +}; +const HlsWithP2P = HlsJsP2PEngine.injectMixin(Hls); + +export const HlsjsOpenPlayer = ({ + streamUrl, + announceTrackers, + onPeerConnect, + onPeerDisconnect, + onChunkDownloaded, + onChunkUploaded, +}: HlsjsOpenPlayer) => { + const videoRef = useRef(null); + const playerRef = useRef(null); + + useEffect(() => { + if (!videoRef.current) return; + + const initPlayer = async () => { + if (!videoRef.current || playerRef.current) return; + + playerRef.current = new OpenPlayerJS(videoRef.current, { + controls: { + layers: { + left: ["play", "time", "volume"], + right: ["settings", "fullscreen", "levels"], + middle: ["progress"], + }, + }, + }); + + await playerRef.current.init(); + }; + + const hls = new HlsWithP2P({ + p2p: { + core: { + announceTrackers, + }, + }, + }); + + if (onPeerConnect) { + hls.p2pEngine.addEventListener("onPeerConnect", onPeerConnect); + } + if (onPeerDisconnect) { + hls.p2pEngine.addEventListener("onPeerClose", onPeerDisconnect); + } + if (onChunkDownloaded) { + hls.p2pEngine.addEventListener("onChunkDownloaded", onChunkDownloaded); + } + if (onChunkUploaded) { + hls.p2pEngine.addEventListener("onChunkUploaded", onChunkUploaded); + } + + hls.attachMedia(videoRef.current); + hls.loadSource(streamUrl); + + void initPlayer(); + + return () => hls.destroy(); + }, [ + announceTrackers, + onChunkDownloaded, + onChunkUploaded, + onPeerConnect, + onPeerDisconnect, + streamUrl, + ]); + + return ( + + ); +}; diff --git a/packages/p2p-media-loader-demo/src/components/players/openPlayer.css b/packages/p2p-media-loader-demo/src/components/players/openPlayer.css new file mode 100644 index 00000000..605e459b --- /dev/null +++ b/packages/p2p-media-loader-demo/src/components/players/openPlayer.css @@ -0,0 +1,931 @@ +@keyframes progress { + 0% { + background-position: 0 0; + } + to { + background-position: -75px 0; + } +} +.op-player { + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; + background: #000; + font-family: sans-serif; + line-height: 1.15; + min-height: 30px; + position: relative; +} +.op-player__video { + overflow: hidden; +} +.op-player, +.op-player *, +.op-player :after, +.op-player :before { + box-sizing: border-box; +} +.op-player__media { + display: inline-block; + height: auto; + object-fit: contain; + position: relative; + width: 100% !important; +} +.op-player [aria-hidden="true"] { + display: none; +} +.op-player__audio { + background: #000; +} +.op-player .media-controls.mac.fullscreen > .controls-bar { + display: none; +} +.op-player__loader { + animation: spin 1s linear infinite; + border: 5px solid #fff; + border-radius: 50%; + border-top-color: red; +} +@keyframes spin { + 0% { + transform: rotate(0deg); + } + to { + transform: rotate(359deg); + } +} +.op-controls { + background: rgba(0, 0, 0, 0.2); + border-bottom-left-radius: inherit; + border-bottom-right-radius: inherit; + bottom: 0; + color: #fff; + display: flex; + font-size: 0.85em; + padding: 0 4px; + pointer-events: all; + position: absolute; + transition: bottom 0.3s ease; + width: 100%; + z-index: 3; +} +.op-controls.op-controls__stacked { + flex-direction: column; +} +.op-controls--hidden .op-controls { + bottom: -36px; + pointer-events: none; +} +.op-player__video .op-controls { + margin-top: 5px; + padding-top: 11px; +} +.op-controls * { + flex-grow: 0; + pointer-events: all; +} +.op-controls button, +.op-player__play, +.op-settings__back { + -webkit-appearance: button; + appearance: button; + background: transparent; + border: none; + cursor: pointer; + font-family: inherit; + font-size: 100%; + line-height: 1.15; + margin: 0; + overflow: visible; + position: relative; + text-transform: none; +} +.op-controls button { + padding: 2px 4px 3px; + z-index: 4; +} +.op-controls button > span { + color: #fff; +} +.op-controls .op-controls__container { + position: relative; +} +.op-player__loader { + height: 60px; + margin-left: -30px; + margin-top: -30px; + top: calc(50% - 20px); + width: 60px; +} +.op-player__loader, +.op-player__play { + display: block; + left: 50%; + position: absolute; + z-index: 2; +} +.op-player__play { + background: transparent; + border: 0; + border-color: transparent transparent transparent #fff; + border-style: solid; + border-width: 26px 0 26px 46px; + cursor: pointer; + height: 52px; + margin-left: -18px; + margin-top: -23px; + padding: 0; + top: calc(50% - 23px); + transition: all 0.1s ease; + width: 0; + will-change: border-width; +} +.op-player__play > span { + clip: rect(0, 0, 0, 0); + border: 0; + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + padding: 0; + position: absolute; + white-space: nowrap; + width: 1px; +} +.op-player__play--paused { + border-style: double; + border-width: 0 0 0 46px; +} +.op-player__play:hover { + border-color: transparent transparent transparent red; +} +.op-controls--hidden .op-player__loader, +.op-controls--hidden .op-player__play { + top: 50%; +} +.op-controls--hidden .op-player__play { + margin-top: -26px; +} +.op-controls button::-moz-focus-inner, +.op-player__play::-moz-focus-inner, +.op-settings__back { + border-style: none; + padding: 0; +} +.op-controls button:-moz-focusing, +.op-player__play:-moz-focusing, +.op-settings__back { + outline: 1px dotted ButtonText; +} +.op-controls button:before { + color: #fff; + display: inline-block; + height: 15px; + margin-left: 0.2em; + margin-right: 0.2em; + text-align: center; + width: 15px; +} +.op-controls-layer__bottom, +.op-controls-layer__center, +.op-controls-layer__top { + display: flex; +} +.op-controls .op-control__left { + justify-self: flex-start; +} +.op-controls .op-control__middle { + justify-self: center; +} +.op-controls .op-control__right { + justify-self: flex-end; + margin-left: auto; +} +.op-controls .op-control__right ~ .op-control__right { + margin-left: 0; +} +.op-controls button:hover { + opacity: 0.5; +} +.op-controls .op-control--no-hover:hover { + opacity: 1; +} +.op-controls button, +.op-controls input[type="range"] { + touch-action: manipulation; +} +.op-controls .op-controls-time { + margin: 4px 3px; +} +.op-controls__playpause:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMS4xIDE2LjJjLjcuMyAxIDEgLjcgMS43LS4xLjMtLjQuNi0uNy43TDUgMzQuN2MtMS4xLjctMiAuMi0yLTEuMVYxLjRDMyAuMSA0LS40IDUgLjNsMjYuMSAxNS45eiIvPjwvc3ZnPg==); +} +.op-controls__playpause--pause:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik00LjcgMGg0LjhjMS4yIDAgMi4yIDEgMi4yIDIuMnYzMC42YzAgMS4yLTEgMi4yLTIuMiAyLjJINC43Yy0xLjIgMC0yLjItMS0yLjItMi4yVjIuMkMyLjUgMSAzLjUgMCA0LjcgMHpNMjYuMiAwSDMxYzEuMiAwIDIuMiAxIDIuMiAyLjJ2MzAuNmMwIDEuMi0xIDIuMi0yLjIgMi4yaC00LjhDMjUgMzUgMjQgMzQgMjQgMzIuOFYyLjJDMjQgMSAyNSAwIDI2LjIgMHoiLz48L3N2Zz4=); +} +.op-controls__playpause--replay:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0yNi42IDkuNGM0LjIgNS4zIDMuMyAxMi45LTIgMTcuMXMtMTIuOSAzLjMtMTcuMS0yQzMuOCAxOS45IDQgMTMuMyA4IDguOUw0LjYgNS40Yy02LjQgNi45LTYgMTcuNi45IDI0czE3LjYgNiAyNC0uOWM1LjktNi4zIDYuMS0xNiAuNS0yMi42bC0zLjQgMy41eiIvPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0yMC40IDIuOGMtLjItLjguMy0xLjYgMS4xLTEuOC4yLS4xLjUtLjEuNyAwTDM0IDIuNmMxLjIuMiAxLjQgMSAuNiAxLjhMMjMuOSAxNS4xYy0uOC44LTEuNi42LTEuOC0uNkwyMC40IDIuOHoiLz48L3N2Zz4=); +} +.op-controls__fullscreen:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wIDBoMzV2MzVIMHoiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGRiIgZD0iTTEwLjIgMjAuNEg3LjN2Ny4zaDcuM3YtMi45aC00LjR2LTQuNHptLTIuOS01LjhoMi45di00LjRoNC40VjcuM0g3LjN2Ny4zem0xNy41IDEwLjJoLTQuNHYyLjloNy4zdi03LjNoLTIuOXY0LjR6TTIwLjQgNy4zdjIuOWg0LjR2NC40aDIuOVY3LjNoLTcuM3oiLz48L3N2Zz4=); + width: 20px !important; +} +.op-controls__fullscreen--out:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wIDBoMzV2MzVIMHoiLz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI0ZGRiIgZD0iTTcuMyAyMy4zaDQuNHY0LjRoMi45di03LjNINy4zdjIuOXptNC40LTExLjZINy4zdjIuOWg3LjNWNy4zaC0yLjl2NC40em04LjcgMTZoMi45di00LjNoNC40di0yLjloLTcuM3Y3LjJ6bTIuOS0xNlY3LjNoLTIuOXY3LjNoNy4zdi0yLjloLTQuNHoiLz48L3N2Zz4=); + width: 20px !important; +} +.op-controls__mute:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0yNy44IDI4LjdjLS42IDAtMS4yLS4zLTEuNS0uOS0uNS0uOC0uMi0xLjkuNi0yLjQgNC40LTIuNiA1LjktOC4yIDMuNC0xMi42LS44LTEuNC0yLTIuNi0zLjQtMy40LS45LS4zLTEuMy0xLjQtLjktMi4zczEuNC0xLjMgMi4zLS44Yy4xIDAgLjIuMS4zLjIgNi4xIDMuNiA4LjEgMTEuNCA0LjUgMTcuNS0xLjEgMS45LTIuNyAzLjQtNC41IDQuNS0uMi4yLS41LjItLjguMnoiLz48cGF0aCBmaWxsPSIjRkZGIiBkPSJNMjQuNSAyMy4xYy0uNiAwLTEuMi0uMy0xLjUtLjktLjUtLjgtLjItMS45LjYtMi40IDEuMy0uNyAxLjctMi4zIDEtMy42LS4yLS40LS42LS44LTEtMS0uOC0uNi0xLTEuNy0uNC0yLjQuNS0uNyAxLjQtLjkgMi4yLS42IDIuOSAxLjcgMy45IDUuNCAyLjMgOC4zLS41LjktMS4zIDEuNy0yLjMgMi4zLS4zLjItLjYuMy0uOS4zek0xNy44IDQuMWwtOC4xIDYuNC0uMi4ySDFjLS42IDAtMSAuNC0xIDF2MTEuNmMwIC42LjQgMSAxIDFoOC41bC4xLjIgOC4xIDYuNWMuNC4zIDEuMS4zIDEuNC0uMi4xLS4yLjItLjQuMi0uNlY0LjljMC0uNi0uNS0xLTEtMS0uMi4xLS40LjEtLjUuMnoiLz48L3N2Zz4=); + width: 18px !important; +} +.op-controls__mute--half:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMC4xIDI0LjNjLS44IDAtMS41LS40LTEuOS0xLjEtLjYtMS0uMi0yLjMuOC0zIDEuNi0uOSAyLjEtMi44IDEuMy00LjQtLjMtLjUtLjctMS0xLjMtMS4zLTEtLjYtMS4zLTItLjctMyAuNi0xIDEuOS0xLjMgMi45LS43IDMuNiAyLjEgNC45IDYuNyAyLjggMTAuMy0uNyAxLjItMS42IDIuMS0yLjggMi44LS4zLjMtLjcuNC0xLjEuNHpNMjEuOSAxIDEyIDguOWwtLjIuMUgxLjJDLjUgOSAwIDkuNiAwIDEwLjN2MTQuM2MwIC43LjUgMS4yIDEuMiAxLjJoMTAuNWwuMi4yIDkuOSA3LjljLjUuNCAxLjMuNCAxLjctLjIuMi0uMi4zLS41LjMtLjhWMmMuMS0uNi0uNC0xLjItMS0xLjMtLjMgMC0uNy4xLS45LjN6Ii8+PC9zdmc+); + width: 18px !important; +} +.op-controls__mute--muted:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0yOCAuMiAxNy42IDguNWwtLjIuMmgtMTFjLS43LS4xLTEuMy40LTEuNCAxLjF2MTVjMCAuNy42IDEuMyAxLjMgMS4zaDExbC4yLjIgMTAuNCA4LjNjLjYuNCAxLjQuNCAxLjgtLjIuMi0uMi4zLS41LjMtLjhWMS4yYzAtLjctLjUtMS4yLTEuMi0xLjItLjMgMC0uNi4xLS44LjJ6Ii8+PC9zdmc+); + width: 18px !important; +} +.op-controls__captions:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGIiBkPSJNMCA0LjR2MjYuMmgzNVY0LjRIMHptMzAuNCAyMWMtLjIuMy0uNi41LS45LjctMS4xLjgtNi4xIDEuMS0xMS45IDEuMXMtMTEtLjMtMTIuMS0xLjFjLS4zLS4yLS43LS40LS45LS43LTEuMS0xLjQtMS4yLTMuNC0xLjMtOHMuMi02LjYgMS4zLThjLjMtLjMuNi0uNS45LS43IDEtLjggNi4zLTEuMSAxMi4xLTEuMXMxMC44LjMgMTEuOSAxLjFjLjMuMi42LjQuOS43IDEuMSAxLjQgMS4zIDMuNCAxLjMgOHMtLjIgNi42LTEuMyA4eiIvPjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsPSIjRkZGIiBkPSJNMTYuOSAxNi4yYy0uMy0zLjYtMi4yLTUuNy01LjYtNS43LTMuMSAwLTUuNiAyLjgtNS42IDcuM3MyLjIgNy40IDUuOSA3LjRjMyAwIDUtMi4yIDUuMy01LjhoLTMuNWMtLjEgMS4zLS43IDIuNC0xLjkgMi40LTEuOSAwLTIuMi0xLjgtMi4yLTMuOCAwLTIuNy44LTQuMSAyLjEtNC4xIDEuMSAwIDEuOS44IDIgMi4zaDMuNXpNMjkgMTYuMmMtLjMtMy42LTIuMi01LjctNS42LTUuNy0zLjEgMC01LjYgMi44LTUuNiA3LjNzMi4yIDcuNCA1LjkgNy40YzMgMCA1LTIuMiA1LjMtNS44aC0zLjVjLS4xIDEuMy0uNyAyLjQtMS45IDIuNC0xLjkgMC0yLjItMS44LTIuMi0zLjggMC0yLjcuOC00LjEgMi4xLTQuMXMxLjkuOCAyIDIuM0gyOXoiLz48L3N2Zz4=); + width: 20px !important; +} +.op-controls__captions.op-controls__captions--on:before { + filter: invert(73%) sepia(71%) saturate(6868%) hue-rotate(356deg) + brightness(101%) contrast(126%); +} +.op-controls__settings:before { + content: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzNSAzNSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgMzUgMzUiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMC41IDE5LjJjLjEtLjYuMS0xLjIuMS0xLjcgMC0uNi0uMS0xLjItLjEtMS43bDMuNy0yLjljLjMtLjMuNC0uOC4yLTEuMWwtMy41LTYuMWMtLjItLjQtLjctLjUtMS4xLS40TDI1LjQgN2MtLjktLjctMS45LTEuMy0yLjktMS43TDIxLjguN2MwLS40LS4zLS43LS44LS43aC03Yy0uNCAwLS44LjMtLjguN2wtLjcgNC42Yy0xLjEuNC0yLjEgMS0zIDEuN0w1LjIgNS4zYy0uNC0uMi0uOSAwLTEuMS40TC42IDExLjhjLS4yLjQtLjEuOS4yIDEuMWwzLjcgMi45Yy0uMS42LS4xIDEuMi0uMSAxLjcgMCAuNi4xIDEuMi4xIDEuN0wuOCAyMi4xYy0uMy4zLS40LjgtLjIgMS4xbDMuNSA2LjFjLjIuNC43LjUgMS4xLjRMOS42IDI4Yy45LjcgMS45IDEuMyAyLjkgMS43bC43IDQuNmMuMS40LjQuNy45LjdoN2MuNCAwIC44LS4zLjgtLjdsLjctNC42YzEuMS0uNCAyLTEgMi45LTEuN2w0LjQgMS43Yy40LjIuOSAwIDEuMS0uNGwzLjUtNi4xYy4yLS40LjEtLjktLjItMS4xbC0zLjgtMi45em0tMTMgNC40Yy0zLjQgMC02LjEtMi43LTYuMS02LjEgMC0zLjQgMi43LTYuMSA2LjEtNi4xIDMuNCAwIDYuMSAyLjcgNi4xIDYuMSAwIDMuNC0yLjggNi4xLTYuMSA2LjF6Ii8+PC9zdmc+); +} +.op-settings { + background: rgba(28, 28, 28, 0.9); + bottom: 48px; + color: #fff; + font-size: 0.85em; + overflow: hidden; + position: absolute; + right: 5px; + text-shadow: 0 0 2px rgba(0, 0, 0, 0.5); + transition: right 0.2s ease; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; + will-change: width, height; + z-index: 4; +} +.op-player__audio .op-settings { + bottom: 32px; + right: 0; +} +.op-settings--sliding { + right: -999px; +} +.op-settings__menu { + margin: 0; + overflow-x: hidden; + overflow-y: auto; + padding: 0; +} +.op-settings__menu-item, +.op-settings__submenu-item { + display: table-row; + outline: none; + padding: 0; +} +.op-settings__menu-label, +.op-settings__submenu-label { + display: table-cell; + padding: 5px 15px; + vertical-align: middle; +} +.op-settings__menu-label > img, +.op-settings__menu-label > svg, +.op-settings__submenu-label > img, +.op-settings__submenu-label > svg { + max-height: 20px; +} +.op-settings__submenu-item, +.op-settings__submenu-label { + display: block; +} +.op-settings__submenu-item { + cursor: pointer; +} +.op-settings__submenu-item[aria-checked="true"] .op-settings__submenu-label { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZD0iTTkgMTYuMiA0LjggMTJsLTEuNCAxLjRMOSAxOSAyMSA3bC0xLjQtMS40TDkgMTYuMnoiIGZpbGw9IiNmZmYiLz48L3N2Zz4="); + background-position: left 4px center; + background-repeat: no-repeat; + background-size: 18px; + padding: 8px 15px 8px 25px; +} +.op-settings__menu-content { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PHBhdGggZD0ibTEyLjU5IDIwLjM0IDQuNTgtNC41OS00LjU4LTQuNTlMMTQgOS43NWw2IDYtNiA2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg=="); + background-position: right 0 center; + background-repeat: no-repeat; + background-size: 32px 32px; + cursor: pointer; + display: table-cell; + padding: 0 38px 0 15px; + vertical-align: middle; +} +.op-settings__header { + padding: 5px; +} +.op-settings__back { + background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PHBhdGggZD0ibTE5LjQxIDIwLjA5LTQuNTgtNC41OSA0LjU4LTQuNTlMMTggOS41bC02IDYgNiA2eiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg=="); + background-position: left 0 center; + background-repeat: no-repeat; + background-size: 20px 32px; + color: inherit; + height: 100%; + padding: 0 10px 0 20px; +} +.op-controls input[type="range"], +.op-controls progress { + -webkit-appearance: none; + appearance: none; + border: 0; + height: 5px; + left: 0; + margin: 0; + position: absolute; + top: 0; + transition: none; + width: 100%; +} +.op-controls input[type="range"] { + -webkit-tap-highlight-color: transparent; + background: transparent; + height: 0; + padding: 2.5px 0; + z-index: 3; +} +.op-controls input[type="range"]:focus, +.op-controls progress { + outline: none; +} +.op-controls input[type="range"]::-moz-focus-outer { + border: 0; +} +.op-controls input[type="range"]::-webkit-slider-runnable-track { + background: 0 0; + border: 0; + cursor: pointer; + height: 8px; + -webkit-user-select: none; + user-select: none; +} +.op-controls input[type="range"]::-moz-range-track { + background: 0 0; + border: 0; + cursor: pointer; + height: 8px; + user-select: none; +} +.op-controls input[type="range"]::-ms-track { + background: 0 0; + border: 0; + cursor: pointer; + height: 8px; + -ms-user-select: none; + user-select: none; +} +.op-controls input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + background: #fff; + border: 2px solid transparent; + border-radius: 100%; + box-sizing: border-box; + height: 12px; + margin-top: -2px; + position: relative; + width: 12px; +} +.op-controls input[type="range"]::-moz-range-thumb { + appearance: none; + background: #fff; + border: 2px solid transparent; + border-radius: 100%; + box-sizing: border-box; + height: 12px; + margin-top: -2px; + position: relative; + width: 12px; +} +.op-controls input[type="range"]::-ms-thumb { + appearance: none; + background: #fff; + border: 2px solid transparent; + border-radius: 100%; + box-sizing: border-box; + height: 12px; + margin-top: -2px; + position: relative; + width: 12px; +} +.op-controls input[type="range"]::-ms-tooltip { + display: none; +} +.op-controls input[type="range"]::-ms-fill-lower, +.op-controls input[type="range"]::-ms-fill-upper { + background: transparent; +} +.op-controls input[type="range"]::-ms-ticks-after, +.op-controls input[type="range"]::-ms-ticks-before { + display: none !important; +} +.op-controls .op-controls__progress--seek.loading { + animation: progress 2s linear infinite; + background: linear-gradient( + -45deg, + hsla(0, 0%, 100%, 0.3) 25%, + transparent 0, + transparent 50%, + hsla(0, 0%, 100%, 0.3) 0, + hsla(0, 0%, 100%, 0.3) 75%, + transparent 0, + transparent + ); + background-repeat: repeat-x; + background-size: 25px 25px; +} +.op-controls .op-controls__progress--seek.error { + background: linear-gradient( + -45deg, + red 25%, + transparent 0, + transparent 50%, + red 0, + red 75%, + transparent 0, + transparent + ); + background-repeat: repeat-x; + background-size: 25px 25px; +} +.op-controls--hidden + .op-controls + .op-controls__progress--seek::-webkit-slider-thumb { + background: transparent; +} +.op-controls--hidden + .op-controls + .op-controls__progress--seek::-moz-range-thumb { + background: transparent; +} +.op-controls--hidden .op-controls .op-controls__progress--seek::-ms-thumb { + background: transparent; +} +.op-player__media[op-live__enabled]:not([op-dvr__enabled]) + + .op-controls + .op-controls__progress--seek { + display: none; +} +.op-player__media[op-live__enabled]:not([op-dvr__enabled]) + + .op-controls + .op-controls__progress, +.op-player__media[op-live__enabled]:not([op-dvr__enabled]) + + .op-controls + .op-controls__progress--buffer, +.op-player__media[op-live__enabled]:not([op-dvr__enabled]) + + .op-controls + .op-controls__progress--played { + background-color: #eee; + pointer-events: none; +} +.op-controls progress { + display: inline-block; + vertical-align: baseline; +} +.op-controls progress::-webkit-progress-bar { + background: 0 0; +} +.op-controls progress::-moz-progress-bar { + background: 0 0; +} +.op-controls .op-controls__progress { + flex-grow: 2; +} +.op-controls .op-controls__progress, +.op-controls .op-controls__progress:hover, +.op-controls .op-controls__volume, +.op-controls .op-controls__volume:hover { + cursor: pointer; +} +.op-controls__progress, +.op-controls__volume { + display: inline-block; + height: 5px; + margin-left: 10px; + margin-top: 9px; + pointer-events: all; + position: relative; +} +.op-player__video .op-controls__progress { + bottom: 34px; + left: 8px; + margin-left: -8px; + position: absolute; + width: 100%; +} +.op-player__video .op-controls.op-controls__stacked .op-controls__progress { + bottom: 0; + position: relative; +} +.op-controls progress::-webkit-progress-value { + background: currentColor; +} +.op-controls progress::-moz-progress-bar { + background: currentColor; +} +.op-controls__progress--buffer::-webkit-progress-value { + -webkit-transition: width 0.2s ease; + transition: width 0.2s ease; +} +.op-controls__progress--played::-webkit-progress-value, +.op-controls__volume--display::-webkit-progress-value { + max-width: 99%; + -webkit-transition: none; + transition: none; +} +.op-player__video .op-controls__progress--played::-webkit-progress-value { + max-width: 100%; +} +.op-controls__progress--buffer::-moz-progress-bar { + -moz-transition: width 0.2s ease; + transition: width 0.2s ease; +} +.op-controls__progress--played::-moz-progress-bar, +.op-controls__volume--display::-moz-progress-bar { + max-width: 99%; + -moz-transition: none; + transition: none; +} +.op-controls .op-controls__progress--played, +.op-controls .op-controls__volume--display { + background: 0 0; + color: red; + transition: all 0.2s ease; + z-index: 2; +} +.op-controls .op-controls__volume--display { + background: hsla(0, 0%, 100%, 0.35); +} +.op-controls .op-controls__progress--buffer { + background: hsla(0, 0%, 100%, 0.3); + color: hsla(0, 0%, 100%, 0.25); +} +.op-ads--active .op-controls .op-controls__progress--seek { + pointer-events: none; +} +.op-ads--active .op-controls .op-controls__progress--played { + color: #fecb2f; +} +.op-ads--active .op-controls .op-controls__progress--buffer { + color: transparent; +} +.op-ads--active + .op-controls + .op-controls__progress--seek::-webkit-slider-thumb { + display: none; +} +.op-ads--active .op-controls .op-controls__progress--seek::-moz-range-thumb { + display: none; +} +.op-ads--active .op-controls .op-controls__progress--seek::-ms-thumb { + display: none; +} +.op-ads--active + .op-controls + .op-controls__progress--seek::-webkit-slider-runnable-track { + cursor: default; +} +.op-ads--active .op-controls .op-controls__progress--seek::-moz-range-track { + cursor: default; +} +.op-ads--active .op-controls .op-controls__progress--seek::-ms-track { + cursor: default; +} +.op-ads--active .op-controls .op-control__hide-in-ad { + cursor: default; + display: none; + pointer-events: none; +} +.op-status { + color: #fff; + font-weight: 400; + left: 0; + padding: 20px 0; + position: absolute; + text-align: center; + top: 30px; + transform: translateY(-40px); + transition: all 0.3s ease; + width: 100%; + z-index: 4; +} +.op-status > span { + background: rgba(0, 0, 0, 0.7); + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + line-height: 150%; + padding: 3px 10px; +} +.op-player__audio .op-status { + top: 23px; +} +.op-controls__tooltip { + background: #eee; + border: 1px solid #000; + bottom: 100%; + color: #000; + display: none; + left: 0; + margin-bottom: 10px; + padding: 1px 4px; + position: absolute; + text-align: center; + transform: translateX(0); +} +.op-player__video .op-controls__tooltip { + margin-bottom: 10px; +} +.op-controls__tooltip:after, +.op-controls__tooltip:before { + content: ""; + height: 0; + left: 0; + margin: 0 auto; + position: absolute; + right: 0; + top: 100%; + width: 0; +} +.op-controls__tooltip:before { + border-left: 8px solid transparent; + border-right: 8px solid transparent; + border-top: 8px solid #000; +} +.op-controls__tooltip:after { + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-top: 7px solid #eee; +} +.op-controls__tooltip--visible { + display: block; +} +.op-controls__volume { + margin-left: 0; + width: 70px; +} +.op-controls .op-controls__mute:before { + text-align: left; +} +.op-player__video .op-controls__volume { + margin-top: 10px; +} +.op-player__unmute { + background: rgba(0, 0, 0, 0.7); + color: #fff; + cursor: pointer; + left: 0; + padding: 5px; + position: absolute; + top: 0; + z-index: 3; +} +.op-player[data-fullscreen="true"] .op-controls { + z-index: 2147483648; +} +.op-player[data-fullscreen="true"].op-controls--hidden { + cursor: none; +} +.op-player[data-fullscreen="true"].op-controls--hidden .op-controls { + bottom: -40px; +} +.op-player video::-webkit-media-controls, +.op-player video::-webkit-media-text-track-container { + display: none !important; +} +.op-captions { + bottom: 0; + color: #fff; + display: none; + font-weight: 400; + left: 0; + padding: 20px 0; + position: absolute; + text-align: center; + transform: translateY(-40px); + transition: transform 0.3s ease; + width: 100%; + z-index: 1; +} +.op-controls--hidden .op-captions { + bottom: -32px; +} +.op-captions--on { + display: block; +} +.op-captions > span { + background: rgba(0, 0, 0, 0.7); + -webkit-box-decoration-break: clone; + box-decoration-break: clone; + display: block; + line-height: 150%; + margin: 0 auto 15px; + padding: 3px 10px; + width: -webkit-fit-content; + width: -moz-fit-content; + width: fit-content; +} +.op-player__audio.op-captions--detected { + background: transparent; + min-height: 95px; +} +.op-player__audio.op-captions--detected .op-captions { + bottom: -10px; + padding: 0; +} +.op-player__audio.op-captions--detected .op-captions > span { + background: transparent; + color: #000; +} +.op-player__audio.op-captions--detected .op-controls { + background: #000; + bottom: auto; +} +.op-player__audio.op-captions--detected .op-settings { + bottom: auto; + top: 35px; +} +.op-controls .op-controls__captions--on:before { + color: red; +} +.op-captions__menu { + bottom: 36px; + left: 50%; + min-width: 73px; + overflow: visible; + transform: translate(-50%); + z-index: 10; +} +.op-captions__menu:after { + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-top: 10px solid rgba(28, 28, 28, 0.9); + content: ""; + height: 0; + left: 0; + margin: 0 auto; + position: absolute; + right: 0; + top: 100%; + width: 0; +} +::cue { + color: #ccc; +} +video:-webkit-media-text-track-display { + top: -15%; +} +.op-levels__menu { + bottom: 36px; + left: 50%; + min-width: 73px; + overflow: visible; + transform: translate(-50%); + z-index: 10; +} +.op-levels__menu:after { + border-left: 10px solid transparent; + border-right: 10px solid transparent; + border-top: 10px solid rgba(28, 28, 28, 0.9); + content: ""; + height: 0; + left: 0; + margin: 0 auto; + position: absolute; + right: 0; + top: 100%; + width: 0; +} +.op-ads { + height: 100%; + left: 0; + position: absolute; + top: 0; + width: 100%; +} +.op-ads--active { + overflow: hidden; +} +.op-ads--active .op-captions, +.op-ads--active .op-controls__captions, +.op-ads--active .op-controls__settings { + display: none; +} +.op-ads--active .op-controls__fullscreen { + float: right; +} +.op-ads--active .op-controls .op-control__right ~ .op-control__right { + margin-left: auto; +} +.op-ads--active .op-ads { + z-index: 1; +} +.op-player[data-fullscreen="true"].op-ads--active .op-ads { + z-index: 2147483645; +} +.op-ads__click-container { + background-color: #807f80; + color: #fff; + cursor: default; + display: none; + padding: 5px; + pointer-events: auto; + position: absolute; + right: 0; + text-align: center; + top: 0; + z-index: 100; +} +.op-ads__click-container--visible { + display: block; +} +.op-player[data-fullscreen="true"].op-ads--active .op-ads__click-container { + z-index: 2147483647; +} +.op-player__audio .op-ads { + display: none; +} +.op-ads__skip { + color: #fff; +} +.op-player:focus, +.op-player > .op-controls :focus, +.op-player__play:focus { + outline: 1px dotted #999; +} +.op-player.op-player__keyboard--inactive .op-player__play:focus, +.op-player.op-player__keyboard--inactive:focus, +.op-player.op-player__keyboard--inactive > .op-controls :focus { + outline: none; +} +.op-player.op-player__full { + bottom: 0; + left: 0; + overflow: hidden; + position: fixed; + right: 0; + top: 0; + z-index: -100; +} +.op-player__full .op-ads, +.op-player__full .op-player__media { + height: auto; + left: 50%; + min-height: 100%; + min-width: 100%; + position: absolute; + top: 50%; + transform: translate(-50%, -50%); + width: auto !important; +} +.op-player__fit--wrapper { + height: 100%; + position: relative; + width: 100%; +} +.op-player.op-player__fit { + background: #000; + height: 100%; + left: 0; + overflow: hidden; + position: absolute; + top: 0; + width: 100%; +} +.op-player__fit .op-ads, +.op-player__fit .op-player__media { + border: 0; + display: block; + height: 100%; + min-height: 100%; + width: 100%; +} +.op-player__ios--iphone .op-player__play { + margin-top: -5px; +} +.op-player.op-player__ios--iphone video::-webkit-media-controls, +.op-player[data-fullscreen="true"].op-player.op-player__ios--iphone + video::-webkit-media-text-track-container { + display: block !important; +} +.op-player[data-fullscreen="true"].op-player.op-player__ios--iphone + video::-webkit-media-text-track-display-backdrop { + background: rgba(0, 0, 0, 0.498) !important; +} +/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImRpc3Qvc3JjL2Nzcy9wbGF5ZXIuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLG9CQUNJLEdBQ0ksdUJBQ0osQ0FDQSxHQUNJLDJCQUNKLENBQ0osQ0FDQSxXQU1JLDZCQUFzQixDQUF0QiwwQkFBc0IsQ0FBdEIscUJBQXNCLENBTHRCLGVBQWdCLENBQ2hCLHNCQUF1QixDQUN2QixnQkFBaUIsQ0FDakIsZUFBZ0IsQ0FDaEIsaUJBRUosQ0FDQSxrQkFDSSxlQUNKLENBQ0EsNkRBSUkscUJBQ0osQ0FFQSxrQkFDSSxvQkFBcUIsQ0FDckIsV0FBWSxDQUNaLGtCQUFtQixDQUNuQixpQkFBa0IsQ0FDbEIsb0JBQ0osQ0FDQSw4QkFDSSxZQUNKLENBQ0Esa0JBQ0ksZUFDSixDQUNBLHdEQUNJLFlBQ0osQ0FDQSxtQkFDSSxpQ0FBa0MsQ0FHbEMscUJBQTBCLENBRDFCLGlCQUFrQixDQUNsQixvQkFDSixDQUNBLGdCQUNJLEdBQ0ksc0JBQ0osQ0FFQSxHQUNJLHdCQUNKLENBQ0osQ0FFQSxhQUNJLHlCQUE4QixDQUM5QixpQ0FBa0MsQ0FDbEMsa0NBQW1DLENBQ25DLFFBQVMsQ0FDVCxVQUFXLENBQ1gsWUFBYSxDQUNiLGVBQWlCLENBQ2pCLGFBQWMsQ0FDZCxrQkFBbUIsQ0FDbkIsaUJBQWtCLENBQ2xCLDBCQUE0QixDQUM1QixVQUFXLENBQ1gsU0FDSixDQUNBLGtDQUNJLHFCQUNKLENBQ0Esa0NBQ0ksWUFBYSxDQUNiLG1CQUNKLENBQ0EsK0JBQ0ksY0FBZSxDQUNmLGdCQUNKLENBQ0EsZUFDSSxXQUFZLENBQ1osa0JBQ0osQ0FDQSx3REFHSSx5QkFBa0IsQ0FBbEIsaUJBQWtCLENBQ2xCLHNCQUF1QixDQUN2QixXQUFZLENBQ1osY0FBZSxDQUNmLG1CQUFvQixDQUNwQixjQUFlLENBQ2YsZ0JBQWlCLENBQ2pCLFFBQVMsQ0FDVCxnQkFBaUIsQ0FDakIsaUJBQWtCLENBQ2xCLG1CQUNKLENBQ0Esb0JBQ0ksbUJBQW9CLENBQ3BCLFNBQ0osQ0FD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aUJBQWtCLENBQ2xCLE9BQVEsQ0FDUixpQkFBa0IsQ0FDbEIsS0FBTSxDQUNOLFdBQ0osQ0FFQSxrQ0FDSSxhQUNKLENBRUEseUVBQ0ksa0JBQ0osQ0FFQSwwQkFDSSxZQUNKLENBRUEsY0FDSSxVQUNKLENBR0EsdUVBR0ksdUJBQ0osQ0FDQSw0S0FHSSxZQUNKLENBR0EsMkJBQ0ksUUFBUyxDQUNULE1BQU8sQ0FDUCxlQUFnQixDQUNoQixjQUFlLENBQ2YsT0FBUSxDQUNSLEtBQU0sQ0FDTixZQUNKLENBQ0EsNERBRUksV0FBWSxDQUNaLFFBQVMsQ0FDVCxlQUFnQixDQUNoQixjQUFlLENBQ2YsaUJBQWtCLENBQ2xCLE9BQVEsQ0FDUiw4QkFBZ0MsQ0FDaEMsb0JBQ0osQ0FHQSx5QkFDSSxXQUFZLENBQ1osaUJBQWtCLENBQ2xCLFVBQ0osQ0FDQSwwQkFDSSxlQUFnQixDQUNoQixXQUFZLENBQ1osTUFBTyxDQUNQLGVBQWdCLENBQ2hCLGlCQUFrQixDQUNsQixLQUFNLENBQ04sVUFDSixDQUNBLDBEQUVJLFFBQVMsQ0FDVCxhQUFjLENBQ2QsV0FBWSxDQUNaLGVBQWdCLENBQ2hCLFVBQ0osQ0FHQSx5Q0FDSSxlQUNKLENBSUEsNEtBQ0ksdUJBQ0osQ0FDQSxtSEFDSSxxQ0FDSiIsImZpbGUiOiJkaXN0L29wZW5wbGF5ZXIuY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLyogPT09IEdlbmVyYWwgPT09PT09PT09PT09PT09PT09PSAqL1xuQGtleWZyYW1lcyBwcm9ncmVzcyB7XG4gICAgMCUge1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwIDA7XG4gICAgfVxuICAgIDEwMCUge1xuICAgICAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAtNzVweCAwO1xuICAgIH1cbn1cbi5vcC1wbGF5ZXIge1xuICAgIGJhY2tncm91bmQ6ICMwMDA7XG4gICAgZm9udC1mYW1pbHk6IHNhbnMtc2VyaWY7XG4gICAgbGluZS1oZWlnaHQ6IDEuMTU7XG4gICAgbWluLWhlaWdodDogMzBweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgdGV4dC1zaXplLWFkanVzdDogMTAwJTtcbn1cbi5vcC1wbGF5ZXJfX3ZpZGVvIHtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xufVxuLm9wLXBsYXllcixcbi5vcC1wbGF5ZXIgKixcbi5vcC1wbGF5ZXIgOjphZnRlcixcbi5vcC1wbGF5ZXIgOjpiZWZvcmUge1xuICAgIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG59XG5cbi5vcC1wbGF5ZXJfX21lZGlhIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgaGVpZ2h0OiBhdXRvO1xuICAgIG9iamVjdC1maXQ6IGNvbnRhaW47XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHdpZHRoOiAxMDAlICFpbXBvcnRhbnQ7XG59XG4ub3AtcGxheWVyIFthcmlhLWhpZGRlbj0ndHJ1ZSddIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLm9wLXBsYXllcl9fYXVkaW8ge1xuICAgIGJhY2tncm91bmQ6ICMwMDA7XG59XG4ub3AtcGxheWVyIC5tZWRpYS1jb250cm9scy5tYWMuZnVsbHNjcmVlbiA+IC5jb250cm9scy1iYXIge1xuICAgIGRpc3BsYXk6IG5vbmU7XG59XG4ub3AtcGxheWVyX19sb2FkZXIge1xuICAgIGFuaW1hdGlvbjogc3BpbiAxcyBpbmZpbml0ZSBsaW5lYXI7XG4gICAgYm9yZGVyOiA1cHggc29saWQgI2ZmZjtcbiAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgYm9yZGVyLXRvcDogNXB4IHNvbGlkICNmMDA7XG59XG5Aa2V5ZnJhbWVzIHNwaW4ge1xuICAgIDAlIHtcbiAgICAgICAgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7XG4gICAgfVxuXG4gICAgMTAwJSB7XG4gICAgICAgIHRyYW5zZm9ybTogcm90YXRlKDM1OWRlZyk7XG4gICAgfVxufVxuLyogPT09IENvbnRyb2xzID09PT09PT09PT09PT09PT09PT0gKi9cbi5vcC1jb250cm9scyB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjIpO1xuICAgIGJvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6IGluaGVyaXQ7XG4gICAgYm9yZGVyLWJvdHRvbS1yaWdodC1yYWRpdXM6IGluaGVyaXQ7XG4gICAgYm90dG9tOiAwO1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgZm9udC1zaXplOiAwLjg1ZW07XG4gICAgcGFkZGluZzogMCA0cHg7XG4gICAgcG9pbnRlci1ldmVudHM6IGFsbDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdHJhbnNpdGlvbjogYm90dG9tIDAuM3MgZWFzZTtcbiAgICB3aWR0aDogMTAwJTtcbiAgICB6LWluZGV4OiAzO1xufVxuLm9wLWNvbnRyb2xzLm9wLWNvbnRyb2xzX19zdGFja2VkIHtcbiAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xufVxuLm9wLWNvbnRyb2xzLS1oaWRkZW4gLm9wLWNvbnRyb2xzIHtcbiAgICBib3R0b206IC0zNnB4O1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuLm9wLXBsYXllcl9fdmlkZW8gLm9wLWNvbnRyb2xzIHtcbiAgICBtYXJnaW4tdG9wOiA1cHg7XG4gICAgcGFkZGluZy10b3A6IDExcHg7XG59XG4ub3AtY29udHJvbHMgKiB7XG4gICAgZmxleC1ncm93OiAwO1xuICAgIHBvaW50ZXItZXZlbnRzOiBhbGw7XG59XG4ub3AtcGxheWVyX19wbGF5LFxuLm9wLXNldHRpbmdzX19iYWNrLFxuLm9wLWNvbnRyb2xzIGJ1dHRvbiB7XG4gICAgYXBwZWFyYW5jZTogYnV0dG9uO1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlcjogbm9uZTtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgZm9udC1mYW1pbHk6IGluaGVyaXQ7XG4gICAgZm9udC1zaXplOiAxMDAlO1xuICAgIGxpbmUtaGVpZ2h0OiAxLjE1O1xuICAgIG1hcmdpbjogMDtcbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgdGV4dC10cmFuc2Zvcm06IG5vbmU7XG59XG4ub3AtY29udHJvbHMgYnV0dG9uIHtcbiAgICBwYWRkaW5nOiAycHggNHB4IDNweDtcbiAgICB6LWluZGV4OiA0O1xufVxuLm9wLWNvbnRyb2xzIGJ1dHRvbiA+IHNwYW4ge1xuICAgIGNvbG9yOiAjZmZmO1xufVxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fY29udGFpbmVyIHtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG4ub3AtcGxheWVyX19sb2FkZXIge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGhlaWdodDogNjBweDtcbiAgICBsZWZ0OiA1MCU7XG4gICAgbWFyZ2luLWxlZnQ6IC0zMHB4O1xuICAgIG1hcmdpbi10b3A6IC0zMHB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IGNhbGMoNTAlIC0gMjBweCk7XG4gICAgd2lkdGg6IDYwcHg7XG4gICAgei1pbmRleDogMjtcbn1cbi5vcC1wbGF5ZXJfX3BsYXkge1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlcjogMDtcbiAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50ICNmZmY7XG4gICAgYm9yZGVyLXN0eWxlOiBzb2xpZDtcbiAgICBib3JkZXItd2lkdGg6IDI2cHggMCAyNnB4IDQ2cHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGhlaWdodDogNTJweDtcbiAgICBsZWZ0OiA1MCU7XG4gICAgbWFyZ2luLWxlZnQ6IC0xOHB4O1xuICAgIG1hcmdpbi10b3A6IC0yM3B4O1xuICAgIHBhZGRpbmc6IDA7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogY2FsYyg1MCUgLSAyM3B4KTtcbiAgICB0cmFuc2l0aW9uOiAxMDBtcyBhbGwgZWFzZTtcbiAgICB3aWR0aDogMDtcbiAgICB3aWxsLWNoYW5nZTogYm9yZGVyLXdpZHRoO1xuICAgIHotaW5kZXg6IDI7XG59XG4ub3AtcGxheWVyX19wbGF5ID4gc3BhbiB7XG4gICAgYm9yZGVyOiAwO1xuICAgIGNsaXA6IHJlY3QoMCwgMCwgMCwgMCk7XG4gICAgY2xpcC1wYXRoOiBpbnNldCg1MCUpO1xuICAgIGhlaWdodDogMXB4O1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgcGFkZGluZzogMDtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgd2hpdGUtc3BhY2U6IG5vd3JhcDtcbiAgICB3aWR0aDogMXB4O1xufVxuLm9wLXBsYXllcl9fcGxheS0tcGF1c2VkIHtcbiAgICBib3JkZXItc3R5bGU6IGRvdWJsZTtcbiAgICBib3JkZXItd2lkdGg6IDAgMCAwIDQ2cHg7XG59XG4ub3AtcGxheWVyX19wbGF5OmhvdmVyIHtcbiAgICBib3JkZXItY29sb3I6IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50IHRyYW5zcGFyZW50ICNmMDA7XG59XG4ub3AtY29udHJvbHMtLWhpZGRlbiAub3AtcGxheWVyX19sb2FkZXIsXG4ub3AtY29udHJvbHMtLWhpZGRlbiAub3AtcGxheWVyX19wbGF5IHtcbiAgICB0b3A6IDUwJTtcbn1cbi5vcC1jb250cm9scy0taGlkZGVuIC5vcC1wbGF5ZXJfX3BsYXkge1xuICAgIG1hcmdpbi10b3A6IC0yNnB4O1xufVxuLm9wLXBsYXllcl9fcGxheTo6LW1vei1mb2N1cy1pbm5lcixcbi5vcC1zZXR0aW5nc19fYmFjayxcbi5vcC1jb250cm9scyBidXR0b246Oi1tb3otZm9jdXMtaW5uZXIge1xuICAgIGJvcmRlci1zdHlsZTogbm9uZTtcbiAgICBwYWRkaW5nOiAwO1xufVxuLm9wLXBsYXllcl9fcGxheTotbW96LWZvY3VzaW5nLFxuLm9wLXNldHRpbmdzX19iYWNrLFxuLm9wLWNvbnRyb2xzIGJ1dHRvbjotbW96LWZvY3VzaW5nIHtcbiAgICBvdXRsaW5lOiAxcHggZG90dGVkIEJ1dHRvblRleHQ7XG59XG4ub3AtY29udHJvbHMgYnV0dG9uOmJlZm9yZSB7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIGhlaWdodDogMTVweDtcbiAgICBtYXJnaW4tbGVmdDogMC4yZW07XG4gICAgbWFyZ2luLXJpZ2h0OiAwLjJlbTtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgd2lkdGg6IDE1cHg7XG59XG4ub3AtY29udHJvbHMtbGF5ZXJfX3RvcCxcbi5vcC1jb250cm9scy1sYXllcl9fY2VudGVyLFxuLm9wLWNvbnRyb2xzLWxheWVyX19ib3R0b20ge1xuICAgIGRpc3BsYXk6IGZsZXg7XG59XG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xfX2xlZnQge1xuICAgIGp1c3RpZnktc2VsZjogZmxleC1zdGFydDtcbn1cbi5vcC1jb250cm9scyAub3AtY29udHJvbF9fbWlkZGxlIHtcbiAgICBqdXN0aWZ5LXNlbGY6IGNlbnRlcjtcbn1cbi5vcC1jb250cm9scyAub3AtY29udHJvbF9fcmlnaHQge1xuICAgIGp1c3RpZnktc2VsZjogZmxleC1lbmQ7XG4gICAgbWFyZ2luLWxlZnQ6IGF1dG87XG59XG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xfX3JpZ2h0IH4gLm9wLWNvbnRyb2xfX3JpZ2h0IHtcbiAgICBtYXJnaW4tbGVmdDogMDtcbn1cbi5vcC1jb250cm9scyBidXR0b246aG92ZXIge1xuICAgIG9wYWNpdHk6IDAuNTtcbn1cbi5vcC1jb250cm9scyAub3AtY29udHJvbC0tbm8taG92ZXI6aG92ZXIge1xuICAgIG9wYWNpdHk6IDE7XG59XG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXSxcbi5vcC1jb250cm9scyBidXR0b24ge1xuICAgIHRvdWNoLWFjdGlvbjogbWFuaXB1bGF0aW9uO1xufVxuXG4vKiA9PT0gVGltZSA9PT09PT09PT09PT09PT09PT09ICovXG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzLXRpbWUge1xuICAgIG1hcmdpbjogNHB4IDNweDtcbn1cblxuLyogPT09IEJ1dHRvbnMgPT09PT09PT09PT09PT09PT09PSAqL1xuLm9wLWNvbnRyb2xzX19wbGF5cGF1c2U6YmVmb3JlIHtcbiAgICBjb250ZW50OiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpZFhSbUxUZ2lQejRLUEhOMlp5QjJaWEp6YVc5dVBTSXhMakVpSUNCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUhodGJHNXpPbmhzYVc1clBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHhPVGs1TDNoc2FXNXJJaUI0UFNJd2NIZ2lJSGs5SWpCd2VDSUtDU0IyYVdWM1FtOTRQU0l3SURBZ016VWdNelVpSUhOMGVXeGxQU0psYm1GaWJHVXRZbUZqYTJkeWIzVnVaRHB1WlhjZ01DQXdJRE0xSURNMU95SWdlRzFzT25Od1lXTmxQU0p3Y21WelpYSjJaU0krQ2p4d1lYUm9JR1pwYkd3OUlpTkdSa1pHUmtZaUlHUTlJazB6TVM0eExERTJMakpqTUM0M0xEQXVNeXd4TERFc01DNDNMREV1TjJNdE1DNHhMREF1TXkwd0xqUXNNQzQyTFRBdU55d3dMamRNTlN3ek5DNDNZeTB4TGpFc01DNDNMVElzTUM0eUxUSXRNUzR4VmpFdU5HTXdMVEV1TXl3eExURXVPQ3d5TFRFdU1Rb0pURE14TGpFc01UWXVNbm9pTHo0S1BDOXpkbWMrKTtcbn1cbi5vcC1jb250cm9sc19fcGxheXBhdXNlLS1wYXVzZTpiZWZvcmUge1xuICAgIGNvbnRlbnQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NEtQSE4yWnlCMlpYSnphVzl1UFNJeExqRWlJSGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5SWdlRzFzYm5NNmVHeHBibXM5SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpFNU9Ua3ZlR3hwYm1zaUlIZzlJakJ3ZUNJZ2VUMGlNSEI0SWdvSklIWnBaWGRDYjNnOUlqQWdNQ0F6TlNBek5TSWdjM1I1YkdVOUltVnVZV0pzWlMxaVlXTnJaM0p2ZFc1a09tNWxkeUF3SURBZ016VWdNelU3SWlCNGJXdzZjM0JoWTJVOUluQnlaWE5sY25abElqNEtQSEJoZEdnZ1ptbHNiRDBpSTBaR1JrWkdSaUlnWkQwaVRUUXVOeXd3YURRdU9HTXhMaklzTUN3eUxqSXNNU3d5TGpJc01pNHlkak13TGpaak1Dd3hMakl0TVN3eUxqSXRNaTR5TERJdU1rZzBMamRqTFRFdU1pd3dMVEl1TWkweExUSXVNaTB5TGpKV01pNHlRekl1TlN3eExETXVOU3d3TERRdU55d3dlaUl2UGdvOGNHRjBhQ0JtYVd4c1BTSWpSa1pHUmtaR0lpQmtQU0pOTWpZdU1pd3dTRE14WXpFdU1pd3dMREl1TWl3eExESXVNaXd5TGpKMk16QXVObU13TERFdU1pMHhMREl1TWkweUxqSXNNaTR5YUMwMExqaERNalVzTXpVc01qUXNNelFzTWpRc016SXVPRll5TGpKRE1qUXNNU3d5TlN3d0xESTJMaklzTUhvaUx6NEtQQzl6ZG1jKyk7XG59XG4ub3AtY29udHJvbHNfX3BsYXlwYXVzZS0tcmVwbGF5OmJlZm9yZSB7XG4gICAgY29udGVudDogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaWRYUm1MVGdpUHo0S1BITjJaeUIyWlhKemFXOXVQU0l4TGpFaUlIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhnOUlqQndlQ0lnZVQwaU1IQjRJZ29KSUhacFpYZENiM2c5SWpBZ01DQXpOU0F6TlNJZ2MzUjViR1U5SW1WdVlXSnNaUzFpWVdOclozSnZkVzVrT201bGR5QXdJREFnTXpVZ016VTdJaUI0Yld3NmMzQmhZMlU5SW5CeVpYTmxjblpsSWo0S1BIQmhkR2dnWm1sc2JEMGlJMFpHUmtaR1JpSWdaRDBpVFRJMkxqWXNPUzQwWXpRdU1pdzFMak1zTXk0ekxERXlMamt0TWl3eE55NHhjeTB4TWk0NUxETXVNeTB4Tnk0eExUSkRNeTQ0TERFNUxqa3NOQ3d4TXk0ekxEZ3NPQzQ1VERRdU5pdzFMalJqTFRZdU5DdzJMamt0Tml3eE55NDJMREF1T1N3eU5Bb0pjekUzTGpZc05pd3lOQzB3TGpsak5TNDVMVFl1TXl3MkxqRXRNVFlzTUM0MUxUSXlMalpNTWpZdU5pdzVMalI2SWk4K0NqeHdZWFJvSUdacGJHdzlJaU5HUmtaR1JrWWlJR1E5SWsweU1DNDBMREl1T0dNdE1DNHlMVEF1T0N3d0xqTXRNUzQyTERFdU1TMHhMamhqTUM0eUxUQXVNU3d3TGpVdE1DNHhMREF1Tnl3d2JERXhMamdzTVM0Mll6RXVNaXd3TGpJc01TNDBMREVzTUM0MkxERXVPRXd5TXk0NUxERTFMakVLQ1dNdE1DNDRMREF1T0MweExqWXNNQzQyTFRFdU9DMHdMalpNTWpBdU5Dd3lMamg2SWk4K0Nqd3ZjM1puUGc9PSk7XG59XG4ub3AtY29udHJvbHNfX2Z1bGxzY3JlZW46YmVmb3JlIHtcbiAgICBjb250ZW50OiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpZFhSbUxUZ2lQejRLUEhOMlp5QjJaWEp6YVc5dVBTSXhMakVpSUhodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGc5SWpCd2VDSWdlVDBpTUhCNElnb0pJSFpwWlhkQ2IzZzlJakFnTUNBek5TQXpOU0lnYzNSNWJHVTlJbVZ1WVdKc1pTMWlZV05yWjNKdmRXNWtPbTVsZHlBd0lEQWdNelVnTXpVN0lpQjRiV3c2YzNCaFkyVTlJbkJ5WlhObGNuWmxJajRLUEdjK0NnazhjRzlzZVdkdmJpQm1hV3hzUFNKdWIyNWxJaUJ3YjJsdWRITTlJakFzTUNBek5Td3dJRE0xTERNMUlEQXNNelVnQ1NJdlBnb0pQSEJoZEdnZ1ptbHNiQzF5ZFd4bFBTSmxkbVZ1YjJSa0lpQmpiR2x3TFhKMWJHVTlJbVYyWlc1dlpHUWlJR1pwYkd3OUlpTkdSa1pHUmtZaUlHUTlJazB4TUM0eUxESXdMalJJTnk0emRqY3VNMmczTGpOMkxUSXVPV2d0TkM0MFZqSXdMalI2SUUwM0xqTXNNVFF1Tm1neUxqbDJMVFF1TkdnMExqUldOeTR6U0RjdU0xWXhOQzQyZWlCTk1qUXVPQ3d5TkM0NGFDMDBMalIyTWk0NWFEY3VNM1l0Tnk0ekNna0phQzB5TGpsV01qUXVPSG9nVFRJd0xqUXNOeTR6ZGpJdU9XZzBMalIyTkM0MGFESXVPVlkzTGpOSU1qQXVOSG9pTHo0S1BDOW5QZ284TDNOMlp6ND0pO1xuICAgIHdpZHRoOiAyMHB4ICFpbXBvcnRhbnQ7XG59XG4ub3AtY29udHJvbHNfX2Z1bGxzY3JlZW4tLW91dDpiZWZvcmUge1xuICAgIGNvbnRlbnQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NEtQSE4yWnlCMlpYSnphVzl1UFNJeExqRWlJSGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5SWdlRzFzYm5NNmVHeHBibXM5SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpFNU9Ua3ZlR3hwYm1zaUlIZzlJakJ3ZUNJZ2VUMGlNSEI0SWdvSklIWnBaWGRDYjNnOUlqQWdNQ0F6TlNBek5TSWdjM1I1YkdVOUltVnVZV0pzWlMxaVlXTnJaM0p2ZFc1a09tNWxkeUF3SURBZ016VWdNelU3SWlCNGJXdzZjM0JoWTJVOUluQnlaWE5sY25abElqNEtQSEJ2YkhsbmIyNGdabWxzYkQwaWJtOXVaU0lnY0c5cGJuUnpQU0l3TERBZ016VXNNQ0F6TlN3ek5TQXdMRE0xSUNJdlBnbzhjR0YwYUNCbWFXeHNMWEoxYkdVOUltVjJaVzV2WkdRaUlHTnNhWEF0Y25Wc1pUMGlaWFpsYm05a1pDSWdabWxzYkQwaUkwWkdSa1pHUmlJZ1pEMGlUVGN1TXl3eU15NHphRFF1TkhZMExqUm9NaTQ1ZGkwM0xqTklOeTR6VmpJekxqTjZJRTB4TVM0M0xERXhMamRJTnk0emRqSXVPV2czTGpOV055NHphQzB5TGpsV01URXVOM29nVFRJd0xqUXNNamN1TjJneUxqbDJMVFF1TTJnMExqUjJMVEl1T1FvSmFDMDNMak5XTWpjdU4zb2dUVEl6TGpNc01URXVOMVkzTGpOb0xUSXVPWFkzTGpOb055NHpkaTB5TGpsSU1qTXVNM29pTHo0S1BDOXpkbWMrKTtcbiAgICB3aWR0aDogMjBweCAhaW1wb3J0YW50O1xufVxuLm9wLWNvbnRyb2xzX19tdXRlOmJlZm9yZSB7XG4gICAgY29udGVudDogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaWRYUm1MVGdpUHo0S1BITjJaeUIyWlhKemFXOXVQU0l4TGpFaUlHbGtQU0pNWVhsbGNsOHhJaUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGh0Ykc1ek9uaHNhVzVyUFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eE9UazVMM2hzYVc1cklpQjRQU0l3Y0hnaUlIazlJakJ3ZUNJS0NTQjJhV1YzUW05NFBTSXdJREFnTXpVZ016VWlJSE4wZVd4bFBTSmxibUZpYkdVdFltRmphMmR5YjNWdVpEcHVaWGNnTUNBd0lETTFJRE0xT3lJZ2VHMXNPbk53WVdObFBTSndjbVZ6WlhKMlpTSStDanh3WVhSb0lHWnBiR3c5SWlOR1JrWkdSa1lpSUdROUlrMHlOeTQ0TERJNExqZGpMVEF1Tml3d0xURXVNaTB3TGpNdE1TNDFMVEF1T1dNdE1DNDFMVEF1T0Mwd0xqSXRNUzQ1TERBdU5pMHlMalJqTkM0MExUSXVOaXcxTGprdE9DNHlMRE11TkMweE1pNDJZeTB3TGpndE1TNDBMVEl0TWk0MkxUTXVOQzB6TGpRS0NVTXlOaXc1TGpFc01qVXVOaXc0TERJMkxEY3VNWE14TGpRdE1TNHpMREl1TXkwd0xqaGpNQzR4TERBc01DNHlMREF1TVN3d0xqTXNNQzR5WXpZdU1Td3pMallzT0M0eExERXhMalFzTkM0MUxERTNMalZqTFRFdU1Td3hMamt0TWk0M0xETXVOQzAwTGpVc05DNDFDZ2xETWpndU5Dd3lPQzQzTERJNExqRXNNamd1Tnl3eU55NDRMREk0TGpkNklpOCtDanh3WVhSb0lHWnBiR3c5SWlOR1JrWkdSa1lpSUdROUlrMHlOQzQxTERJekxqRmpMVEF1Tml3d0xURXVNaTB3TGpNdE1TNDFMVEF1T1dNdE1DNDFMVEF1T0Mwd0xqSXRNUzQ1TERBdU5pMHlMalJqTVM0ekxUQXVOeXd4TGpjdE1pNHpMREV0TXk0Mll5MHdMakl0TUM0MExUQXVOaTB3TGpndE1TMHhDZ2xqTFRBdU9DMHdMall0TVMweExqY3RNQzQwTFRJdU5HTXdMalV0TUM0M0xERXVOQzB3TGprc01pNHlMVEF1Tm1NeUxqa3NNUzQzTERNdU9TdzFMalFzTWk0ekxEZ3VNMk10TUM0MUxEQXVPUzB4TGpNc01TNDNMVEl1TXl3eUxqTkRNalV1TVN3eU15d3lOQzQ0TERJekxqRXNNalF1TlN3eU15NHhlaUlLQ1M4K0NqeHdZWFJvSUdacGJHdzlJaU5HUmtaR1JrWWlJR1E5SWsweE55NDRMRFF1TVd3dE9DNHhMRFl1Tkd3dE1DNHlMREF1TWtneFl5MHdMallzTUMweExEQXVOQzB4TERGMk1URXVObU13TERBdU5pd3dMalFzTVN3eExERm9PQzQxYkRBdU1Td3dMakpzT0M0eExEWXVOUW9KWXpBdU5Dd3dMak1zTVM0eExEQXVNeXd4TGpRdE1DNHlZekF1TVMwd0xqSXNNQzR5TFRBdU5Dd3dMakl0TUM0MlZqUXVPV013TFRBdU5pMHdMalV0TVMweExURkRNVGd1TVN3MExERTNMamtzTkN3eE55NDRMRFF1TVhvaUx6NEtQQzl6ZG1jKyk7XG4gICAgd2lkdGg6IDE4cHggIWltcG9ydGFudDtcbn1cbi5vcC1jb250cm9sc19fbXV0ZS0taGFsZjpiZWZvcmUge1xuICAgIGNvbnRlbnQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NEtQSE4yWnlCMlpYSnphVzl1UFNJeExqRWlJSGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5SWdlRzFzYm5NNmVHeHBibXM5SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpFNU9Ua3ZlR3hwYm1zaUlIZzlJakJ3ZUNJZ2VUMGlNSEI0SWdvSklIWnBaWGRDYjNnOUlqQWdNQ0F6TlNBek5TSWdjM1I1YkdVOUltVnVZV0pzWlMxaVlXTnJaM0p2ZFc1a09tNWxkeUF3SURBZ016VWdNelU3SWlCNGJXdzZjM0JoWTJVOUluQnlaWE5sY25abElqNEtQSEJoZEdnZ1ptbHNiRDBpSTBaR1JrWkdSaUlnWkQwaVRUTXdMakVzTWpRdU0yTXRNQzQ0TERBdE1TNDFMVEF1TkMweExqa3RNUzR4WXkwd0xqWXRNUzB3TGpJdE1pNHpMREF1T0Mwell6RXVOaTB3TGprc01pNHhMVEl1T0N3eExqTXROQzQwWXkwd0xqTXRNQzQxTFRBdU55MHhMVEV1TXkweExqTUtDV010TVMwd0xqWXRNUzR6TFRJdE1DNDNMVE5qTUM0MkxURXNNUzQ1TFRFdU15d3lMamt0TUM0M1l6TXVOaXd5TGpFc05DNDVMRFl1Tnl3eUxqZ3NNVEF1TTJNdE1DNDNMREV1TWkweExqWXNNaTR4TFRJdU9Dd3lMamhETXpBdU9Td3lOQzR5TERNd0xqVXNNalF1TXl3ek1DNHhMREkwTGpONklpOCtDanh3WVhSb0lHWnBiR3c5SWlOR1JrWkdSa1lpSUdROUlrMHlNUzQ1TERGTU1USXNPQzQ1VERFeExqZ3NPVWd4TGpKRE1DNDFMRGtzTUN3NUxqWXNNQ3d4TUM0ell6QXNNQ3d3TERBc01Dd3dkakUwTGpOak1Dd3dMamNzTUM0MUxERXVNaXd4TGpJc01TNHlhREV3TGpWc01DNHlMREF1TW13NUxqa3NOeTQ1Q2dsak1DNDFMREF1TkN3eExqTXNNQzQwTERFdU55MHdMakpqTUM0eUxUQXVNaXd3TGpNdE1DNDFMREF1TXkwd0xqaFdNbU13TGpFdE1DNDJMVEF1TkMweExqSXRNUzB4TGpORE1qSXVOU3d3TGpjc01qSXVNU3d3TGpnc01qRXVPU3d4ZWlJdlBnbzhMM04yWno0PSk7XG4gICAgd2lkdGg6IDE4cHggIWltcG9ydGFudDtcbn1cbi5vcC1jb250cm9sc19fbXV0ZS0tbXV0ZWQ6YmVmb3JlIHtcbiAgICBjb250ZW50OiB1cmwoZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpZFhSbUxUZ2lQejRLUEhOMlp5QjJaWEp6YVc5dVBTSXhMakVpSUhodGJHNXpQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh5TURBd0wzTjJaeUlnZUcxc2JuTTZlR3hwYm1zOUltaDBkSEE2THk5M2QzY3Vkek11YjNKbkx6RTVPVGt2ZUd4cGJtc2lJSGc5SWpCd2VDSWdlVDBpTUhCNElnb0pJSFpwWlhkQ2IzZzlJakFnTUNBek5TQXpOU0lnYzNSNWJHVTlJbVZ1WVdKc1pTMWlZV05yWjNKdmRXNWtPbTVsZHlBd0lEQWdNelVnTXpVN0lpQjRiV3c2YzNCaFkyVTlJbkJ5WlhObGNuWmxJajRLUEhCaGRHZ2dabWxzYkQwaUkwWkdSa1pHUmlJZ1pEMGlUVEk0TERBdU1rd3hOeTQyTERndU5Xd3RNQzR5TERBdU1tZ3RNVEZETlM0M0xEZ3VOaXcxTGpFc09TNHhMRFVzT1M0NFl6QXNNQ3d3TERBdU1Td3dMREF1TVhZeE5DNDVZekFzTUM0M0xEQXVOaXd4TGpNc01TNHpMREV1TTJNd0xEQXNNQ3d3TERBc01Bb0phREV4YkRBdU1pd3dMakpzTVRBdU5DdzRMak5qTUM0MkxEQXVOQ3d4TGpRc01DNDBMREV1T0Mwd0xqSmpNQzR5TFRBdU1pd3dMak10TUM0MUxEQXVNeTB3TGpoV01TNHlZekF0TUM0M0xUQXVOUzB4TGpJdE1TNHlMVEV1TWtNeU9DNDFMREFzTWpndU1pd3dMakVzTWpnc01DNHllaUl2UGdvOEwzTjJaejQ9KTtcbiAgICB3aWR0aDogMThweCAhaW1wb3J0YW50O1xufVxuLm9wLWNvbnRyb2xzX19jYXB0aW9uczpiZWZvcmUge1xuICAgIGNvbnRlbnQ6IHVybChkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlkWFJtTFRnaVB6NEtQSE4yWnlCMlpYSnphVzl1UFNJeExqRWlJSGh0Ykc1elBTSm9kSFJ3T2k4dmQzZDNMbmN6TG05eVp5OHlNREF3TDNOMlp5SWdlRzFzYm5NNmVHeHBibXM5SW1oMGRIQTZMeTkzZDNjdWR6TXViM0puTHpFNU9Ua3ZlR3hwYm1zaUlIZzlJakJ3ZUNJZ2VUMGlNSEI0SWdvSklIWnBaWGRDYjNnOUlqQWdNQ0F6TlNBek5TSWdjM1I1YkdVOUltVnVZV0pzWlMxaVlXTnJaM0p2ZFc1a09tNWxkeUF3SURBZ016VWdNelU3SWlCNGJXdzZjM0JoWTJVOUluQnlaWE5sY25abElqNEtQSEJoZEdnZ1ptbHNiQzF5ZFd4bFBTSmxkbVZ1YjJSa0lpQmpiR2x3TFhKMWJHVTlJbVYyWlc1dlpHUWlJR1pwYkd3OUlpTkdSa1pHUmtZaUlHUTlJazB3TERRdU5IWXlOaTR5YURNMVZqUXVORWd3ZWlCTk16QXVOQ3d5TlM0MFl5MHdMaklzTUM0ekxUQXVOaXd3TGpVdE1DNDVMREF1TjJNdE1TNHhMREF1T0MwMkxqRXNNUzR4TFRFeExqa3NNUzR4VXpZdU5pd3lOaTQ1TERVdU5Td3lOaTR4Q2dsakxUQXVNeTB3TGpJdE1DNDNMVEF1TkMwd0xqa3RNQzQzWXkweExqRXRNUzQwTFRFdU1pMHpMalF0TVM0ekxUaHpNQzR5TFRZdU5pd3hMak10T0dNd0xqTXRNQzR6TERBdU5pMHdMalVzTUM0NUxUQXVOMk14TFRBdU9DdzJMak10TVM0eExERXlMakV0TVM0eGN6RXdMamdzTUM0ekxERXhMamtzTVM0eENnbGpNQzR6TERBdU1pd3dMallzTUM0MExEQXVPU3d3TGpkak1TNHhMREV1TkN3eExqTXNNeTQwTERFdU15dzRVek14TGpVc01qUXNNekF1TkN3eU5TNDBlaUl2UGdvOGNHRjBhQ0JtYVd4c0xYSjFiR1U5SW1WMlpXNXZaR1FpSUdOc2FYQXRjblZzWlQwaVpYWmxibTlrWkNJZ1ptbHNiRDBpSTBaR1JrWkdSaUlnWkQwaVRURTJMamtzTVRZdU1tTXRNQzR6TFRNdU5pMHlMakl0TlM0M0xUVXVOaTAxTGpkakxUTXVNU3d3TFRVdU5pd3lMamd0TlM0MkxEY3VNM015TGpJc055NDBMRFV1T1N3M0xqUmpNeXd3TERVdE1pNHlMRFV1TXkwMUxqaG9MVE11TlFvSll5MHdMakVzTVM0ekxUQXVOeXd5TGpRdE1TNDVMREl1TkdNdE1TNDVMREF0TWk0eUxURXVPQzB5TGpJdE15NDRZekF0TWk0M0xEQXVPQzAwTGpFc01pNHhMVFF1TVdNeExqRXNNQ3d4TGprc01DNDRMRElzTWk0elNERTJMamw2SWk4K0NqeHdZWFJvSUdacGJHd3RjblZzWlQwaVpYWmxibTlrWkNJZ1kyeHBjQzF5ZFd4bFBTSmxkbVZ1YjJSa0lpQm1hV3hzUFNJalJrWkdSa1pHSWlCa1BTSk5NamtzTVRZdU1tTXRNQzR6TFRNdU5pMHlMakl0TlM0M0xUVXVOaTAxTGpkakxUTXVNU3d3TFRVdU5pd3lMamd0TlM0MkxEY3VNM015TGpJc055NDBMRFV1T1N3M0xqUmpNeXd3TERVdE1pNHlMRFV1TXkwMUxqaG9MVE11TlFvSll5MHdMakVzTVM0ekxUQXVOeXd5TGpRdE1TNDVMREl1TkdNdE1TNDVMREF0TWk0eUxURXVPQzB5TGpJdE15NDRZekF0TWk0M0xEQXVPQzAwTGpFc01pNHhMVFF1TVhNeExqa3NNQzQ0TERJc01pNHpTREk1ZWlJdlBnbzhMM04yWno0PSk7XG4gICAgd2lkdGg6IDIwcHggIWltcG9ydGFudDtcbn1cbi5vcC1jb250cm9sc19fY2FwdGlvbnMub3AtY29udHJvbHNfX2NhcHRpb25zLS1vbjpiZWZvcmUge1xuICAgIGZpbHRlcjogaW52ZXJ0KDczJSkgc2VwaWEoNzElKSBzYXR1cmF0ZSg2ODY4JSkgaHVlLXJvdGF0ZSgzNTZkZWcpIGJyaWdodG5lc3MoMTAxJSkgY29udHJhc3QoMTI2JSk7XG59XG4ub3AtY29udHJvbHNfX3NldHRpbmdzOmJlZm9yZSB7XG4gICAgY29udGVudDogdXJsKGRhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEQ5NGJXd2dkbVZ5YzJsdmJqMGlNUzR3SWlCbGJtTnZaR2x1WnowaWRYUm1MVGdpUHo0S1BITjJaeUIyWlhKemFXOXVQU0l4TGpFaUlIaHRiRzV6UFNKb2RIUndPaTh2ZDNkM0xuY3pMbTl5Wnk4eU1EQXdMM04yWnlJZ2VHMXNibk02ZUd4cGJtczlJbWgwZEhBNkx5OTNkM2N1ZHpNdWIzSm5MekU1T1RrdmVHeHBibXNpSUhnOUlqQndlQ0lnZVQwaU1IQjRJZ29KSUhacFpYZENiM2c5SWpBZ01DQXpOU0F6TlNJZ2MzUjViR1U5SW1WdVlXSnNaUzFpWVdOclozSnZkVzVrT201bGR5QXdJREFnTXpVZ016VTdJaUI0Yld3NmMzQmhZMlU5SW5CeVpYTmxjblpsSWo0S1BIQmhkR2dnWm1sc2JEMGlJMFpHUmtaR1JpSWdaRDBpVFRNd0xqVXNNVGt1TW1Nd0xqRXRNQzQyTERBdU1TMHhMaklzTUM0eExURXVOMk13TFRBdU5pMHdMakV0TVM0eUxUQXVNUzB4TGpkc015NDNMVEl1T1dNd0xqTXRNQzR6TERBdU5DMHdMamdzTUM0eUxURXVNV3d0TXk0MUxUWXVNUW9KWXkwd0xqSXRNQzQwTFRBdU55MHdMalV0TVM0eExUQXVOR3d0TkM0MExERXVOMk10TUM0NUxUQXVOeTB4TGprdE1TNHpMVEl1T1MweExqZHNMVEF1TnkwMExqWkRNakV1T0N3d0xqTXNNakV1TlN3d0xESXhMREJvTFRkakxUQXVOQ3d3TFRBdU9Dd3dMak10TUM0NExEQXVOMnd0TUM0M0xEUXVOZ29KWXkweExqRXNNQzQwTFRJdU1Td3hMVE1zTVM0M1REVXVNaXcxTGpOakxUQXVOQzB3TGpJdE1DNDVMREF0TVM0eExEQXVOR3d0TXk0MUxEWXVNV010TUM0eUxEQXVOQzB3TGpFc01DNDVMREF1TWl3eExqRnNNeTQzTERJdU9XTXRNQzR4TERBdU5pMHdMakVzTVM0eUxUQXVNU3d4TGpjS0NXTXdMREF1Tml3d0xqRXNNUzR5TERBdU1Td3hMamRzTFRNdU55d3lMamxqTFRBdU15d3dMak10TUM0MExEQXVPQzB3TGpJc01TNHhiRE11TlN3MkxqRmpNQzR5TERBdU5Dd3dMamNzTUM0MUxERXVNU3d3TGpSc05DNDBMVEV1TjJNd0xqa3NNQzQzTERFdU9Td3hMak1zTWk0NUxERXVOd29KYkRBdU55dzBMalpqTUM0eExEQXVOQ3d3TGpRc01DNDNMREF1T1N3d0xqZG9OMk13TGpRc01Dd3dMamd0TUM0ekxEQXVPQzB3TGpkc01DNDNMVFF1Tm1NeExqRXRNQzQwTERJdE1Td3lMamt0TVM0M2JEUXVOQ3d4TGpkak1DNDBMREF1TWl3d0xqa3NNQ3d4TGpFdE1DNDBiRE11TlMwMkxqRUtDV013TGpJdE1DNDBMREF1TVMwd0xqa3RNQzR5TFRFdU1Vd3pNQzQxTERFNUxqSjZJRTB4Tnk0MUxESXpMalpqTFRNdU5Dd3dMVFl1TVMweUxqY3ROaTR4TFRZdU1XTXdMVE11TkN3eUxqY3ROaTR4TERZdU1TMDJMakZqTXk0MExEQXNOaTR4TERJdU55dzJMakVzTmk0eENnbERNak11Tml3eU1DNDVMREl3TGpnc01qTXVOaXd4Tnk0MUxESXpMalpNTVRjdU5Td3lNeTQyZWlJdlBnbzhMM04yWno0PSk7XG59XG5cbi8qID09PSBTZXR0aW5ncyA9PT09PT09PT09PT09PT09PT09ICovXG4ub3Atc2V0dGluZ3Mge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMjgsIDI4LCAyOCwgMC45KTtcbiAgICBib3R0b206IDQ4cHg7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgZm9udC1zaXplOiAwLjg1ZW07XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgcmlnaHQ6IDVweDtcbiAgICB0ZXh0LXNoYWRvdzogMCAwIDJweCByZ2JhKDAsIDAsIDAsIDAuNSk7XG4gICAgdHJhbnNpdGlvbjogcmlnaHQgMC4ycyBlYXNlO1xuICAgIHVzZXItc2VsZWN0OiBub25lO1xuICAgIHdpbGwtY2hhbmdlOiB3aWR0aCwgaGVpZ2h0O1xuICAgIHotaW5kZXg6IDQ7XG59XG4ub3AtcGxheWVyX19hdWRpbyAub3Atc2V0dGluZ3Mge1xuICAgIGJvdHRvbTogMzJweDtcbiAgICByaWdodDogMDtcbn1cbi5vcC1zZXR0aW5ncy0tc2xpZGluZyB7XG4gICAgcmlnaHQ6IC05OTlweDtcbn1cbi5vcC1zZXR0aW5nc19fbWVudSB7XG4gICAgbWFyZ2luOiAwO1xuICAgIG92ZXJmbG93LXg6IGhpZGRlbjtcbiAgICBvdmVyZmxvdy15OiBhdXRvO1xuICAgIHBhZGRpbmc6IDA7XG59XG4ub3Atc2V0dGluZ3NfX21lbnUtaXRlbSxcbi5vcC1zZXR0aW5nc19fc3VibWVudS1pdGVtIHtcbiAgICBkaXNwbGF5OiB0YWJsZS1yb3c7XG4gICAgb3V0bGluZTogbm9uZTtcbiAgICBwYWRkaW5nOiAwO1xufVxuLm9wLXNldHRpbmdzX19tZW51LWxhYmVsLFxuLm9wLXNldHRpbmdzX19zdWJtZW51LWxhYmVsIHtcbiAgICBkaXNwbGF5OiB0YWJsZS1jZWxsO1xuICAgIHBhZGRpbmc6IDVweCAxNXB4O1xuICAgIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG59XG4ub3Atc2V0dGluZ3NfX21lbnUtbGFiZWwgPiBpbWcsXG4ub3Atc2V0dGluZ3NfX21lbnUtbGFiZWwgPiBzdmcsXG4ub3Atc2V0dGluZ3NfX3N1Ym1lbnUtbGFiZWwgPiBpbWcsXG4ub3Atc2V0dGluZ3NfX3N1Ym1lbnUtbGFiZWwgPiBzdmcge1xuICAgIG1heC1oZWlnaHQ6IDIwcHg7XG59XG4ub3Atc2V0dGluZ3NfX3N1Ym1lbnUtaXRlbSxcbi5vcC1zZXR0aW5nc19fc3VibWVudS1sYWJlbCB7XG4gICAgZGlzcGxheTogYmxvY2s7XG59XG4ub3Atc2V0dGluZ3NfX3N1Ym1lbnUtaXRlbSB7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xufVxuLm9wLXNldHRpbmdzX19zdWJtZW51LWl0ZW1bYXJpYS1jaGVja2VkPSd0cnVlJ10gLm9wLXNldHRpbmdzX19zdWJtZW51LWxhYmVsIHtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlHaGxhV2RvZEQwaU1UQXdKU0lnZG1WeWMybHZiajBpTVM0eElpQjJhV1YzUW05NFBTSXdJREFnTWpRZ01qUWlJSGRwWkhSb1BTSXhNREFsSWo0OGNHRjBhQ0JrUFNKTk9TQXhOaTR5VERRdU9DQXhNbXd0TVM0MElERXVORXc1SURFNUlESXhJRGRzTFRFdU5DMHhMalJNT1NBeE5pNHllaUlnWm1sc2JEMGlJMlptWmlJZ0x6NDhMM04yWno0PScpO1xuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGxlZnQgNHB4IGNlbnRlcjtcbiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0O1xuICAgIGJhY2tncm91bmQtc2l6ZTogMThweDtcbiAgICBwYWRkaW5nOiA4cHggMTVweCA4cHggMjVweDtcbn1cbi5vcC1zZXR0aW5nc19fbWVudS1jb250ZW50IHtcbiAgICBiYWNrZ3JvdW5kLWltYWdlOiB1cmwoJ2RhdGE6aW1hZ2Uvc3ZnK3htbDtiYXNlNjQsUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlHaGxhV2RvZEQwaU1UQXdKU0lnZG1WeWMybHZiajBpTVM0eElpQjJhV1YzUW05NFBTSXdJREFnTXpJZ016SWlJSGRwWkhSb1BTSXhNREFsSWo0OGNHRjBhQ0JrUFNKdElERXlMalU1TERJd0xqTTBJRFF1TlRnc0xUUXVOVGtnTFRRdU5UZ3NMVFF1TlRrZ01TNDBNU3d0TVM0ME1TQTJMRFlnTFRZc05pQjZJaUJtYVd4c1BTSWpabVptSWlBdlBqd3ZjM1puUGc9PScpO1xuICAgIGJhY2tncm91bmQtcG9zaXRpb246IHJpZ2h0IDAgY2VudGVyO1xuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgYmFja2dyb3VuZC1zaXplOiAzMnB4IDMycHg7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGRpc3BsYXk6IHRhYmxlLWNlbGw7XG4gICAgcGFkZGluZzogMCAxNXB4O1xuICAgIHBhZGRpbmctcmlnaHQ6IDM4cHg7XG4gICAgdmVydGljYWwtYWxpZ246IG1pZGRsZTtcbn1cbi5vcC1zZXR0aW5nc19faGVhZGVyIHtcbiAgICBwYWRkaW5nOiA1cHg7XG59XG4ub3Atc2V0dGluZ3NfX2JhY2sge1xuICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgnZGF0YTppbWFnZS9zdmcreG1sO2Jhc2U2NCxQSE4yWnlCNGJXeHVjejBpYUhSMGNEb3ZMM2QzZHk1M015NXZjbWN2TWpBd01DOXpkbWNpSUdobGFXZG9kRDBpTVRBd0pTSWdkbVZ5YzJsdmJqMGlNUzR4SWlCMmFXVjNRbTk0UFNJd0lEQWdNeklnTXpJaUlIZHBaSFJvUFNJeE1EQWxJajQ4Y0dGMGFDQmtQU0pOSURFNUxqUXhMREl3TGpBNUlERTBMamd6TERFMUxqVWdNVGt1TkRFc01UQXVPVEVnTVRnc09TNDFJR3dnTFRZc05pQTJMRFlnZWlJZ1ptbHNiRDBpSTJabVppSWdMejQ4TDNOMlp6ND0nKTtcbiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiBsZWZ0IDAgY2VudGVyO1xuICAgIGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XG4gICAgYmFja2dyb3VuZC1zaXplOiAyMHB4IDMycHg7XG4gICAgY29sb3I6IGluaGVyaXQ7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIHBhZGRpbmc6IDAgMTBweCAwIDIwcHg7XG59XG5cbi8qID09PSBQcm9ncmVzcyAvIFZvbHVtZSA9PT09PT09PT09PT09PT09PT09ICovXG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXSxcbi5vcC1jb250cm9scyBwcm9ncmVzcyB7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICBib3JkZXI6IDA7XG4gICAgaGVpZ2h0OiA1cHg7XG4gICAgbGVmdDogMDtcbiAgICBtYXJnaW46IDA7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICB0cmFuc2l0aW9uOiBub25lO1xuICAgIHdpZHRoOiAxMDAlO1xufVxuLm9wLWNvbnRyb2xzIGlucHV0W3R5cGU9J3JhbmdlJ10ge1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIGhlaWdodDogMDtcbiAgICBwYWRkaW5nOiAyLjVweCAwO1xuICAgIC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcjogdHJhbnNwYXJlbnQ7XG4gICAgei1pbmRleDogMztcbn1cbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOmZvY3VzLFxuLm9wLWNvbnRyb2xzIHByb2dyZXNzIHtcbiAgICBvdXRsaW5lOiBub25lO1xufVxuLm9wLWNvbnRyb2xzIGlucHV0W3R5cGU9J3JhbmdlJ106Oi1tb3otZm9jdXMtb3V0ZXIge1xuICAgIGJvcmRlcjogMDtcbn1cbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOjotd2Via2l0LXNsaWRlci1ydW5uYWJsZS10cmFjayB7XG4gICAgYmFja2dyb3VuZDogMCAwO1xuICAgIGJvcmRlcjogMDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgaGVpZ2h0OiA4cHg7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXTo6LW1vei1yYW5nZS10cmFjayB7XG4gICAgYmFja2dyb3VuZDogMCAwO1xuICAgIGJvcmRlcjogMDtcbiAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgaGVpZ2h0OiA4cHg7XG4gICAgdXNlci1zZWxlY3Q6IG5vbmU7XG59XG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXTo6LW1zLXRyYWNrIHtcbiAgICBiYWNrZ3JvdW5kOiAwIDA7XG4gICAgYm9yZGVyOiAwO1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICBoZWlnaHQ6IDhweDtcbiAgICB1c2VyLXNlbGVjdDogbm9uZTtcbn1cbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOjotd2Via2l0LXNsaWRlci10aHVtYiB7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci1yYWRpdXM6IDEwMCU7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBoZWlnaHQ6IDEycHg7XG4gICAgbWFyZ2luLXRvcDogLTJweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgd2lkdGg6IDEycHg7XG59XG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXTo6LW1vei1yYW5nZS10aHVtYiB7XG4gICAgYXBwZWFyYW5jZTogbm9uZTtcbiAgICBiYWNrZ3JvdW5kOiAjZmZmO1xuICAgIGJvcmRlcjogMnB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci1yYWRpdXM6IDEwMCU7XG4gICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICBoZWlnaHQ6IDEycHg7XG4gICAgbWFyZ2luLXRvcDogLTJweDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgd2lkdGg6IDEycHg7XG59XG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXTo6LW1zLXRodW1iIHtcbiAgICBhcHBlYXJhbmNlOiBub25lO1xuICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgYm9yZGVyOiAycHggc29saWQgdHJhbnNwYXJlbnQ7XG4gICAgYm9yZGVyLXJhZGl1czogMTAwJTtcbiAgICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICAgIGhlaWdodDogMTJweDtcbiAgICBtYXJnaW4tdG9wOiAtMnB4O1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICB3aWR0aDogMTJweDtcbn1cbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOjotbXMtdG9vbHRpcCB7XG4gICAgZGlzcGxheTogbm9uZTtcbn1cbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOjotbXMtZmlsbC1sb3dlcixcbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOjotbXMtZmlsbC11cHBlciB7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG4ub3AtY29udHJvbHMgaW5wdXRbdHlwZT0ncmFuZ2UnXTo6LW1zLXRpY2tzLWJlZm9yZSxcbi5vcC1jb250cm9scyBpbnB1dFt0eXBlPSdyYW5nZSddOjotbXMtdGlja3MtYWZ0ZXIge1xuICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbn1cbi5vcC1jb250cm9scyAub3AtY29udHJvbHNfX3Byb2dyZXNzLS1zZWVrLmxvYWRpbmcge1xuICAgIGFuaW1hdGlvbjogcHJvZ3Jlc3MgMnMgbGluZWFyIGluZmluaXRlO1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudChcbiAgICAgICAgLTQ1ZGVnLFxuICAgICAgICByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMykgMjUlLFxuICAgICAgICB0cmFuc3BhcmVudCAyNSUsXG4gICAgICAgIHRyYW5zcGFyZW50IDUwJSxcbiAgICAgICAgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjMpIDUwJSxcbiAgICAgICAgcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjMpIDc1JSxcbiAgICAgICAgdHJhbnNwYXJlbnQgNzUlLFxuICAgICAgICB0cmFuc3BhcmVudFxuICAgICk7XG4gICAgYmFja2dyb3VuZC1yZXBlYXQ6IHJlcGVhdC14O1xuICAgIGJhY2tncm91bmQtc2l6ZTogMjVweCAyNXB4O1xufVxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWsuZXJyb3Ige1xuICAgIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgtNDVkZWcsICNmMDAgMjUlLCB0cmFuc3BhcmVudCAyNSUsIHRyYW5zcGFyZW50IDUwJSwgI2YwMCA1MCUsICNmMDAgNzUlLCB0cmFuc3BhcmVudCA3NSUsIHRyYW5zcGFyZW50KTtcbiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0LXg7XG4gICAgYmFja2dyb3VuZC1zaXplOiAyNXB4IDI1cHg7XG59XG4ub3AtY29udHJvbHMtLWhpZGRlbiAub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tc2Vlazo6LXdlYmtpdC1zbGlkZXItdGh1bWIge1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xufVxuLm9wLWNvbnRyb2xzLS1oaWRkZW4gLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWs6Oi1tb3otcmFuZ2UtdGh1bWIge1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xufVxuLm9wLWNvbnRyb2xzLS1oaWRkZW4gLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWs6Oi1tcy10aHVtYiB7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG59XG4ub3AtcGxheWVyX19tZWRpYVtvcC1saXZlX19lbmFibGVkXTpub3QoW29wLWR2cl9fZW5hYmxlZF0pICsgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWsge1xuICAgIGRpc3BsYXk6IG5vbmU7XG59XG4ub3AtcGxheWVyX19tZWRpYVtvcC1saXZlX19lbmFibGVkXTpub3QoW29wLWR2cl9fZW5hYmxlZF0pICsgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MsXG4ub3AtcGxheWVyX19tZWRpYVtvcC1saXZlX19lbmFibGVkXTpub3QoW29wLWR2cl9fZW5hYmxlZF0pICsgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXBsYXllZCxcbi5vcC1wbGF5ZXJfX21lZGlhW29wLWxpdmVfX2VuYWJsZWRdOm5vdChbb3AtZHZyX19lbmFibGVkXSkgKyAub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tYnVmZmVyIHtcbiAgICBiYWNrZ3JvdW5kLWNvbG9yOiAjZWVlO1xuICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xufVxuLm9wLWNvbnRyb2xzIHByb2dyZXNzIHtcbiAgICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gICAgdmVydGljYWwtYWxpZ246IGJhc2VsaW5lO1xufVxuLm9wLWNvbnRyb2xzIHByb2dyZXNzOjotd2Via2l0LXByb2dyZXNzLWJhciB7XG4gICAgYmFja2dyb3VuZDogMCAwO1xufVxuLm9wLWNvbnRyb2xzIHByb2dyZXNzOjotbW96LXByb2dyZXNzLWJhciB7XG4gICAgYmFja2dyb3VuZDogMCAwO1xufVxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3Mge1xuICAgIGZsZXgtZ3JvdzogMjtcbn1cbi5vcC1jb250cm9scyAub3AtY29udHJvbHNfX3Byb2dyZXNzLFxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3M6aG92ZXIsXG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX192b2x1bWUsXG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX192b2x1bWU6aG92ZXIge1xuICAgIGN1cnNvcjogcG9pbnRlcjtcbn1cbi5vcC1jb250cm9sc19fcHJvZ3Jlc3MsXG4ub3AtY29udHJvbHNfX3ZvbHVtZSB7XG4gICAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICAgIGhlaWdodDogNXB4O1xuICAgIG1hcmdpbi1sZWZ0OiAxMHB4O1xuICAgIG1hcmdpbi10b3A6IDlweDtcbiAgICBwb2ludGVyLWV2ZW50czogYWxsO1xuICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbn1cbi5vcC1wbGF5ZXJfX3ZpZGVvIC5vcC1jb250cm9sc19fcHJvZ3Jlc3Mge1xuICAgIGJvdHRvbTogMzRweDtcbiAgICBsZWZ0OiA4cHg7XG4gICAgbWFyZ2luLWxlZnQ6IC04cHg7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHdpZHRoOiAxMDAlO1xufVxuLm9wLXBsYXllcl9fdmlkZW8gLm9wLWNvbnRyb2xzLm9wLWNvbnRyb2xzX19zdGFja2VkIC5vcC1jb250cm9sc19fcHJvZ3Jlc3Mge1xuICAgIGJvdHRvbTogMDtcbiAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG59XG4ub3AtY29udHJvbHMgcHJvZ3Jlc3M6Oi13ZWJraXQtcHJvZ3Jlc3MtdmFsdWUge1xuICAgIGJhY2tncm91bmQ6IGN1cnJlbnRDb2xvcjtcbn1cbi5vcC1jb250cm9scyBwcm9ncmVzczo6LW1vei1wcm9ncmVzcy1iYXIge1xuICAgIGJhY2tncm91bmQ6IGN1cnJlbnRDb2xvcjtcbn1cbi5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLWJ1ZmZlcjo6LXdlYmtpdC1wcm9ncmVzcy12YWx1ZSB7XG4gICAgdHJhbnNpdGlvbjogd2lkdGggMC4ycyBlYXNlO1xufVxuLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tcGxheWVkOjotd2Via2l0LXByb2dyZXNzLXZhbHVlLFxuLm9wLWNvbnRyb2xzX192b2x1bWUtLWRpc3BsYXk6Oi13ZWJraXQtcHJvZ3Jlc3MtdmFsdWUge1xuICAgIG1heC13aWR0aDogOTklO1xuICAgIHRyYW5zaXRpb246IG5vbmU7XG59XG4ub3AtcGxheWVyX192aWRlbyAub3AtY29udHJvbHNfX3Byb2dyZXNzLS1wbGF5ZWQ6Oi13ZWJraXQtcHJvZ3Jlc3MtdmFsdWUge1xuICAgIG1heC13aWR0aDogMTAwJTtcbn1cbi5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLWJ1ZmZlcjo6LW1vei1wcm9ncmVzcy1iYXIge1xuICAgIHRyYW5zaXRpb246IHdpZHRoIDAuMnMgZWFzZTtcbn1cbi5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXBsYXllZDo6LW1vei1wcm9ncmVzcy1iYXIsXG4ub3AtY29udHJvbHNfX3ZvbHVtZS0tZGlzcGxheTo6LW1vei1wcm9ncmVzcy1iYXIge1xuICAgIG1heC13aWR0aDogOTklO1xuICAgIHRyYW5zaXRpb246IG5vbmU7XG59XG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tcGxheWVkLFxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fdm9sdW1lLS1kaXNwbGF5IHtcbiAgICBiYWNrZ3JvdW5kOiAwIDA7XG4gICAgY29sb3I6ICNmMDA7XG4gICAgdHJhbnNpdGlvbjogYWxsIDAuMnMgZWFzZTtcbiAgICB6LWluZGV4OiAyO1xufVxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fdm9sdW1lLS1kaXNwbGF5IHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMzUpO1xufVxuLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLWJ1ZmZlciB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjMpO1xuICAgIGNvbG9yOiByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMjUpO1xufVxuLm9wLWFkcy0tYWN0aXZlIC5vcC1jb250cm9scyAub3AtY29udHJvbHNfX3Byb2dyZXNzLS1zZWVrIHtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cbi5vcC1hZHMtLWFjdGl2ZSAub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tcGxheWVkIHtcbiAgICBjb2xvcjogI2ZlY2IyZjtcbn1cbi5vcC1hZHMtLWFjdGl2ZSAub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tYnVmZmVyIHtcbiAgICBjb2xvcjogdHJhbnNwYXJlbnQ7XG59XG4ub3AtYWRzLS1hY3RpdmUgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWs6Oi13ZWJraXQtc2xpZGVyLXRodW1iIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLm9wLWFkcy0tYWN0aXZlIC5vcC1jb250cm9scyAub3AtY29udHJvbHNfX3Byb2dyZXNzLS1zZWVrOjotbW96LXJhbmdlLXRodW1iIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLm9wLWFkcy0tYWN0aXZlIC5vcC1jb250cm9scyAub3AtY29udHJvbHNfX3Byb2dyZXNzLS1zZWVrOjotbXMtdGh1bWIge1xuICAgIGRpc3BsYXk6IG5vbmU7XG59XG4ub3AtYWRzLS1hY3RpdmUgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWs6Oi13ZWJraXQtc2xpZGVyLXJ1bm5hYmxlLXRyYWNrIHtcbiAgICBjdXJzb3I6IGRlZmF1bHQ7XG59XG4ub3AtYWRzLS1hY3RpdmUgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sc19fcHJvZ3Jlc3MtLXNlZWs6Oi1tb3otcmFuZ2UtdHJhY2sge1xuICAgIGN1cnNvcjogZGVmYXVsdDtcbn1cbi5vcC1hZHMtLWFjdGl2ZSAub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19wcm9ncmVzcy0tc2Vlazo6LW1zLXRyYWNrIHtcbiAgICBjdXJzb3I6IGRlZmF1bHQ7XG59XG4ub3AtYWRzLS1hY3RpdmUgLm9wLWNvbnRyb2xzIC5vcC1jb250cm9sX19oaWRlLWluLWFkIHtcbiAgICBjdXJzb3I6IGRlZmF1bHQ7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbn1cblxuLyogPT09IFN0YXR1cyA9PT09PT09PT09PT09PT09PT0gKi9cbi5vcC1zdGF0dXMge1xuICAgIGNvbG9yOiAjZmZmO1xuICAgIGZvbnQtd2VpZ2h0OiA0MDA7XG4gICAgbGVmdDogMDtcbiAgICBwYWRkaW5nOiAyMHB4IDA7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB0b3A6IDMwcHg7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC00MHB4KTtcbiAgICB0cmFuc2l0aW9uOiBhbGwgMC4zcyBlYXNlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHotaW5kZXg6IDQ7XG59XG4ub3Atc3RhdHVzID4gc3BhbiB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjcpO1xuICAgIGJveC1kZWNvcmF0aW9uLWJyZWFrOiBjbG9uZTtcbiAgICBsaW5lLWhlaWdodDogMTUwJTtcbiAgICBwYWRkaW5nOiAzcHggMTBweDtcbn1cblxuLm9wLXBsYXllcl9fYXVkaW8gLm9wLXN0YXR1cyB7XG4gICAgdG9wOiAyM3B4O1xufVxuXG4vKiA9PT0gVG9vbHRpcCA9PT09PT09PT09PT09PT09PT0gKi9cbi5vcC1jb250cm9sc19fdG9vbHRpcCB7XG4gICAgYmFja2dyb3VuZDogI2VlZTtcbiAgICBib3JkZXI6IDFweCBzb2xpZCAjMDAwO1xuICAgIGJvdHRvbTogMTAwJTtcbiAgICBjb2xvcjogIzAwMDtcbiAgICBkaXNwbGF5OiBub25lO1xuICAgIGxlZnQ6IDA7XG4gICAgbWFyZ2luLWJvdHRvbTogMTBweDtcbiAgICBwYWRkaW5nOiAxcHggNHB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKDAlKTtcbn1cbi5vcC1wbGF5ZXJfX3ZpZGVvIC5vcC1jb250cm9sc19fdG9vbHRpcCB7XG4gICAgbWFyZ2luLWJvdHRvbTogMTBweDtcbn1cbi5vcC1jb250cm9sc19fdG9vbHRpcDpiZWZvcmUsXG4ub3AtY29udHJvbHNfX3Rvb2x0aXA6YWZ0ZXIge1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIGhlaWdodDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIG1hcmdpbjogMCBhdXRvO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICByaWdodDogMDtcbiAgICB0b3A6IDEwMCU7XG4gICAgd2lkdGg6IDA7XG59XG4ub3AtY29udHJvbHNfX3Rvb2x0aXA6YmVmb3JlIHtcbiAgICBib3JkZXItbGVmdDogc29saWQgOHB4IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci1yaWdodDogc29saWQgOHB4IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci10b3A6IHNvbGlkIDhweCAjMDAwO1xufVxuLm9wLWNvbnRyb2xzX190b29sdGlwOmFmdGVyIHtcbiAgICBib3JkZXItbGVmdDogc29saWQgN3B4IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci1yaWdodDogc29saWQgN3B4IHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci10b3A6IHNvbGlkIDdweCAjZWVlO1xufVxuLm9wLWNvbnRyb2xzX190b29sdGlwLS12aXNpYmxlIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbn1cblxuLyogPT09IFZvbHVtZSA9PT09PT09PT09PT09PT09PT09ICovXG4ub3AtY29udHJvbHNfX3ZvbHVtZSB7XG4gICAgbWFyZ2luLWxlZnQ6IDA7XG4gICAgd2lkdGg6IDcwcHg7XG59XG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19tdXRlOmJlZm9yZSB7XG4gICAgdGV4dC1hbGlnbjogbGVmdDtcbn1cbi5vcC1wbGF5ZXJfX3ZpZGVvIC5vcC1jb250cm9sc19fdm9sdW1lIHtcbiAgICBtYXJnaW4tdG9wOiAxMHB4O1xufVxuLm9wLXBsYXllcl9fdW5tdXRlIHtcbiAgICBiYWNrZ3JvdW5kOiByZ2JhKDAsIDAsIDAsIDAuNyk7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIGxlZnQ6IDA7XG4gICAgcGFkZGluZzogNXB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDA7XG4gICAgei1pbmRleDogMztcbn1cblxuLyogPT0gRnVsbHNjcmVlbiA9PT09PT09PT09PT09ICovXG4ub3AtcGxheWVyW2RhdGEtZnVsbHNjcmVlbj0ndHJ1ZSddIC5vcC1jb250cm9scyB7XG4gICAgei1pbmRleDogMjE0NzQ4MzY0ODtcbn1cbi5vcC1wbGF5ZXJbZGF0YS1mdWxsc2NyZWVuPSd0cnVlJ10ub3AtY29udHJvbHMtLWhpZGRlbiB7XG4gICAgY3Vyc29yOiBub25lO1xufVxuLm9wLXBsYXllcltkYXRhLWZ1bGxzY3JlZW49J3RydWUnXS5vcC1jb250cm9scy0taGlkZGVuIC5vcC1jb250cm9scyB7XG4gICAgYm90dG9tOiAtNDBweDtcbn1cbi5vcC1wbGF5ZXIgdmlkZW86Oi13ZWJraXQtbWVkaWEtY29udHJvbHMsXG4ub3AtcGxheWVyIHZpZGVvOjotd2Via2l0LW1lZGlhLXRleHQtdHJhY2stY29udGFpbmVyIHtcbiAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG59XG5cbi8qID09IENhcHRpb25zID09PT09PT09PT09PT09PSAqL1xuLm9wLWNhcHRpb25zIHtcbiAgICBib3R0b206IDA7XG4gICAgY29sb3I6ICNmZmY7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICBmb250LXdlaWdodDogNDAwO1xuICAgIGxlZnQ6IDA7XG4gICAgcGFkZGluZzogMjBweCAwO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGVZKC00MHB4KTtcbiAgICB0cmFuc2l0aW9uOiB0cmFuc2Zvcm0gMC4zcyBlYXNlO1xuICAgIHdpZHRoOiAxMDAlO1xuICAgIHotaW5kZXg6IDE7XG59XG4ub3AtY29udHJvbHMtLWhpZGRlbiAub3AtY2FwdGlvbnMge1xuICAgIGJvdHRvbTogLTMycHg7XG59XG4ub3AtY2FwdGlvbnMtLW9uIHtcbiAgICBkaXNwbGF5OiBibG9jaztcbn1cbi5vcC1jYXB0aW9ucyA+IHNwYW4ge1xuICAgIGJhY2tncm91bmQ6IHJnYmEoMCwgMCwgMCwgMC43KTtcbiAgICBib3gtZGVjb3JhdGlvbi1icmVhazogY2xvbmU7XG4gICAgZGlzcGxheTogYmxvY2s7XG4gICAgbGluZS1oZWlnaHQ6IDE1MCU7XG4gICAgbWFyZ2luOiAwIGF1dG8gMTVweDtcbiAgICBwYWRkaW5nOiAzcHggMTBweDtcbiAgICB3aWR0aDogZml0LWNvbnRlbnQ7XG59XG4ub3AtcGxheWVyX19hdWRpby5vcC1jYXB0aW9ucy0tZGV0ZWN0ZWQge1xuICAgIGJhY2tncm91bmQ6IHRyYW5zcGFyZW50O1xuICAgIG1pbi1oZWlnaHQ6IDk1cHg7XG59XG4ub3AtcGxheWVyX19hdWRpby5vcC1jYXB0aW9ucy0tZGV0ZWN0ZWQgLm9wLWNhcHRpb25zIHtcbiAgICBib3R0b206IC0xMHB4O1xuICAgIHBhZGRpbmc6IDA7XG59XG4ub3AtcGxheWVyX19hdWRpby5vcC1jYXB0aW9ucy0tZGV0ZWN0ZWQgLm9wLWNhcHRpb25zID4gc3BhbiB7XG4gICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgY29sb3I6ICMwMDA7XG59XG4ub3AtcGxheWVyX19hdWRpby5vcC1jYXB0aW9ucy0tZGV0ZWN0ZWQgLm9wLWNvbnRyb2xzIHtcbiAgICBiYWNrZ3JvdW5kOiAjMDAwO1xuICAgIGJvdHRvbTogYXV0bztcbn1cbi5vcC1wbGF5ZXJfX2F1ZGlvLm9wLWNhcHRpb25zLS1kZXRlY3RlZCAub3Atc2V0dGluZ3Mge1xuICAgIGJvdHRvbTogYXV0bztcbiAgICB0b3A6IDM1cHg7XG59XG4ub3AtY29udHJvbHMgLm9wLWNvbnRyb2xzX19jYXB0aW9ucy0tb246YmVmb3JlIHtcbiAgICBjb2xvcjogcmVkO1xufVxuLm9wLWNhcHRpb25zX19tZW51IHtcbiAgICBib3R0b206IDM2cHg7XG4gICAgbGVmdDogNTAlO1xuICAgIG1pbi13aWR0aDogNzNweDtcbiAgICBvdmVyZmxvdzogdmlzaWJsZTtcbiAgICB0cmFuc2Zvcm06IHRyYW5zbGF0ZSgtNTAlLCAwKTtcbiAgICB6LWluZGV4OiAxMDtcbn1cbi5vcC1jYXB0aW9uc19fbWVudTphZnRlciB7XG4gICAgYm9yZGVyLWxlZnQ6IDEwcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gICAgYm9yZGVyLXJpZ2h0OiAxMHB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci10b3A6IDEwcHggc29saWQgcmdiYSgyOCwgMjgsIDI4LCAwLjkpO1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIGhlaWdodDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIG1hcmdpbjogMCBhdXRvO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICByaWdodDogMDtcbiAgICB0b3A6IDEwMCU7XG4gICAgd2lkdGg6IDA7XG59XG5cbi8qIFdlYlZUVCBjdWVzICovXG46OmN1ZSB7XG4gICAgY29sb3I6ICNjY2M7XG59XG52aWRlbzotd2Via2l0LW1lZGlhLXRleHQtdHJhY2stZGlzcGxheSB7XG4gICAgdG9wOiAtMTUlO1xufVxuXG4vKiA9PT0gTGV2ZWxzID09PT09PT09PT09PT09PT0gKi9cbi5vcC1sZXZlbHNfX21lbnUge1xuICAgIGJvdHRvbTogMzZweDtcbiAgICBsZWZ0OiA1MCU7XG4gICAgbWluLXdpZHRoOiA3M3B4O1xuICAgIG92ZXJmbG93OiB2aXNpYmxlO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIDApO1xuICAgIHotaW5kZXg6IDEwO1xufVxuLm9wLWxldmVsc19fbWVudTphZnRlciB7XG4gICAgYm9yZGVyLWxlZnQ6IDEwcHggc29saWQgdHJhbnNwYXJlbnQ7XG4gICAgYm9yZGVyLXJpZ2h0OiAxMHB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICAgIGJvcmRlci10b3A6IDEwcHggc29saWQgcmdiYSgyOCwgMjgsIDI4LCAwLjkpO1xuICAgIGNvbnRlbnQ6ICcnO1xuICAgIGhlaWdodDogMDtcbiAgICBsZWZ0OiAwO1xuICAgIG1hcmdpbjogMCBhdXRvO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICByaWdodDogMDtcbiAgICB0b3A6IDEwMCU7XG4gICAgd2lkdGg6IDA7XG59XG5cbi8qID09PSBBZHMgPT09PT09PT09PT09PT09PT09PSAqL1xuLm9wLWFkcyB7XG4gICAgaGVpZ2h0OiAxMDAlO1xuICAgIGxlZnQ6IDA7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHRvcDogMDtcbiAgICB3aWR0aDogMTAwJTtcbn1cbi5vcC1hZHMtLWFjdGl2ZSB7XG4gICAgb3ZlcmZsb3c6IGhpZGRlbjtcbn1cbi5vcC1hZHMtLWFjdGl2ZSAub3AtY29udHJvbHNfX2NhcHRpb25zLFxuLm9wLWFkcy0tYWN0aXZlIC5vcC1jYXB0aW9ucyxcbi5vcC1hZHMtLWFjdGl2ZSAub3AtY29udHJvbHNfX3NldHRpbmdzIHtcbiAgICBkaXNwbGF5OiBub25lO1xufVxuLm9wLWFkcy0tYWN0aXZlIC5vcC1jb250cm9sc19fZnVsbHNjcmVlbiB7XG4gICAgZmxvYXQ6IHJpZ2h0O1xufVxuLm9wLWFkcy0tYWN0aXZlIC5vcC1jb250cm9scyAub3AtY29udHJvbF9fcmlnaHQgfiAub3AtY29udHJvbF9fcmlnaHQge1xuICAgIG1hcmdpbi1sZWZ0OiBhdXRvO1xufVxuLm9wLWFkcy0tYWN0aXZlIC5vcC1hZHMge1xuICAgIHotaW5kZXg6IDE7XG59XG4ub3AtcGxheWVyW2RhdGEtZnVsbHNjcmVlbj0ndHJ1ZSddLm9wLWFkcy0tYWN0aXZlIC5vcC1hZHMge1xuICAgIHotaW5kZXg6IDIxNDc0ODM2NDU7XG59XG5cbi5vcC1hZHNfX2NsaWNrLWNvbnRhaW5lciB7XG4gICAgYmFja2dyb3VuZC1jb2xvcjogIzgwN2Y4MDtcbiAgICBjb2xvcjogI2ZmZjtcbiAgICBjdXJzb3I6IGRlZmF1bHQ7XG4gICAgZGlzcGxheTogbm9uZTtcbiAgICBwYWRkaW5nOiA1cHg7XG4gICAgcG9pbnRlci1ldmVudHM6IGF1dG87XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHJpZ2h0OiAwO1xuICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICB0b3A6IDA7XG4gICAgei1pbmRleDogMTAwO1xufVxuXG4ub3AtYWRzX19jbGljay1jb250YWluZXItLXZpc2libGUge1xuICAgIGRpc3BsYXk6IGJsb2NrO1xufVxuXG4ub3AtcGxheWVyW2RhdGEtZnVsbHNjcmVlbj0ndHJ1ZSddLm9wLWFkcy0tYWN0aXZlIC5vcC1hZHNfX2NsaWNrLWNvbnRhaW5lciB7XG4gICAgei1pbmRleDogMjE0NzQ4MzY0Nztcbn1cblxuLm9wLXBsYXllcl9fYXVkaW8gLm9wLWFkcyB7XG4gICAgZGlzcGxheTogbm9uZTtcbn1cblxuLm9wLWFkc19fc2tpcCB7XG4gICAgY29sb3I6ICNmZmY7XG59XG5cbi8qID09PSBGb2N1cyA9PT09PT09PT09PT09PT09PT09ICovXG4ub3AtcGxheWVyOmZvY3VzLFxuLm9wLXBsYXllcl9fcGxheTpmb2N1cyxcbi5vcC1wbGF5ZXIgPiAub3AtY29udHJvbHMgKjpmb2N1cyB7XG4gICAgb3V0bGluZTogZG90dGVkIDFweCAjOTk5O1xufVxuLm9wLXBsYXllci5vcC1wbGF5ZXJfX2tleWJvYXJkLS1pbmFjdGl2ZTpmb2N1cyxcbi5vcC1wbGF5ZXIub3AtcGxheWVyX19rZXlib2FyZC0taW5hY3RpdmUgLm9wLXBsYXllcl9fcGxheTpmb2N1cyxcbi5vcC1wbGF5ZXIub3AtcGxheWVyX19rZXlib2FyZC0taW5hY3RpdmUgPiAub3AtY29udHJvbHMgKjpmb2N1cyB7XG4gICAgb3V0bGluZTogbm9uZTtcbn1cblxuLyogPT09IEZ1bGxzY3JlZW4gZWZmZWN0ID09PT09PT09PSAqL1xuLm9wLXBsYXllci5vcC1wbGF5ZXJfX2Z1bGwge1xuICAgIGJvdHRvbTogMDtcbiAgICBsZWZ0OiAwO1xuICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgcG9zaXRpb246IGZpeGVkO1xuICAgIHJpZ2h0OiAwO1xuICAgIHRvcDogMDtcbiAgICB6LWluZGV4OiAtMTAwO1xufVxuLm9wLXBsYXllcl9fZnVsbCAub3AtcGxheWVyX19tZWRpYSxcbi5vcC1wbGF5ZXJfX2Z1bGwgLm9wLWFkcyB7XG4gICAgaGVpZ2h0OiBhdXRvO1xuICAgIGxlZnQ6IDUwJTtcbiAgICBtaW4taGVpZ2h0OiAxMDAlO1xuICAgIG1pbi13aWR0aDogMTAwJTtcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgdG9wOiA1MCU7XG4gICAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gICAgd2lkdGg6IGF1dG8gIWltcG9ydGFudDtcbn1cblxuLyogPT09IEZpdCBlZmZlY3QgPT09PT09PSAqL1xuLm9wLXBsYXllcl9fZml0LS13cmFwcGVyIHtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgcG9zaXRpb246IHJlbGF0aXZlO1xuICAgIHdpZHRoOiAxMDAlO1xufVxuLm9wLXBsYXllci5vcC1wbGF5ZXJfX2ZpdCB7XG4gICAgYmFja2dyb3VuZDogIzAwMDtcbiAgICBoZWlnaHQ6IDEwMCU7XG4gICAgbGVmdDogMDtcbiAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDA7XG4gICAgd2lkdGg6IDEwMCU7XG59XG4ub3AtcGxheWVyX19maXQgLm9wLXBsYXllcl9fbWVkaWEsXG4ub3AtcGxheWVyX19maXQgLm9wLWFkcyB7XG4gICAgYm9yZGVyOiAwO1xuICAgIGRpc3BsYXk6IGJsb2NrO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBtaW4taGVpZ2h0OiAxMDAlO1xuICAgIHdpZHRoOiAxMDAlO1xufVxuXG4vKiA9PT0gRGV2aWNlLXNwZWNpZmljIHJ1bGVzID09PT09PT09PSAqL1xuLm9wLXBsYXllcl9faW9zLS1pcGhvbmUgLm9wLXBsYXllcl9fcGxheSB7XG4gICAgbWFyZ2luLXRvcDogLTVweDtcbn1cbi5vcC1wbGF5ZXIub3AtcGxheWVyX19pb3MtLWlwaG9uZSB2aWRlbzo6LXdlYmtpdC1tZWRpYS1jb250cm9scyB7XG4gICAgZGlzcGxheTogYmxvY2sgIWltcG9ydGFudDtcbn1cbi5vcC1wbGF5ZXJbZGF0YS1mdWxsc2NyZWVuPSd0cnVlJ10ub3AtcGxheWVyLm9wLXBsYXllcl9faW9zLS1pcGhvbmUgdmlkZW86Oi13ZWJraXQtbWVkaWEtdGV4dC10cmFjay1jb250YWluZXIge1xuICAgIGRpc3BsYXk6IGJsb2NrICFpbXBvcnRhbnQ7XG59XG4ub3AtcGxheWVyW2RhdGEtZnVsbHNjcmVlbj0ndHJ1ZSddLm9wLXBsYXllci5vcC1wbGF5ZXJfX2lvcy0taXBob25lIHZpZGVvOjotd2Via2l0LW1lZGlhLXRleHQtdHJhY2stZGlzcGxheS1iYWNrZHJvcCB7XG4gICAgYmFja2dyb3VuZDogcmdiYSgwLCAwLCAwLCAwLjQ5ODAzOSkgIWltcG9ydGFudDtcbn1cbiJdfQ== */ diff --git a/packages/p2p-media-loader-demo/src/constants.ts b/packages/p2p-media-loader-demo/src/constants.ts index 091d31fc..cd5ce457 100644 --- a/packages/p2p-media-loader-demo/src/constants.ts +++ b/packages/p2p-media-loader-demo/src/constants.ts @@ -4,6 +4,7 @@ export const PLAYERS = [ "hlsjs-clappr", "hlsjs-vime", "hlsjs-plyr", + "hlsjs-openplayer", ] as const; export const DEFAULT_STREAM = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 91bd304b..ab343317 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -118,6 +118,9 @@ importers: hls.js: specifier: ^1.5.7 version: 1.5.7 + openplayerjs: + specifier: ^2.14.3 + version: 2.14.3 p2p-media-loader-core: specifier: workspace:* version: link:../p2p-media-loader-core @@ -915,6 +918,11 @@ packages: asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + auto-changelog@2.4.0: + resolution: {integrity: sha512-vh17hko1c0ItsEcw6m7qPRf3m45u+XK5QyCrrBFViElZ8jnKrPC1roSznrd1fIB/0vR/zawdECCRJtTuqIXaJw==} + engines: {node: '>=8.3'} + hasBin: true + available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -1614,6 +1622,11 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -1993,6 +2006,9 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + nested-error-stacks@2.1.1: resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} @@ -2000,6 +2016,15 @@ packages: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-fetch@3.3.2: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2052,6 +2077,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + openplayerjs@2.14.3: + resolution: {integrity: sha512-1fY19ShTCNVgUaKkD+aL6Jf55jf8S2EUTZ958UwERN6qsofHRBIp3dGPjoG9jOHw/bY6zFxZKlpXx3tJgXp7YQ==} + engines: {node: '>=16.0.0'} + optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -2098,6 +2127,11 @@ packages: resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} engines: {node: '>= 0.10'} + parse-github-url@1.0.2: + resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} + engines: {node: '>=0.10.0'} + hasBin: true + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -2374,6 +2408,10 @@ packages: resolution: {integrity: sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==} engines: {node: '>=0.10.0'} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} @@ -2459,6 +2497,9 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + ts-api-utils@1.3.0: resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -2515,6 +2556,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + uint8-util@2.2.4: resolution: {integrity: sha512-uEI5lLozmKQPYEevfEhP9LY3Je5ZmrQhaWXrzTVqrLNQl36xsRh8NiAxYwB9J+2BAt99TRbmCkROQB2ZKhx4UA==} @@ -2589,6 +2635,12 @@ packages: resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -2609,6 +2661,9 @@ packages: engines: {node: '>= 8'} hasBin: true + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -3428,6 +3483,16 @@ snapshots: asynckit@0.4.0: {} + auto-changelog@2.4.0: + dependencies: + commander: 7.2.0 + handlebars: 4.7.8 + node-fetch: 2.7.0 + parse-github-url: 1.0.2 + semver: 7.6.0 + transitivePeerDependencies: + - encoding + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 @@ -4423,6 +4488,15 @@ snapshots: graphemer@1.4.0: {} + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + has-bigints@1.0.2: {} has-flag@3.0.0: {} @@ -4765,10 +4839,16 @@ snapshots: natural-compare@1.4.0: {} + neo-async@2.6.2: {} + nested-error-stacks@2.1.1: {} node-domexception@1.0.0: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-fetch@3.3.2: dependencies: data-uri-to-buffer: 4.0.1 @@ -4855,6 +4935,13 @@ snapshots: dependencies: wrappy: 1.0.2 + openplayerjs@2.14.3: + dependencies: + auto-changelog: 2.4.0 + core-js: 3.37.0 + transitivePeerDependencies: + - encoding + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 @@ -4905,6 +4992,8 @@ snapshots: pbkdf2: 3.1.2 safe-buffer: 5.2.1 + parse-github-url@1.0.2: {} + path-browserify@1.0.1: {} path-exists@4.0.0: {} @@ -5199,6 +5288,8 @@ snapshots: source-map-js@1.1.0: {} + source-map@0.6.1: {} + sprintf-js@1.1.3: {} stencil-wormhole@3.4.1: {} @@ -5310,6 +5401,8 @@ snapshots: dependencies: is-number: 7.0.0 + tr46@0.0.3: {} + ts-api-utils@1.3.0(typescript@5.4.2): dependencies: typescript: 5.4.2 @@ -5370,6 +5463,9 @@ snapshots: typescript@5.4.2: {} + uglify-js@3.17.4: + optional: true + uint8-util@2.2.4: dependencies: base64-arraybuffer: 1.0.2 @@ -5435,6 +5531,13 @@ snapshots: web-streams-polyfill@3.3.3: {} + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + which-boxed-primitive@1.0.2: dependencies: is-bigint: 1.0.4 @@ -5477,6 +5580,8 @@ snapshots: dependencies: isexe: 2.0.0 + wordwrap@1.0.0: {} + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 From b67a41aebc7adb6b33dd178ee68b855352378c80 Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Thu, 18 Apr 2024 16:51:57 +0300 Subject: [PATCH 06/55] added opt groups in playback options --- .../src/components/P2PVideoDemo.tsx | 20 +++++----- .../src/components/PlaybackOptions.tsx | 37 +++++++++++++++---- .../p2p-media-loader-demo/src/constants.ts | 16 ++++---- .../src/hooks/useQueryParams.ts | 2 +- packages/p2p-media-loader-demo/src/types.ts | 5 +++ 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx index d7a40909..a9588d47 100644 --- a/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx +++ b/packages/p2p-media-loader-demo/src/components/P2PVideoDemo.tsx @@ -8,7 +8,7 @@ import { useCallback, useMemo, useRef, useState } from "react"; import { DownloadStatsChart } from "./chart/DownloadStatsChart"; import { NodeNetwork } from "./nodeNetwork/NodeNetwork"; import { DebugTools } from "./debugTools/DebugTools"; -import { DownloadStats } from "../types"; +import { DownloadStats, PlayerKey } from "../types"; import { HlsjsDPlayer } from "./players/HlsjsDPLayer"; import { HlsjsClapprPlayer } from "./players/HlsjsClapprPlayer"; import { HlsjsVime } from "./players/HlsjsVime"; @@ -22,8 +22,6 @@ declare global { } } -export type Player = (typeof PLAYERS)[number]; - type DemoProps = { debugToolsEnabled?: boolean; }; @@ -77,13 +75,13 @@ export const P2PVideoDemo = ({ debugToolsEnabled }: DemoProps) => { }, []); const handlePlaybackOptionsUpdate = (url: string, player: string) => { - if (!PLAYERS.includes(player as Player)) return; + if (!(player in PLAYERS)) return; setURLQueryParams({ streamUrl: url, player }); }; const renderPlayer = () => { - switch (queryParams.player) { - case "hlsjs-openplayer": + switch (queryParams.player as PlayerKey) { + case "openPlayer_hls": return ( { /> ); - case "hlsjs-plyr": + case "plyr_hls": return ( { /> ); - case "hlsjs-vime": + case "vime_hls": return ( { /> ); - case "hlsjs-clappr": + case "clappr_hls": return ( { /> ); - case "hlsjs-dplayer": + case "dplayer_hls": return ( { /> ); - case "hlsjs": + case "hlsjs_hls": return ( void; @@ -17,6 +18,17 @@ export const PlaybackOptions = ({ const isHttps = window.location.protocol === "https:"; + const hlsPlayers: Partial> = {}; + const shakaPlayers: Partial> = {}; + + Object.entries(PLAYERS).forEach(([key, name]) => { + if (key.includes("hls")) { + hlsPlayers[key as PlayerKey] = name; + } else if (key.includes("shaka")) { + shakaPlayers[key as PlayerKey] = name; + } + }); + const handleApply = () => { const player = playerSelectRef.current?.value; const streamUrl = streamUrlInputRef.current?.value; @@ -45,16 +57,27 @@ export const PlaybackOptions = ({
diff --git a/packages/p2p-media-loader-demo/src/constants.ts b/packages/p2p-media-loader-demo/src/constants.ts index cd5ce457..ec971bb2 100644 --- a/packages/p2p-media-loader-demo/src/constants.ts +++ b/packages/p2p-media-loader-demo/src/constants.ts @@ -1,11 +1,11 @@ -export const PLAYERS = [ - "hlsjs", - "hlsjs-dplayer", - "hlsjs-clappr", - "hlsjs-vime", - "hlsjs-plyr", - "hlsjs-openplayer", -] as const; +export const PLAYERS = { + hlsjs_hls: "Hls.js", + dplayer_hls: "DPlayer", + clappr_hls: "Clappr", + vime_hls: "Vime", + plyr_hls: "Plyr", + openPlayer_hls: "OpenPlayerJS", +} as const; export const DEFAULT_STREAM = "https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"; export const COLORS = { diff --git a/packages/p2p-media-loader-demo/src/hooks/useQueryParams.ts b/packages/p2p-media-loader-demo/src/hooks/useQueryParams.ts index 921c5c12..ee40bf36 100644 --- a/packages/p2p-media-loader-demo/src/hooks/useQueryParams.ts +++ b/packages/p2p-media-loader-demo/src/hooks/useQueryParams.ts @@ -4,7 +4,7 @@ import { DEFAULT_STREAM, DEFAULT_TRACKERS, PLAYERS } from "../constants"; type QueryParamsType = Record; const defaultParams: QueryParamsType = { - player: PLAYERS[0], + player: Object.keys(PLAYERS)[0], streamUrl: DEFAULT_STREAM, trackers: DEFAULT_TRACKERS, }; diff --git a/packages/p2p-media-loader-demo/src/types.ts b/packages/p2p-media-loader-demo/src/types.ts index af21995f..05341364 100644 --- a/packages/p2p-media-loader-demo/src/types.ts +++ b/packages/p2p-media-loader-demo/src/types.ts @@ -1,3 +1,5 @@ +import { PLAYERS } from "./constants"; + export type DownloadStats = { httpDownloaded: number; p2pDownloaded: number; @@ -12,3 +14,6 @@ export type SvgDimensionsType = { export type ChartsData = { seconds: number; } & DownloadStats; + +export type PlayerKey = keyof typeof PLAYERS; +export type PlayerName = (typeof PLAYERS)[PlayerKey]; From 754e21c3beaf91de78730e3d59c523803524fe74 Mon Sep 17 00:00:00 2001 From: DimaDemchenko Date: Fri, 19 Apr 2024 14:57:34 +0300 Subject: [PATCH 07/55] shaka player --- demo/index.html | 3 + packages/p2p-media-loader-demo/package.json | 5 +- .../src/components/P2PVideoDemo.tsx | 25 ++++-- .../components/players/{ => hlsjs}/Hlsjs.tsx | 0 .../players/{ => hlsjs}/HlsjsClapprPlayer.tsx | 0 .../players/{ => hlsjs}/HlsjsDPLayer.tsx | 0 .../players/hlsjs/HlsjsMediaElement.tsx | 89 +++++++++++++++++++ .../players/{ => hlsjs}/HlsjsOpenPlayer.tsx | 0 .../players/{ => hlsjs}/HlsjsPlyr.tsx | 0 .../players/{ => hlsjs}/HlsjsVime.tsx | 0 .../players/{ => hlsjs}/openPlayer.css | 0 .../components/players/{ => hlsjs}/plyr.css | 0 .../src/components/players/shaka/Shaka.tsx | 78 ++++++++++++++++ .../p2p-media-loader-demo/src/constants.ts | 2 + pnpm-lock.yaml | 31 +++++++ 15 files changed, 226 insertions(+), 7 deletions(-) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/Hlsjs.tsx (100%) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/HlsjsClapprPlayer.tsx (100%) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/HlsjsDPLayer.tsx (100%) create mode 100644 packages/p2p-media-loader-demo/src/components/players/hlsjs/HlsjsMediaElement.tsx rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/HlsjsOpenPlayer.tsx (100%) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/HlsjsPlyr.tsx (100%) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/HlsjsVime.tsx (100%) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/openPlayer.css (100%) rename packages/p2p-media-loader-demo/src/components/players/{ => hlsjs}/plyr.css (100%) create mode 100644 packages/p2p-media-loader-demo/src/components/players/shaka/Shaka.tsx diff --git a/demo/index.html b/demo/index.html index 62453718..bb7cefb8 100644 --- a/demo/index.html +++ b/demo/index.html @@ -20,6 +20,9 @@ type="text/javascript" src="https://cdn.jsdelivr.net/npm/shaka-player@~4/dist/shaka-player.compiled.min.js" > + + + - - - - +