[{"data":1,"prerenderedAt":5128},["ShallowReactive",2],{"navigation_docs":3,"-video-player-api":63,"-video-player-api-surround":5123},[4,26,44],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":25},"Getting Started","i-lucide:rocket","\u002Fgetting-started","01.getting-started",[10,14],{"title":11,"path":12,"stem":13,"icon":6},"Introduction","\u002Fgetting-started\u002Fintroduction","01.getting-started\u002F01.introduction",{"title":15,"icon":16,"path":17,"stem":18,"children":19,"page":25},"AI","i-lucide:bot","\u002Fgetting-started\u002Fai","01.getting-started\u002F02.ai",[20],{"title":21,"path":22,"stem":23,"icon":24},"LLMs Integration","\u002Fgetting-started\u002Fai\u002Fllms-txt","01.getting-started\u002F02.ai\u002F01.llms-txt","i-lucide:folder-code",false,{"title":27,"path":28,"stem":29,"children":30},"Video Player","\u002Fvideo-player","02.video-player",[31,34,39],{"title":27,"path":28,"stem":32,"icon":33},"02.video-player\u002Findex","i-lucide:play-circle",{"title":35,"path":36,"stem":37,"icon":38},"Getting started","\u002Fvideo-player\u002Fgetting-started","02.video-player\u002F01.getting-started","i-lucide:download",{"title":40,"path":41,"stem":42,"icon":43},"API reference","\u002Fvideo-player\u002Fapi","02.video-player\u002F02.api","i-lucide:book-open",{"title":45,"icon":46,"path":47,"stem":48,"children":49,"page":25},"Ship Kit","i-lucide:package","\u002Fshipkit","03.shipkit",[50,53,58],{"title":11,"path":51,"stem":52,"icon":46},"\u002Fshipkit\u002Fintroduction","03.shipkit\u002F01.introduction",{"title":54,"path":55,"stem":56,"icon":57},"CLI","\u002Fshipkit\u002Fcli","03.shipkit\u002F02.cli","i-lucide:terminal",{"title":59,"path":60,"stem":61,"icon":62},"Vite Configs","\u002Fshipkit\u002Fvite-configs","03.shipkit\u002F03.vite-configs","i-lucide:code",{"id":64,"title":40,"body":65,"description":5116,"extension":5117,"links":5118,"meta":5119,"navigation":5120,"path":41,"seo":5121,"stem":42,"__hash__":5122},"docs\u002F02.video-player\u002F02.api.md",{"type":66,"value":67,"toc":5083},"minimark",[68,73,154,285,328,353,372,377,384,554,563,567,572,741,744,811,827,831,841,1056,1088,1107,1266,1283,1292,1741,1763,1769,1775,1922,2083,2090,2107,2245,2248,2298,2313,2347,2351,2367,2436,2459,2465,2481,2606,2633,2639,2656,2884,2966,3002,3006,3015,3032,3127,3398,3411,3415,3623,3630,3693,3708,3712,3883,3903,3917,3921,3927,3933,3970,3996,4055,4059,4127,4146,4150,4153,4267,4270,4319,4323,4344,4348,4352,4361,4813,4982,4991,4995,5013,5017,5020,5024,5037,5065,5079],[69,70,72],"h2",{"id":71},"components","Components",[74,75,80],"pre",{"className":76,"code":77,"language":78,"meta":79,"style":79},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { VideoPlayer, VideoStage, VideoCard, VideoPlaceholder, VideoPlayerPlugin, getPlatform } from '@munsonlabs\u002Fvideo-player'\nimport '@munsonlabs\u002Fvideo-player\u002Fstyle'\n","ts","",[81,82,83,142],"code",{"__ignoreMap":79},[84,85,88,92,96,100,103,106,108,111,113,116,118,121,123,126,129,132,135,139],"span",{"class":86,"line":87},"line",1,[84,89,91],{"class":90},"s7zQu","import",[84,93,95],{"class":94},"sMK4o"," {",[84,97,99],{"class":98},"sTEyZ"," VideoPlayer",[84,101,102],{"class":94},",",[84,104,105],{"class":98}," VideoStage",[84,107,102],{"class":94},[84,109,110],{"class":98}," VideoCard",[84,112,102],{"class":94},[84,114,115],{"class":98}," VideoPlaceholder",[84,117,102],{"class":94},[84,119,120],{"class":98}," VideoPlayerPlugin",[84,122,102],{"class":94},[84,124,125],{"class":98}," getPlatform",[84,127,128],{"class":94}," }",[84,130,131],{"class":90}," from",[84,133,134],{"class":94}," '",[84,136,138],{"class":137},"sfazB","@munsonlabs\u002Fvideo-player",[84,140,141],{"class":94},"'\n",[84,143,145,147,149,152],{"class":86,"line":144},2,[84,146,91],{"class":90},[84,148,134],{"class":94},[84,150,151],{"class":137},"@munsonlabs\u002Fvideo-player\u002Fstyle",[84,153,141],{"class":94},[155,156,157,170],"table",{},[158,159,160],"thead",{},[161,162,163,167],"tr",{},[164,165,166],"th",{},"Export",[164,168,169],{},"Description",[171,172,173,184,194,207,219,233,255,269],"tbody",{},[161,174,175,181],{},[176,177,178],"td",{},[81,179,180],{},"VideoPlayer",[176,182,183],{},"The player itself - one video, full controls, always mounted immediately",[161,185,186,191],{},[176,187,188],{},[81,189,190],{},"VideoCard",[176,192,193],{},"Lazy-mountable single video (shows a poster\u002Fplaceholder until it enters view or is clicked)",[161,195,196,201],{},[176,197,198],{},[81,199,200],{},"VideoStage",[176,202,203,204,206],{},"Sticky, full-width playlist stage that receives videos from ",[81,205,190],{}," via window events",[161,208,209,214],{},[176,210,211],{},[81,212,213],{},"VideoPlaceholder",[176,215,216,217],{},"Poster\u002Floading placeholder used internally by ",[81,218,190],{},[161,220,221,226],{},[176,222,223],{},[81,224,225],{},"VideoPlayerPlugin",[176,227,228,229,232],{},"Vue plugin - ",[81,230,231],{},"app.use(VideoPlayerPlugin)"," registers all components globally",[161,234,235,240],{},[176,236,237],{},[81,238,239],{},"getPlatform(url)",[176,241,242,243,246,247,250,251,254],{},"Returns ",[81,244,245],{},"'youtube' | 'vimeo' | 'dailymotion' | 'jwplayer' | 'brightcove' | 'html5'"," for a built-in URL, or whatever ",[81,248,249],{},"key"," a ",[81,252,253],{},"registerPlatform()"," call registered",[161,256,257,261],{},[176,258,259],{},[81,260,253],{},[176,262,263,264],{},"Teaches the player a new platform without forking - see ",[265,266,268],"a",{"href":267},"#adding-a-custom-platform","below",[161,270,271,276],{},[176,272,273],{},[81,274,275],{},"HideMarker",[176,277,278,279,281,282],{},"Slotless sentinel - tucks a pinned ",[81,280,200],{}," away to a sliver while it's in the viewport, see ",[265,283,268],{"href":284},"#hiding-the-pinned-stage-over-content",[286,287,288,289,292,293,296,297,300,301,300,304,300,307,310,311,315,316,319,320,323,324,327],"p",{},"A custom-element build is also available from ",[81,290,291],{},"@munsonlabs\u002Fvideo-player\u002Felement",", exposing ",[81,294,295],{},"\u003Cml-video-card>"," (and ",[81,298,299],{},"ml-video-player","\u002F",[81,302,303],{},"ml-video-stage",[81,305,306],{},"ml-video-placeholder",[81,308,309],{},"ml-hide-marker",", plus the ",[265,312,314],{"href":313},"#headless-controls","headless controls"," below as ",[81,317,318],{},"ml-controls-play-button"," etc.) for non-Vue hosts — the ",[81,321,322],{},"ml-"," prefix namespaces the tags to avoid colliding with other libraries' custom elements, and ",[81,325,326],{},"ml-controls-*"," further separates the headless controls from the core player tags.",[286,329,330,331,334,335,338,339,341,342,345,346,345,349,352],{},"If you only need one half, two smaller bundles are also available: ",[81,332,333],{},"@munsonlabs\u002Fvideo-player\u002Felement\u002Fcore"," (just the four player\u002Fstage\u002Fitem\u002Fplaceholder tags) and ",[81,336,337],{},"@munsonlabs\u002Fvideo-player\u002Felement\u002Fcontrols"," (just the thirteen ",[81,340,326],{}," tags). Don't import more than one of ",[81,343,344],{},"\u002Felement",", ",[81,347,348],{},"\u002Felement\u002Fcore",[81,350,351],{},"\u002Felement\u002Fcontrols"," on the same page — they'd double-register any tag they share and throw.",[286,354,355,357,358,360,361,364,365,368,369,371],{},[81,356,344],{}," and ",[81,359,348],{}," dynamically ",[81,362,363],{},"import()"," a platform's adapter code (YouTube\u002FVimeo\u002FDailymotion\u002FJW Player\u002FBrightcove) only once a URL for that platform actually mounts, from a sibling ",[81,366,367],{},"chunks\u002F"," directory - a page that only plays plain MP4\u002FHLS\u002FDASH downloads none of it. A directory-serving CDN (unpkg\u002Fjsdelivr\u002Fesm.sh) needs no special handling; self-hosting either bundle means deploying its ",[81,370,367],{}," directory alongside it.",[373,374,376],"h3",{"id":375},"how-a-url-becomes-a-playing-embed","How a URL becomes a playing embed",[286,378,379,380,383],{},"What happens between setting ",[81,381,382],{},"src"," and an embed (YouTube\u002FVimeo\u002FDailymotion\u002Fa custom platform) actually appearing on screen, end to end:",[385,386,387,411,429,475,494,520,541],"ol",{},[388,389,390,394,395,398,399,402,403,406,407,410],"li",{},[391,392,393],"strong",{},"Platform detection."," On mount, ",[81,396,397],{},"usePlayer"," calls ",[81,400,401],{},"resolvePlatform(src)",", which checks the URL against every registered matcher (the six built-ins plus anything added via ",[81,404,405],{},"registerPlatform",") and returns a platform key plus whether it's ",[81,408,409],{},"embed"," or a plain source.",[388,412,413,416,417,420,421,424,425,428],{},[391,414,415],{},"Adapter construction."," That result goes to ",[81,418,419],{},"mountAdapter",", which either resolves a source URL and builds a native ",[81,422,423],{},"\u003Cvideo>","\u002Fhls.js\u002Fdash.js adapter, or - for embeds - looks up the platform's registered factory (e.g. ",[81,426,427],{},"createYoutubeAdapter",") and calls it.",[388,430,431,434,435,438,439,442,443,445,446,449,450,452,453,456,457,460,461,463,464,466,467,471,472,474],{},[391,432,433],{},"Hidden mount."," The embed factory calls ",[81,436,437],{},"createEmbedMount",", which inserts a wrapper ",[81,440,441],{},"\u003Cdiv>"," next to the ",[81,444,423],{}," element and starts it at ",[81,447,448],{},"opacity: 0; pointer-events: none",". The ",[81,451,423],{}," (showing its ",[81,454,455],{},"poster",") stays the visible thing for now - this is what masks the embed SDK's own iframe loading chrome (spinners, its own poster flash) until the SDK is actually ready. The adapter's ",[81,458,459],{},"el"," is this wrapper, not the ",[81,462,423],{}," itself (unlike the native path, where ",[81,465,459],{}," ",[468,469,470],"em",{},"is"," the ",[81,473,423],{},").",[388,476,477,480,481,345,484,345,487,345,490,493],{},[391,478,479],{},"SDK boot + event translation."," The factory loads the platform's SDK (or reuses it if another instance already has), builds the player inside the wrapper, and translates the SDK's own events into the common set every adapter emits (",[81,482,483],{},"play",[81,485,486],{},"pause",[81,488,489],{},"timeupdate",[81,491,492],{},"durationchange",", etc.).",[388,495,496,499,500,345,502,505,506,509,510,345,513,345,516,519],{},[391,497,498],{},"Wiring."," Back in ",[81,501,397],{},[81,503,504],{},"finalizeAdapter"," stores the adapter and calls ",[81,507,508],{},"attachPlayerEvents",", which subscribes all the reactive player state (",[81,511,512],{},"isPlaying",[81,514,515],{},"current",[81,517,518],{},"supportsCaptions",", ...) to those translated events.",[388,521,522,525,526,529,530,533,534,536,537,540],{},[391,523,524],{},"Reveal."," Once the adapter actually starts playing for the first time (",[81,527,528],{},"hasStarted"," flips true), a ",[81,531,532],{},"watch"," swaps visibility: the ",[81,535,423],{}," is hidden and the wrapper fades to ",[81,538,539],{},"opacity: 1"," with pointer events restored - this is the moment the embed becomes the visible thing.",[388,542,543,546,547,550,551,553],{},[391,544,545],{},"Teardown."," On unmount, the adapter's ",[81,548,549],{},"dispose()"," removes the wrapper, restores the ",[81,552,423],{}," element's normal display, and detaches the platform's own event listeners.",[286,555,556,557,559,560,562],{},"The native (non-embed) path skips steps 3 and 6 entirely - the ",[81,558,423],{}," element is the adapter's ",[81,561,459],{}," from the start, so there's nothing separate to reveal.",[69,564,566],{"id":565},"adding-a-custom-platform","Adding a custom platform",[286,568,569,571],{},[81,570,405],{}," teaches the player about a platform beyond the built-in six (YouTube, Vimeo, Dailymotion, Brightcove, JW Player, plain HTML5\u002FHLS\u002FDASH), without forking the package:",[74,573,575],{"className":76,"code":574,"language":78,"meta":79,"style":79},"import { registerPlatform } from '@munsonlabs\u002Fvideo-player'\n\nregisterPlatform({\n  key: 'acme',\n  test: (url) => url.includes('acme.tv'),\n  embed: true, \u002F\u002F true: the platform has its own SDK\u002Fiframe; false: it resolves to a plain playable file\n  createAdapter: (videoEl, options) => createAcmeAdapter(videoEl, options),\n})\n",[81,576,577,596,602,614,635,679,697,732],{"__ignoreMap":79},[84,578,579,581,583,586,588,590,592,594],{"class":86,"line":87},[84,580,91],{"class":90},[84,582,95],{"class":94},[84,584,585],{"class":98}," registerPlatform",[84,587,128],{"class":94},[84,589,131],{"class":90},[84,591,134],{"class":94},[84,593,138],{"class":137},[84,595,141],{"class":94},[84,597,598],{"class":86,"line":144},[84,599,601],{"emptyLinePlaceholder":600},true,"\n",[84,603,605,608,611],{"class":86,"line":604},3,[84,606,405],{"class":607},"s2Zo4",[84,609,610],{"class":98},"(",[84,612,613],{"class":94},"{\n",[84,615,617,621,624,626,629,632],{"class":86,"line":616},4,[84,618,620],{"class":619},"swJcz","  key",[84,622,623],{"class":94},":",[84,625,134],{"class":94},[84,627,628],{"class":137},"acme",[84,630,631],{"class":94},"'",[84,633,634],{"class":94},",\n",[84,636,638,641,643,646,650,653,657,660,663,666,668,670,673,675,677],{"class":86,"line":637},5,[84,639,640],{"class":607},"  test",[84,642,623],{"class":94},[84,644,645],{"class":94}," (",[84,647,649],{"class":648},"sHdIc","url",[84,651,652],{"class":94},")",[84,654,656],{"class":655},"spNyl"," =>",[84,658,659],{"class":98}," url",[84,661,662],{"class":94},".",[84,664,665],{"class":607},"includes",[84,667,610],{"class":98},[84,669,631],{"class":94},[84,671,672],{"class":137},"acme.tv",[84,674,631],{"class":94},[84,676,652],{"class":98},[84,678,634],{"class":94},[84,680,682,685,687,691,693],{"class":86,"line":681},6,[84,683,684],{"class":619},"  embed",[84,686,623],{"class":94},[84,688,690],{"class":689},"sfNiH"," true",[84,692,102],{"class":94},[84,694,696],{"class":695},"sHwdD"," \u002F\u002F true: the platform has its own SDK\u002Fiframe; false: it resolves to a plain playable file\n",[84,698,700,703,705,707,710,712,715,717,719,722,725,727,730],{"class":86,"line":699},7,[84,701,702],{"class":607},"  createAdapter",[84,704,623],{"class":94},[84,706,645],{"class":94},[84,708,709],{"class":648},"videoEl",[84,711,102],{"class":94},[84,713,714],{"class":648}," options",[84,716,652],{"class":94},[84,718,656],{"class":655},[84,720,721],{"class":607}," createAcmeAdapter",[84,723,724],{"class":98},"(videoEl",[84,726,102],{"class":94},[84,728,729],{"class":98}," options)",[84,731,634],{"class":94},[84,733,735,738],{"class":86,"line":734},8,[84,736,737],{"class":94},"}",[84,739,740],{"class":98},")\n",[286,742,743],{},"Call it once, before mounting any player that might see the new URL - resolution reads the registry fresh every time (no caching), so ordering is the only thing that matters.",[745,746,747,792],"ul",{},[388,748,749,754,755,758,759,762,763,300,765,300,767,770,771,300,774,300,777,780,781,345,783,345,785,345,788,345,790,493],{},[391,750,751],{},[81,752,753],{},"embed: true"," - the platform owns its own player (YouTube, Twitch, Vimeo). ",[81,756,757],{},"createAdapter"," is a factory ",[81,760,761],{},"(videoEl, options) => PlaybackAdapter"," returning every method the player needs (",[81,764,483],{},[81,766,486],{},[81,768,769],{},"currentTime","\u002Fcaptions\u002Fquality\u002FPiP\u002Ffullscreen\u002F",[81,772,773],{},"on",[81,775,776],{},"off",[81,778,779],{},"dispose","), translating your SDK's own events into the ones the player listens for (",[81,782,483],{},[81,784,486],{},[81,786,787],{},"ended",[81,789,489],{},[81,791,492],{},[388,793,794,799,800,803,804,807,808,810],{},[391,795,796],{},[81,797,798],{},"embed: false"," - the platform just hosts a file\u002Fmanifest behind an opaque URL or ID (JW Player, Brightcove). ",[81,801,802],{},"resolveSource"," (optional - skip it if the URL is already a direct, playable link) returns ",[81,805,806],{},"{ src, type?, poster?, adTagUrl? }","; the native ",[81,809,423],{},"\u002Fhls.js\u002Fdash.js path handles playback for you.",[286,812,813,815,816,819,820,300,823,826],{},[81,814,405],{}," is ",[81,817,818],{},"registerMatcher"," + ",[81,821,822],{},"registerEmbedAdapter",[81,824,825],{},"registerSourceResolver"," in one call - each is exported separately too, for the rare case you only need one.",[373,828,830],{"id":829},"from-a-web-component","From a web component",[286,832,833,835,836,357,838,840],{},[81,834,405],{}," is exported from ",[81,837,344],{},[81,839,348],{}," too:",[74,842,846],{"className":843,"code":844,"language":845,"meta":79,"style":79},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript type=\"module\">\n  import { registerPlatform } from 'https:\u002F\u002Fesm.sh\u002F@munsonlabs\u002Fvideo-player\u002Felement\u002Fcore'\n  registerPlatform({ key: 'acme', test: (url) => url.includes('acme.tv'), embed: true, createAdapter: createAcmeAdapter })\n\n  const player = document.createElement('ml-video-player')\n  player.setAttribute('src', 'https:\u002F\u002Facme.tv\u002Fwatch\u002F123')\n  document.body.append(player)\n\u003C\u002Fscript>\n","html",[81,847,848,873,893,968,972,1000,1029,1047],{"__ignoreMap":79},[84,849,850,853,856,859,862,865,868,870],{"class":86,"line":87},[84,851,852],{"class":94},"\u003C",[84,854,855],{"class":619},"script",[84,857,858],{"class":655}," type",[84,860,861],{"class":94},"=",[84,863,864],{"class":94},"\"",[84,866,867],{"class":137},"module",[84,869,864],{"class":94},[84,871,872],{"class":94},">\n",[84,874,875,878,880,882,884,886,888,891],{"class":86,"line":144},[84,876,877],{"class":90},"  import",[84,879,95],{"class":94},[84,881,585],{"class":98},[84,883,128],{"class":94},[84,885,131],{"class":90},[84,887,134],{"class":94},[84,889,890],{"class":137},"https:\u002F\u002Fesm.sh\u002F@munsonlabs\u002Fvideo-player\u002Felement\u002Fcore",[84,892,141],{"class":94},[84,894,895,898,900,903,906,908,910,912,914,916,919,921,923,925,927,929,931,933,935,937,939,941,943,945,947,950,952,954,956,959,961,964,966],{"class":86,"line":604},[84,896,897],{"class":607},"  registerPlatform",[84,899,610],{"class":98},[84,901,902],{"class":94},"{",[84,904,905],{"class":619}," key",[84,907,623],{"class":94},[84,909,134],{"class":94},[84,911,628],{"class":137},[84,913,631],{"class":94},[84,915,102],{"class":94},[84,917,918],{"class":607}," test",[84,920,623],{"class":94},[84,922,645],{"class":94},[84,924,649],{"class":648},[84,926,652],{"class":94},[84,928,656],{"class":655},[84,930,659],{"class":98},[84,932,662],{"class":94},[84,934,665],{"class":607},[84,936,610],{"class":98},[84,938,631],{"class":94},[84,940,672],{"class":137},[84,942,631],{"class":94},[84,944,652],{"class":98},[84,946,102],{"class":94},[84,948,949],{"class":619}," embed",[84,951,623],{"class":94},[84,953,690],{"class":689},[84,955,102],{"class":94},[84,957,958],{"class":619}," createAdapter",[84,960,623],{"class":94},[84,962,963],{"class":98}," createAcmeAdapter ",[84,965,737],{"class":94},[84,967,740],{"class":98},[84,969,970],{"class":86,"line":616},[84,971,601],{"emptyLinePlaceholder":600},[84,973,974,977,980,982,985,987,990,992,994,996,998],{"class":86,"line":637},[84,975,976],{"class":655},"  const",[84,978,979],{"class":98}," player ",[84,981,861],{"class":94},[84,983,984],{"class":98}," document",[84,986,662],{"class":94},[84,988,989],{"class":607},"createElement",[84,991,610],{"class":98},[84,993,631],{"class":94},[84,995,299],{"class":137},[84,997,631],{"class":94},[84,999,740],{"class":98},[84,1001,1002,1005,1007,1010,1012,1014,1016,1018,1020,1022,1025,1027],{"class":86,"line":681},[84,1003,1004],{"class":98},"  player",[84,1006,662],{"class":94},[84,1008,1009],{"class":607},"setAttribute",[84,1011,610],{"class":98},[84,1013,631],{"class":94},[84,1015,382],{"class":137},[84,1017,631],{"class":94},[84,1019,102],{"class":94},[84,1021,134],{"class":94},[84,1023,1024],{"class":137},"https:\u002F\u002Facme.tv\u002Fwatch\u002F123",[84,1026,631],{"class":94},[84,1028,740],{"class":98},[84,1030,1031,1034,1036,1039,1041,1044],{"class":86,"line":699},[84,1032,1033],{"class":98},"  document",[84,1035,662],{"class":94},[84,1037,1038],{"class":98},"body",[84,1040,662],{"class":94},[84,1042,1043],{"class":607},"append",[84,1045,1046],{"class":98},"(player)\n",[84,1048,1049,1052,1054],{"class":86,"line":734},[84,1050,1051],{"class":94},"\u003C\u002F",[84,1053,855],{"class":619},[84,1055,872],{"class":94},[286,1057,1058,1059,1062,1063,300,1065,398,1067,1070,1071,1074,1075,466,1078,1081,1082,1084,1085,1087],{},"One thing that doesn't come up in the Vue case - ",[391,1060,1061],{},"timing",": importing ",[81,1064,344],{},[81,1066,348],{},[81,1068,1069],{},"customElements.define()",", which synchronously upgrades any matching tag already in the DOM as part of that call, and a ",[81,1072,1073],{},"\u003Cscript type=\"module\">"," defers until after the whole document has been parsed - so a ",[468,1076,1077],{},"statically-declared",[81,1079,1080],{},"\u003Cml-video-player>"," tag is already sitting in the DOM by the time your script runs, and gets upgraded (running ",[81,1083,397],{},"'s adapter resolution) as soon as the import above evaluates, before your own ",[81,1086,405],{}," call on the next line has a chance to run. Creating the tag from script, after registering, as above sidesteps this entirely.",[286,1089,1090,1091,1093,1094,1099,1100,1102,1103,1106],{},"If your tags are statically declared in the markup (so you can't create them after registering), load ",[81,1092,348],{}," with a ",[391,1095,1096],{},[81,1097,1098],{},"?defer"," query instead: it skips the automatic ",[81,1101,1069],{}," on import, so you register your platform first and then call the exported ",[81,1104,1105],{},"defineElements()"," yourself - the static tags upgrade at that point, with your platform already in the registry:",[74,1108,1110],{"className":843,"code":1109,"language":845,"meta":79,"style":79},"\u003Cscript type=\"module\">\n  import { registerPlatform, defineElements } from 'https:\u002F\u002Fesm.sh\u002F@munsonlabs\u002Fvideo-player\u002Felement\u002Fcore?defer'\n  registerPlatform({ key: 'acme', test: (url) => url.includes('acme.tv'), embed: true, createAdapter: createAcmeAdapter })\n  defineElements()\n\u003C\u002Fscript>\n\n\u003Cml-video-player src=\"https:\u002F\u002Facme.tv\u002Fwatch\u002F123\">\u003C\u002Fml-video-player>\n",[81,1111,1112,1130,1154,1222,1230,1238,1242],{"__ignoreMap":79},[84,1113,1114,1116,1118,1120,1122,1124,1126,1128],{"class":86,"line":87},[84,1115,852],{"class":94},[84,1117,855],{"class":619},[84,1119,858],{"class":655},[84,1121,861],{"class":94},[84,1123,864],{"class":94},[84,1125,867],{"class":137},[84,1127,864],{"class":94},[84,1129,872],{"class":94},[84,1131,1132,1134,1136,1138,1140,1143,1145,1147,1149,1152],{"class":86,"line":144},[84,1133,877],{"class":90},[84,1135,95],{"class":94},[84,1137,585],{"class":98},[84,1139,102],{"class":94},[84,1141,1142],{"class":98}," defineElements",[84,1144,128],{"class":94},[84,1146,131],{"class":90},[84,1148,134],{"class":94},[84,1150,1151],{"class":137},"https:\u002F\u002Fesm.sh\u002F@munsonlabs\u002Fvideo-player\u002Felement\u002Fcore?defer",[84,1153,141],{"class":94},[84,1155,1156,1158,1160,1162,1164,1166,1168,1170,1172,1174,1176,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196,1198,1200,1202,1204,1206,1208,1210,1212,1214,1216,1218,1220],{"class":86,"line":604},[84,1157,897],{"class":607},[84,1159,610],{"class":98},[84,1161,902],{"class":94},[84,1163,905],{"class":619},[84,1165,623],{"class":94},[84,1167,134],{"class":94},[84,1169,628],{"class":137},[84,1171,631],{"class":94},[84,1173,102],{"class":94},[84,1175,918],{"class":607},[84,1177,623],{"class":94},[84,1179,645],{"class":94},[84,1181,649],{"class":648},[84,1183,652],{"class":94},[84,1185,656],{"class":655},[84,1187,659],{"class":98},[84,1189,662],{"class":94},[84,1191,665],{"class":607},[84,1193,610],{"class":98},[84,1195,631],{"class":94},[84,1197,672],{"class":137},[84,1199,631],{"class":94},[84,1201,652],{"class":98},[84,1203,102],{"class":94},[84,1205,949],{"class":619},[84,1207,623],{"class":94},[84,1209,690],{"class":689},[84,1211,102],{"class":94},[84,1213,958],{"class":619},[84,1215,623],{"class":94},[84,1217,963],{"class":98},[84,1219,737],{"class":94},[84,1221,740],{"class":98},[84,1223,1224,1227],{"class":86,"line":616},[84,1225,1226],{"class":607},"  defineElements",[84,1228,1229],{"class":98},"()\n",[84,1231,1232,1234,1236],{"class":86,"line":637},[84,1233,1051],{"class":94},[84,1235,855],{"class":619},[84,1237,872],{"class":94},[84,1239,1240],{"class":86,"line":681},[84,1241,601],{"emptyLinePlaceholder":600},[84,1243,1244,1246,1248,1251,1253,1255,1257,1259,1262,1264],{"class":86,"line":699},[84,1245,852],{"class":94},[84,1247,299],{"class":619},[84,1249,1250],{"class":655}," src",[84,1252,861],{"class":94},[84,1254,864],{"class":94},[84,1256,1024],{"class":137},[84,1258,864],{"class":94},[84,1260,1261],{"class":94},">\u003C\u002F",[84,1263,299],{"class":619},[84,1265,872],{"class":94},[286,1267,1268,1270,1271,1273,1274,1276,1277,1279,1280,1282],{},[81,1269,1098],{}," is read from the ",[81,1272,348],{}," module's own URL, so import ",[81,1275,348],{}," directly with the query (or point an import-map entry at a URL that includes it) - the combined ",[81,1278,344],{}," bundle always registers immediately, since it imports the core module internally without the query. ",[81,1281,1105],{}," is idempotent: it only defines whichever tags aren't already registered.",[69,1284,1286,1287,1289,1290,652],{"id":1285},"props-videocard-videoplayer","Props (",[81,1288,190],{}," \u002F ",[81,1291,180],{},[155,1293,1294,1309],{},[158,1295,1296],{},[161,1297,1298,1301,1304,1307],{},[164,1299,1300],{},"Prop",[164,1302,1303],{},"Type",[164,1305,1306],{},"Default",[164,1308,169],{},[171,1310,1311,1333,1352,1369,1396,1416,1432,1449,1469,1487,1505,1524,1542,1563,1582,1602,1625,1652,1670,1699,1720],{},[161,1312,1313,1317,1322,1325],{},[176,1314,1315],{},[81,1316,382],{},[176,1318,1319],{},[81,1320,1321],{},"string",[176,1323,1324],{},"-",[176,1326,1327,1330,1331],{},[391,1328,1329],{},"Required."," The video URL or platform-specific URI - platform is auto-detected, see ",[265,1332,35],{"href":36},[161,1334,1335,1340,1344,1349],{},[176,1336,1337],{},[81,1338,1339],{},"title",[176,1341,1342],{},[81,1343,1321],{},[176,1345,1346],{},[81,1347,1348],{},"''",[176,1350,1351],{},"Video title",[161,1353,1354,1358,1362,1366],{},[176,1355,1356],{},[81,1357,455],{},[176,1359,1360],{},[81,1361,1321],{},[176,1363,1364],{},[81,1365,1348],{},[176,1367,1368],{},"Poster image URL",[161,1370,1371,1376,1380,1385],{},[176,1372,1373],{},[81,1374,1375],{},"aspectRatio",[176,1377,1378],{},[81,1379,1321],{},[176,1381,1382],{},[81,1383,1384],{},"'16:9'",[176,1386,1387,1388,345,1390,345,1393],{},"e.g. ",[81,1389,1384],{},[81,1391,1392],{},"'9:16'",[81,1394,1395],{},"'4:3'",[161,1397,1398,1403,1408,1413],{},[176,1399,1400],{},[81,1401,1402],{},"autoplay",[176,1404,1405],{},[81,1406,1407],{},"boolean",[176,1409,1410],{},[81,1411,1412],{},"false",[176,1414,1415],{},"Autoplay on mount (starts muted - browsers block unmuted autoplay without a gesture)",[161,1417,1418,1423,1427,1429],{},[176,1419,1420],{},[81,1421,1422],{},"muted",[176,1424,1425],{},[81,1426,1407],{},[176,1428,1324],{},[176,1430,1431],{},"Force a starting mute state - if unset, follows the shared persisted audio preference",[161,1433,1434,1439,1444,1446],{},[176,1435,1436],{},[81,1437,1438],{},"volume",[176,1440,1441],{},[81,1442,1443],{},"number",[176,1445,1324],{},[176,1447,1448],{},"Force a starting volume (0-1) - if unset, follows the shared persisted audio preference",[161,1450,1451,1456,1460,1466],{},[176,1452,1453],{},[81,1454,1455],{},"lazy",[176,1457,1458],{},[81,1459,1407],{},[176,1461,1462,1465],{},[81,1463,1464],{},"true","*",[176,1467,1468],{},"Show placeholder until clicked",[161,1470,1471,1476,1480,1484],{},[176,1472,1473],{},[81,1474,1475],{},"nativeUi",[176,1477,1478],{},[81,1479,1407],{},[176,1481,1482],{},[81,1483,1412],{},[176,1485,1486],{},"Use the platform's native controls (YouTube, Vimeo, Dailymotion only)",[161,1488,1489,1494,1498,1502],{},[176,1490,1491],{},[81,1492,1493],{},"autoStage",[176,1495,1496],{},[81,1497,1407],{},[176,1499,1500],{},[81,1501,1412],{},[176,1503,1504],{},"Immediately send this video to the stage on mount",[161,1506,1507,1512,1516,1521],{},[176,1508,1509],{},[81,1510,1511],{},"playbackRate",[176,1513,1514],{},[81,1515,1443],{},[176,1517,1518],{},[81,1519,1520],{},"1",[176,1522,1523],{},"Initial playback rate",[161,1525,1526,1531,1535,1539],{},[176,1527,1528],{},[81,1529,1530],{},"adTagUrl",[176,1532,1533],{},[81,1534,1321],{},[176,1536,1537],{},[81,1538,1348],{},[176,1540,1541],{},"VAST or VMAP ad tag URL",[161,1543,1544,1549,1554,1556],{},[176,1545,1546],{},[81,1547,1548],{},"adMacroParams",[176,1550,1551],{},[81,1552,1553],{},"object",[176,1555,1324],{},[176,1557,1558,1559,1562],{},"Fills ",[81,1560,1561],{},"{macro}"," tokens in whichever ad tag URL ends up in use",[161,1564,1565,1570,1574,1576],{},[176,1566,1567],{},[81,1568,1569],{},"headerBidding",[176,1571,1572],{},[81,1573,1553],{},[176,1575,1324],{},[176,1577,1578,1579],{},"Runs a Prebid.js auction before the ad plays: ",[81,1580,1581],{},"{ adUnit, params?, timeoutMs? }",[161,1583,1584,1589,1594,1596],{},[176,1585,1586],{},[81,1587,1588],{},"tracks",[176,1590,1591],{},[81,1592,1593],{},"array",[176,1595,1324],{},[176,1597,1598,1599],{},"WebVTT caption\u002Fsubtitle tracks: ",[81,1600,1601],{},"{ src, kind?, srclang?, label?, default? }[]",[161,1603,1604,1609,1613,1618],{},[176,1605,1606],{},[81,1607,1608],{},"payload",[176,1610,1611],{},[81,1612,1553],{},[176,1614,1615],{},[81,1616,1617],{},"{}",[176,1619,1620,1621,1624],{},"Arbitrary data attached to every ",[81,1622,1623],{},"state-change"," event",[161,1626,1627,1632,1637,1642],{},[176,1628,1629],{},[81,1630,1631],{},"action",[176,1633,1634],{},[81,1635,1636],{},"PlayerAction",[176,1638,1639],{},[81,1640,1641],{},"null",[176,1643,1644,1645,1648,1649],{},"Button shown in the player HUD - a built-in (",[81,1646,1647],{},"'mute' | 'loop' | 'autoplay'",") or ",[81,1650,1651],{},"{ icon, label, onClick }",[161,1653,1654,1659,1663,1667],{},[176,1655,1656],{},[81,1657,1658],{},"disableTapCapture",[176,1660,1661],{},[81,1662,1407],{},[176,1664,1665],{},[81,1666,1412],{},[176,1668,1669],{},"Disables the full-video tap-to-reveal-controls overlay",[161,1671,1672,1677,1681,1685],{},[176,1673,1674],{},[81,1675,1676],{},"controls",[176,1678,1679],{},[81,1680,1407],{},[176,1682,1683],{},[81,1684,1464],{},[176,1686,1687,1688,1690,1691,1693,1694,1698],{},"Set ",[81,1689,1412],{}," to render a bare ",[81,1692,423],{}," with no HUD at all - drive playback via the ",[265,1695,1697],{"href":1696},"#template-ref-methods-videoplayer","template-ref methods"," instead",[161,1700,1701,1706,1710,1714],{},[176,1702,1703],{},[81,1704,1705],{},"playInView",[176,1707,1708],{},[81,1709,1407],{},[176,1711,1712],{},[81,1713,1412],{},[176,1715,1716,1717,1719],{},"Auto-play once at least half the player is visible, and auto-pause once it isn't - for a scroll-snap feed. Implies muted unless ",[81,1718,1422],{}," is set explicitly",[161,1721,1722,1727,1732,1734],{},[176,1723,1724],{},[81,1725,1726],{},"pin",[176,1728,1729],{},[81,1730,1731],{},"PinCorner",[176,1733,1324],{},[176,1735,1736,1737,1740],{},"Pins the player to that screen corner (",[81,1738,1739],{},"'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'",") once it scrolls out of view while playing, instead of auto-pausing. Omit to disable",[286,1742,1743,1744,1746,1747,1749,1750,1752,1753,1755,1756,1759,1760,1762],{},"* Only ",[81,1745,190],{}," implements the lazy placeholder. ",[81,1748,180],{}," accepts the prop for type compatibility but always mounts immediately regardless of its value. ",[81,1751,1705],{}," works with the default lazy placeholder too - ",[81,1754,213],{}," watches its own visibility and mounts the real player once it crosses the same threshold, so you don't need ",[81,1757,1758],{},"lazy=\"false\""," to use both together. If several ",[81,1761,1705],{}," players are visible at once, a shared debounce lets only the last one to cross the threshold actually play.",[69,1764,1766,1767,652],{"id":1765},"template-ref-methods-videoplayer","Template-ref methods (",[81,1768,180],{},[286,1770,1771,1772,1774],{},"A template ref on ",[81,1773,180],{}," exposes the imperative API:",[74,1776,1780],{"className":1777,"code":1778,"language":1779,"meta":79,"style":79},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup>\nimport { ref } from 'vue'\nconst player = ref(null)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CVideoPlayer ref=\"player\" src=\"...\" \u002F>\n  \u003Cbutton @click=\"player.retry()\">Retry\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n","vue",[81,1781,1782,1793,1812,1829,1837,1841,1850,1882,1913],{"__ignoreMap":79},[84,1783,1784,1786,1788,1791],{"class":86,"line":87},[84,1785,852],{"class":94},[84,1787,855],{"class":619},[84,1789,1790],{"class":655}," setup",[84,1792,872],{"class":94},[84,1794,1795,1797,1799,1802,1804,1806,1808,1810],{"class":86,"line":144},[84,1796,91],{"class":90},[84,1798,95],{"class":94},[84,1800,1801],{"class":98}," ref",[84,1803,128],{"class":94},[84,1805,131],{"class":90},[84,1807,134],{"class":94},[84,1809,1779],{"class":137},[84,1811,141],{"class":94},[84,1813,1814,1817,1819,1821,1823,1825,1827],{"class":86,"line":604},[84,1815,1816],{"class":655},"const",[84,1818,979],{"class":98},[84,1820,861],{"class":94},[84,1822,1801],{"class":607},[84,1824,610],{"class":98},[84,1826,1641],{"class":94},[84,1828,740],{"class":98},[84,1830,1831,1833,1835],{"class":86,"line":616},[84,1832,1051],{"class":94},[84,1834,855],{"class":619},[84,1836,872],{"class":94},[84,1838,1839],{"class":86,"line":637},[84,1840,601],{"emptyLinePlaceholder":600},[84,1842,1843,1845,1848],{"class":86,"line":681},[84,1844,852],{"class":94},[84,1846,1847],{"class":619},"template",[84,1849,872],{"class":94},[84,1851,1852,1855,1857,1859,1861,1863,1866,1868,1870,1872,1874,1877,1879],{"class":86,"line":699},[84,1853,1854],{"class":94},"  \u003C",[84,1856,180],{"class":619},[84,1858,1801],{"class":655},[84,1860,861],{"class":94},[84,1862,864],{"class":94},[84,1864,1865],{"class":137},"player",[84,1867,864],{"class":94},[84,1869,1250],{"class":655},[84,1871,861],{"class":94},[84,1873,864],{"class":94},[84,1875,1876],{"class":137},"...",[84,1878,864],{"class":94},[84,1880,1881],{"class":94}," \u002F>\n",[84,1883,1884,1886,1889,1892,1894,1896,1899,1901,1904,1907,1909,1911],{"class":86,"line":734},[84,1885,1854],{"class":94},[84,1887,1888],{"class":619},"button",[84,1890,1891],{"class":655}," @click",[84,1893,861],{"class":94},[84,1895,864],{"class":94},[84,1897,1898],{"class":137},"player.retry()",[84,1900,864],{"class":94},[84,1902,1903],{"class":94},">",[84,1905,1906],{"class":98},"Retry",[84,1908,1051],{"class":94},[84,1910,1888],{"class":619},[84,1912,872],{"class":94},[84,1914,1916,1918,1920],{"class":86,"line":1915},9,[84,1917,1051],{"class":94},[84,1919,1847],{"class":619},[84,1921,872],{"class":94},[155,1923,1924,1933],{},[158,1925,1926],{},[161,1927,1928,1931],{},[164,1929,1930],{},"Method",[164,1932,169],{},[171,1934,1935,1945,1965,1975,1989,1999,2012,2025,2041,2057,2070],{},[161,1936,1937,1942],{},[176,1938,1939],{},[81,1940,1941],{},"togglePlay()",[176,1943,1944],{},"Play\u002Fpause",[161,1946,1947,1952],{},[176,1948,1949],{},[81,1950,1951],{},"seek(percent)",[176,1953,1954,1955,1324,1958,1961,1962],{},"Seek to a percentage (",[81,1956,1957],{},"0",[81,1959,1960],{},"100",") of the video's duration - for an absolute time, pass ",[81,1963,1964],{},"(seconds \u002F total) * 100",[161,1966,1967,1972],{},[176,1968,1969],{},[81,1970,1971],{},"toggleMute()",[176,1973,1974],{},"Toggle mute",[161,1976,1977,1982],{},[176,1978,1979],{},[81,1980,1981],{},"setVolume(level)",[176,1983,1984,1985,1324,1987],{},"Set volume, ",[81,1986,1957],{},[81,1988,1520],{},[161,1990,1991,1996],{},[176,1992,1993],{},[81,1994,1995],{},"toggleFullscreen()",[176,1997,1998],{},"Enter\u002Fexit fullscreen",[161,2000,2001,2006],{},[176,2002,2003],{},[81,2004,2005],{},"toggleLoop()",[176,2007,2008,2009],{},"Toggle loop - fires ",[81,2010,2011],{},"loopchange",[161,2013,2014,2019],{},[176,2015,2016],{},[81,2017,2018],{},"setPlaybackRate(rate)",[176,2020,2021,2022],{},"Change playback speed - fires ",[81,2023,2024],{},"ratechange",[161,2026,2027,2032],{},[176,2028,2029],{},[81,2030,2031],{},"setCaptionTrack(index)",[176,2033,2034,2035,2037,2038],{},"Select a caption track by index, or ",[81,2036,1641],{}," to turn captions off - fires ",[81,2039,2040],{},"captionchange",[161,2042,2043,2048],{},[176,2044,2045],{},[81,2046,2047],{},"setQuality(index)",[176,2049,2050,2051,2053,2054],{},"Select a quality level by index, or ",[81,2052,1641],{}," for Auto - fires ",[81,2055,2056],{},"qualitychange",[161,2058,2059,2064],{},[176,2060,2061],{},[81,2062,2063],{},"togglePip()",[176,2065,2066,2067],{},"Enter\u002Fexit Picture-in-Picture - fires ",[81,2068,2069],{},"pipchange",[161,2071,2072,2077],{},[176,2073,2074],{},[81,2075,2076],{},"retry()",[176,2078,2079,2080],{},"Re-attempts loading the current source after an ",[81,2081,2082],{},"error",[69,2084,1766,2086,357,2088,652],{"id":2085},"template-ref-methods-videocard-and-videostage",[81,2087,190],{},[81,2089,200],{},[286,2091,2092,357,2094,2096,2097,2099,2100,300,2103,2106],{},[81,2093,190],{},[81,2095,200],{}," both forward the same controls\u002Fstate as ",[81,2098,180],{}," above (everything except the internal ",[81,2101,2102],{},"fire",[81,2104,2105],{},"fmt"," helpers), so a template ref on either works the same way:",[74,2108,2110],{"className":1777,"code":2109,"language":1779,"meta":79,"style":79},"\u003Cscript setup>\nimport { ref } from 'vue'\nconst item = ref(null)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CVideoCard ref=\"item\" src=\"...\" lazy \u002F>\n  \u003Cbutton @click=\"item.togglePlay()\">Play\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n",[81,2111,2112,2122,2140,2157,2165,2169,2177,2209,2237],{"__ignoreMap":79},[84,2113,2114,2116,2118,2120],{"class":86,"line":87},[84,2115,852],{"class":94},[84,2117,855],{"class":619},[84,2119,1790],{"class":655},[84,2121,872],{"class":94},[84,2123,2124,2126,2128,2130,2132,2134,2136,2138],{"class":86,"line":144},[84,2125,91],{"class":90},[84,2127,95],{"class":94},[84,2129,1801],{"class":98},[84,2131,128],{"class":94},[84,2133,131],{"class":90},[84,2135,134],{"class":94},[84,2137,1779],{"class":137},[84,2139,141],{"class":94},[84,2141,2142,2144,2147,2149,2151,2153,2155],{"class":86,"line":604},[84,2143,1816],{"class":655},[84,2145,2146],{"class":98}," item ",[84,2148,861],{"class":94},[84,2150,1801],{"class":607},[84,2152,610],{"class":98},[84,2154,1641],{"class":94},[84,2156,740],{"class":98},[84,2158,2159,2161,2163],{"class":86,"line":616},[84,2160,1051],{"class":94},[84,2162,855],{"class":619},[84,2164,872],{"class":94},[84,2166,2167],{"class":86,"line":637},[84,2168,601],{"emptyLinePlaceholder":600},[84,2170,2171,2173,2175],{"class":86,"line":681},[84,2172,852],{"class":94},[84,2174,1847],{"class":619},[84,2176,872],{"class":94},[84,2178,2179,2181,2183,2185,2187,2189,2192,2194,2196,2198,2200,2202,2204,2207],{"class":86,"line":699},[84,2180,1854],{"class":94},[84,2182,190],{"class":619},[84,2184,1801],{"class":655},[84,2186,861],{"class":94},[84,2188,864],{"class":94},[84,2190,2191],{"class":137},"item",[84,2193,864],{"class":94},[84,2195,1250],{"class":655},[84,2197,861],{"class":94},[84,2199,864],{"class":94},[84,2201,1876],{"class":137},[84,2203,864],{"class":94},[84,2205,2206],{"class":655}," lazy",[84,2208,1881],{"class":94},[84,2210,2211,2213,2215,2217,2219,2221,2224,2226,2228,2231,2233,2235],{"class":86,"line":734},[84,2212,1854],{"class":94},[84,2214,1888],{"class":619},[84,2216,1891],{"class":655},[84,2218,861],{"class":94},[84,2220,864],{"class":94},[84,2222,2223],{"class":137},"item.togglePlay()",[84,2225,864],{"class":94},[84,2227,1903],{"class":94},[84,2229,2230],{"class":98},"Play",[84,2232,1051],{"class":94},[84,2234,1888],{"class":619},[84,2236,872],{"class":94},[84,2238,2239,2241,2243],{"class":86,"line":1915},[84,2240,1051],{"class":94},[84,2242,1847],{"class":619},[84,2244,872],{"class":94},[286,2246,2247],{},"The forwarding differs slightly by how each component owns (or doesn't own) the underlying player:",[745,2249,2250,2266],{},[388,2251,2252,2256,2257,2259,2260,2262,2263,2265],{},[391,2253,2254],{},[81,2255,190],{}," may still be showing its lazy placeholder when the ref is used - calling any control method mounts the real player first if needed. When a ",[81,2258,200],{}," is present on the page, ",[81,2261,190],{}," hands playback off to it entirely instead: ",[81,2264,1941],{}," selects\u002Ftoggles this video on the stage, and every other method is a no-op since the stage owns the actual player.",[388,2267,2268,2272,2273,345,2276,345,2279,2282,2283,2286,2287,2290,2291,2293,2294,2297],{},[391,2269,2270],{},[81,2271,200],{}," additionally exposes ",[81,2274,2275],{},"playNext()",[81,2277,2278],{},"playPrevious()",[81,2280,2281],{},"hasNext",", and ",[81,2284,2285],{},"hasPrevious"," when a ",[81,2288,2289],{},"playlist"," prop is set. Unlike ",[81,2292,190],{},", it can't auto-mount a player without a video already selected (via a playlist entry or ",[81,2295,2296],{},"onVideoSelect",") - calling a control method before that is a no-op.",[286,2299,2300,2301,2304,2305,300,2308,300,2310,2312],{},"Because this forwarding is wired up via ",[81,2302,2303],{},"defineExpose",", the same methods\u002Fstate are available identically whether you're holding a Vue template ref or a DOM reference to the ",[81,2306,2307],{},"ml-video-card",[81,2309,303],{},[81,2311,299],{}," custom-element form:",[74,2314,2318],{"className":2315,"code":2316,"language":2317,"meta":79,"style":79},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","document.querySelector('ml-video-card').togglePlay()\n","js",[81,2319,2320],{"__ignoreMap":79},[84,2321,2322,2325,2327,2330,2332,2334,2336,2338,2340,2342,2345],{"class":86,"line":87},[84,2323,2324],{"class":98},"document",[84,2326,662],{"class":94},[84,2328,2329],{"class":607},"querySelector",[84,2331,610],{"class":98},[84,2333,631],{"class":94},[84,2335,2307],{"class":137},[84,2337,631],{"class":94},[84,2339,652],{"class":98},[84,2341,662],{"class":94},[84,2343,2344],{"class":607},"togglePlay",[84,2346,1229],{"class":98},[69,2348,2350],{"id":2349},"hiding-the-pinned-stage-over-content","Hiding the pinned stage over content",[286,2352,2353,2354,2356,2357,2359,2360,2363,2364,2366],{},"When ",[81,2355,200],{}," is pinned to a corner (any ",[81,2358,1726],{}," other than ",[81,2361,2362],{},"'full-width'","), ",[81,2365,275],{}," lets you keep it from covering a specific section of the page - a footer, a signup form, a comments block. Place it just before that content: the stage slides mostly off-screen (leaving a small sliver) for as long as the marker is in the viewport, and slides back once it isn't.",[74,2368,2370],{"className":1777,"code":2369,"language":1779,"meta":79,"style":79},"\u003CVideoStage pin=\"bottom-right\" :playlist=\"videos\" \u002F>\n\n\u003C!-- ...page content... -->\n\n\u003CHideMarker \u002F>\n\u003CFooter \u002F>\n",[81,2371,2372,2406,2410,2415,2419,2427],{"__ignoreMap":79},[84,2373,2374,2376,2378,2381,2383,2385,2388,2390,2393,2395,2397,2399,2402,2404],{"class":86,"line":87},[84,2375,852],{"class":94},[84,2377,200],{"class":619},[84,2379,2380],{"class":655}," pin",[84,2382,861],{"class":94},[84,2384,864],{"class":94},[84,2386,2387],{"class":137},"bottom-right",[84,2389,864],{"class":94},[84,2391,2392],{"class":94}," :",[84,2394,2289],{"class":655},[84,2396,861],{"class":94},[84,2398,864],{"class":94},[84,2400,2401],{"class":98},"videos",[84,2403,864],{"class":94},[84,2405,1881],{"class":94},[84,2407,2408],{"class":86,"line":144},[84,2409,601],{"emptyLinePlaceholder":600},[84,2411,2412],{"class":86,"line":604},[84,2413,2414],{"class":695},"\u003C!-- ...page content... -->\n",[84,2416,2417],{"class":86,"line":616},[84,2418,601],{"emptyLinePlaceholder":600},[84,2420,2421,2423,2425],{"class":86,"line":637},[84,2422,852],{"class":94},[84,2424,275],{"class":619},[84,2426,1881],{"class":94},[84,2428,2429,2431,2434],{"class":86,"line":681},[84,2430,852],{"class":94},[84,2432,2433],{"class":619},"Footer",[84,2435,1881],{"class":94},[286,2437,2438,2439,2441,2442,2444,2445,2447,2448,2451,2452,2455,2456,474],{},"There's no prop linking ",[81,2440,275],{}," to a specific stage - there's only ever one ",[81,2443,200],{}," on a page, so it always applies to whichever one is mounted. It renders a single, unstyled, full-width ",[81,2446,441],{}," with ",[81,2449,2450],{},"min-height: 1px"," and no slot for content, so it triggers briefly as the page scrolls past that exact line rather than staying active for as long as some section below it remains visible - place it precisely where you want the stage to tuck away. The sliver width is a CSS custom property: ",[81,2453,2454],{},"--mlv-stage-tuck"," (default ",[81,2457,2458],{},"32px",[373,2460,2462],{"id":2461},"useforwardedplayer",[81,2463,2464],{},"useForwardedPlayer",[286,2466,2467,2468,2470,2471,2473,2474,300,2476,300,2478,2480],{},"Builds your own wrapper component the same way - a curated forward of a template-ref'd ",[81,2469,180],{},"'s controls\u002Fstate for your own ",[81,2472,2303],{},", so a consumer of your wrapper gets the exact same API as a direct ",[81,2475,180],{},[81,2477,190],{},[81,2479,200],{}," ref (or custom-element reference):",[74,2482,2484],{"className":1777,"code":2483,"language":1779,"meta":79,"style":79},"\u003Cscript setup>\nimport { VideoPlayer, useForwardedPlayer } from '@munsonlabs\u002Fvideo-player'\nconst { playerRef, forwarded } = useForwardedPlayer()\ndefineExpose(forwarded)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CVideoPlayer ref=\"playerRef\" src=\"...\" \u002F>\n\u003C\u002Ftemplate>\n",[81,2485,2486,2496,2519,2542,2549,2557,2561,2569,2598],{"__ignoreMap":79},[84,2487,2488,2490,2492,2494],{"class":86,"line":87},[84,2489,852],{"class":94},[84,2491,855],{"class":619},[84,2493,1790],{"class":655},[84,2495,872],{"class":94},[84,2497,2498,2500,2502,2504,2506,2509,2511,2513,2515,2517],{"class":86,"line":144},[84,2499,91],{"class":90},[84,2501,95],{"class":94},[84,2503,99],{"class":98},[84,2505,102],{"class":94},[84,2507,2508],{"class":98}," useForwardedPlayer",[84,2510,128],{"class":94},[84,2512,131],{"class":90},[84,2514,134],{"class":94},[84,2516,138],{"class":137},[84,2518,141],{"class":94},[84,2520,2521,2523,2525,2528,2530,2533,2535,2538,2540],{"class":86,"line":604},[84,2522,1816],{"class":655},[84,2524,95],{"class":94},[84,2526,2527],{"class":98}," playerRef",[84,2529,102],{"class":94},[84,2531,2532],{"class":98}," forwarded ",[84,2534,737],{"class":94},[84,2536,2537],{"class":94}," =",[84,2539,2508],{"class":607},[84,2541,1229],{"class":98},[84,2543,2544,2546],{"class":86,"line":616},[84,2545,2303],{"class":607},[84,2547,2548],{"class":98},"(forwarded)\n",[84,2550,2551,2553,2555],{"class":86,"line":637},[84,2552,1051],{"class":94},[84,2554,855],{"class":619},[84,2556,872],{"class":94},[84,2558,2559],{"class":86,"line":681},[84,2560,601],{"emptyLinePlaceholder":600},[84,2562,2563,2565,2567],{"class":86,"line":699},[84,2564,852],{"class":94},[84,2566,1847],{"class":619},[84,2568,872],{"class":94},[84,2570,2571,2573,2575,2577,2579,2581,2584,2586,2588,2590,2592,2594,2596],{"class":86,"line":734},[84,2572,1854],{"class":94},[84,2574,180],{"class":619},[84,2576,1801],{"class":655},[84,2578,861],{"class":94},[84,2580,864],{"class":94},[84,2582,2583],{"class":137},"playerRef",[84,2585,864],{"class":94},[84,2587,1250],{"class":655},[84,2589,861],{"class":94},[84,2591,864],{"class":94},[84,2593,1876],{"class":137},[84,2595,864],{"class":94},[84,2597,1881],{"class":94},[84,2599,2600,2602,2604],{"class":86,"line":1915},[84,2601,1051],{"class":94},[84,2603,1847],{"class":619},[84,2605,872],{"class":94},[286,2607,2608,2610,2611,2613,2614,2616,2617,2620,2621,2623,2624,2627,2628,2630,2631,662],{},[81,2609,2464],{}," owns the ref itself - bind ",[81,2612,2583],{}," on the wrapped ",[81,2615,180],{}," and spread (or pass) ",[81,2618,2619],{},"forwarded"," into your own ",[81,2622,2303],{},". Pass a ",[81,2625,2626],{},"guard"," callback to intercept a method call before it reaches the underlying player - return ",[81,2629,1412],{}," to swallow it, or run a side effect (e.g. mounting a lazy placeholder first) before returning ",[81,2632,1464],{},[373,2634,2636],{"id":2635},"exposeplayeronelement",[81,2637,2638],{},"exposePlayerOnElement",[286,2640,2641,2642,300,2645,300,2648,2651,2652,2655],{},"Copies a plain Vue ",[81,2643,2644],{},"\u003CVideoPlayer>",[81,2646,2647],{},"\u003CVideoCard>",[81,2649,2650],{},"\u003CVideoStage>","'s exposed API directly onto a real DOM element, so code with no access to your Vue app's internals - a third party's own script, a ",[81,2653,2654],{},"\u003Cml-controls-*>"," custom element from a completely separate bundle - can read\u002Fcall it the same way it would on a genuine custom element:",[74,2657,2659],{"className":1777,"code":2658,"language":1779,"meta":79,"style":79},"\u003Cscript setup>\nimport { ref, onMounted } from 'vue'\nimport { VideoPlayer, exposePlayerOnElement } from '@munsonlabs\u002Fvideo-player'\nconst playerRef = ref(null)\nconst wrapperEl = ref(null)\nonMounted(() => exposePlayerOnElement(wrapperEl.value, playerRef.value))\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv id=\"my-player\" ref=\"wrapperEl\">\n    \u003CVideoPlayer ref=\"playerRef\" src=\"...\" \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[81,2660,2661,2671,2694,2717,2734,2751,2782,2790,2794,2802,2835,2865,2875],{"__ignoreMap":79},[84,2662,2663,2665,2667,2669],{"class":86,"line":87},[84,2664,852],{"class":94},[84,2666,855],{"class":619},[84,2668,1790],{"class":655},[84,2670,872],{"class":94},[84,2672,2673,2675,2677,2679,2681,2684,2686,2688,2690,2692],{"class":86,"line":144},[84,2674,91],{"class":90},[84,2676,95],{"class":94},[84,2678,1801],{"class":98},[84,2680,102],{"class":94},[84,2682,2683],{"class":98}," onMounted",[84,2685,128],{"class":94},[84,2687,131],{"class":90},[84,2689,134],{"class":94},[84,2691,1779],{"class":137},[84,2693,141],{"class":94},[84,2695,2696,2698,2700,2702,2704,2707,2709,2711,2713,2715],{"class":86,"line":604},[84,2697,91],{"class":90},[84,2699,95],{"class":94},[84,2701,99],{"class":98},[84,2703,102],{"class":94},[84,2705,2706],{"class":98}," exposePlayerOnElement",[84,2708,128],{"class":94},[84,2710,131],{"class":90},[84,2712,134],{"class":94},[84,2714,138],{"class":137},[84,2716,141],{"class":94},[84,2718,2719,2721,2724,2726,2728,2730,2732],{"class":86,"line":616},[84,2720,1816],{"class":655},[84,2722,2723],{"class":98}," playerRef ",[84,2725,861],{"class":94},[84,2727,1801],{"class":607},[84,2729,610],{"class":98},[84,2731,1641],{"class":94},[84,2733,740],{"class":98},[84,2735,2736,2738,2741,2743,2745,2747,2749],{"class":86,"line":637},[84,2737,1816],{"class":655},[84,2739,2740],{"class":98}," wrapperEl ",[84,2742,861],{"class":94},[84,2744,1801],{"class":607},[84,2746,610],{"class":98},[84,2748,1641],{"class":94},[84,2750,740],{"class":98},[84,2752,2753,2756,2758,2761,2763,2765,2768,2770,2773,2775,2777,2779],{"class":86,"line":681},[84,2754,2755],{"class":607},"onMounted",[84,2757,610],{"class":98},[84,2759,2760],{"class":94},"()",[84,2762,656],{"class":655},[84,2764,2706],{"class":607},[84,2766,2767],{"class":98},"(wrapperEl",[84,2769,662],{"class":94},[84,2771,2772],{"class":98},"value",[84,2774,102],{"class":94},[84,2776,2527],{"class":98},[84,2778,662],{"class":94},[84,2780,2781],{"class":98},"value))\n",[84,2783,2784,2786,2788],{"class":86,"line":699},[84,2785,1051],{"class":94},[84,2787,855],{"class":619},[84,2789,872],{"class":94},[84,2791,2792],{"class":86,"line":734},[84,2793,601],{"emptyLinePlaceholder":600},[84,2795,2796,2798,2800],{"class":86,"line":1915},[84,2797,852],{"class":94},[84,2799,1847],{"class":619},[84,2801,872],{"class":94},[84,2803,2805,2807,2810,2813,2815,2817,2820,2822,2824,2826,2828,2831,2833],{"class":86,"line":2804},10,[84,2806,1854],{"class":94},[84,2808,2809],{"class":619},"div",[84,2811,2812],{"class":655}," id",[84,2814,861],{"class":94},[84,2816,864],{"class":94},[84,2818,2819],{"class":137},"my-player",[84,2821,864],{"class":94},[84,2823,1801],{"class":655},[84,2825,861],{"class":94},[84,2827,864],{"class":94},[84,2829,2830],{"class":137},"wrapperEl",[84,2832,864],{"class":94},[84,2834,872],{"class":94},[84,2836,2838,2841,2843,2845,2847,2849,2851,2853,2855,2857,2859,2861,2863],{"class":86,"line":2837},11,[84,2839,2840],{"class":94},"    \u003C",[84,2842,180],{"class":619},[84,2844,1801],{"class":655},[84,2846,861],{"class":94},[84,2848,864],{"class":94},[84,2850,2583],{"class":137},[84,2852,864],{"class":94},[84,2854,1250],{"class":655},[84,2856,861],{"class":94},[84,2858,864],{"class":94},[84,2860,1876],{"class":137},[84,2862,864],{"class":94},[84,2864,1881],{"class":94},[84,2866,2868,2871,2873],{"class":86,"line":2867},12,[84,2869,2870],{"class":94},"  \u003C\u002F",[84,2872,2809],{"class":619},[84,2874,872],{"class":94},[84,2876,2878,2880,2882],{"class":86,"line":2877},13,[84,2879,1051],{"class":94},[84,2881,1847],{"class":619},[84,2883,872],{"class":94},[74,2885,2887],{"className":843,"code":2886,"language":845,"meta":79,"style":79},"\u003C!-- a completely separate script\u002Fbundle, e.g. a third party's own -->\n\u003Cscript type=\"module\">\n  import '@munsonlabs\u002Fvideo-player\u002Felement\u002Fcontrols'\n\u003C\u002Fscript>\n\u003Cml-controls-transcript for=\"my-player\" cues='[{\"time\":0,\"text\":\"...\"}]'>\u003C\u002Fml-controls-transcript>\n",[81,2888,2889,2894,2912,2922,2930],{"__ignoreMap":79},[84,2890,2891],{"class":86,"line":87},[84,2892,2893],{"class":695},"\u003C!-- a completely separate script\u002Fbundle, e.g. a third party's own -->\n",[84,2895,2896,2898,2900,2902,2904,2906,2908,2910],{"class":86,"line":144},[84,2897,852],{"class":94},[84,2899,855],{"class":619},[84,2901,858],{"class":655},[84,2903,861],{"class":94},[84,2905,864],{"class":94},[84,2907,867],{"class":137},[84,2909,864],{"class":94},[84,2911,872],{"class":94},[84,2913,2914,2916,2918,2920],{"class":86,"line":604},[84,2915,877],{"class":90},[84,2917,134],{"class":94},[84,2919,337],{"class":137},[84,2921,141],{"class":94},[84,2923,2924,2926,2928],{"class":86,"line":616},[84,2925,1051],{"class":94},[84,2927,855],{"class":619},[84,2929,872],{"class":94},[84,2931,2932,2934,2937,2940,2942,2944,2946,2948,2951,2953,2955,2958,2960,2962,2964],{"class":86,"line":637},[84,2933,852],{"class":94},[84,2935,2936],{"class":619},"ml-controls-transcript",[84,2938,2939],{"class":655}," for",[84,2941,861],{"class":94},[84,2943,864],{"class":94},[84,2945,2819],{"class":137},[84,2947,864],{"class":94},[84,2949,2950],{"class":655}," cues",[84,2952,861],{"class":94},[84,2954,631],{"class":94},[84,2956,2957],{"class":137},"[{\"time\":0,\"text\":\"...\"}]",[84,2959,631],{"class":94},[84,2961,1261],{"class":94},[84,2963,2936],{"class":619},[84,2965,872],{"class":94},[745,2967,2968,2978,2989],{},[388,2969,2970,2971,300,2974,2977],{},"State fields are copied as live getters, not snapshotted values - ",[81,2972,2973],{},"el.current",[81,2975,2976],{},"el.isPlaying"," etc. keep reflecting the real player for as long as it's mounted, the same as reading them off a template ref would. Methods are copied directly (they already close over the real player internally, so there's nothing to keep \"live\" there).",[388,2979,2980,2982,2983,2985,2986,2988],{},[81,2981,459],{}," doesn't need to be the player's own root element - a wrapper ",[81,2984,441],{}," (as above), or any other element entirely, works exactly the same; ",[81,2987,2638],{}," only cares about the element you hand it.",[388,2990,2991,2992,2995,2996,2998,2999,3001],{},"This has nothing to do with the ",[81,2993,2994],{},"\u002Felement*"," bundles or custom elements on the ",[468,2997,1865],{}," side - you're still rendering a plain Vue ",[81,3000,2644],{},". It's purely about making that player's state reachable from outside your Vue app, for whoever needs to reach it.",[69,3003,3005],{"id":3004},"headless-controls","Headless controls",[286,3007,3008,3009,3011,3012,3014],{},"Unstyled control primitives for building a custom HUD - each is a single component, published both as a Vue component and as a ",[81,3010,322],{}," custom element from the exact same source (no duplicated logic), the same way ",[81,3013,180],{}," itself is.",[286,3016,3017,3018,3020,3021,3023,3024,3026,3027,3031],{},"As Vue components they're part of the main ",[81,3019,138],{}," import - nothing extra to install. As custom elements they're part of ",[81,3022,291],{}," (or the smaller ",[81,3025,337],{},", if you don't need the core player tags too) - see ",[265,3028,3030],{"href":3029},"#custom-element-non-vue-usage","Custom-element usage"," below.",[74,3033,3035],{"className":76,"code":3034,"language":78,"meta":79,"style":79},"import {\n  PlayButton, MuteButton, FullscreenButton, LoopButton, PipButton,\n  CaptionsButton, QualityButton, PlaybackRateButton, Buffering, Scrubber,\n  VolumeSlider, TimeDisplay, Transcript,\n} from '@munsonlabs\u002Fvideo-player'\n",[81,3036,3037,3044,3071,3098,3115],{"__ignoreMap":79},[84,3038,3039,3041],{"class":86,"line":87},[84,3040,91],{"class":90},[84,3042,3043],{"class":94}," {\n",[84,3045,3046,3049,3051,3054,3056,3059,3061,3064,3066,3069],{"class":86,"line":144},[84,3047,3048],{"class":98},"  PlayButton",[84,3050,102],{"class":94},[84,3052,3053],{"class":98}," MuteButton",[84,3055,102],{"class":94},[84,3057,3058],{"class":98}," FullscreenButton",[84,3060,102],{"class":94},[84,3062,3063],{"class":98}," LoopButton",[84,3065,102],{"class":94},[84,3067,3068],{"class":98}," PipButton",[84,3070,634],{"class":94},[84,3072,3073,3076,3078,3081,3083,3086,3088,3091,3093,3096],{"class":86,"line":604},[84,3074,3075],{"class":98},"  CaptionsButton",[84,3077,102],{"class":94},[84,3079,3080],{"class":98}," QualityButton",[84,3082,102],{"class":94},[84,3084,3085],{"class":98}," PlaybackRateButton",[84,3087,102],{"class":94},[84,3089,3090],{"class":98}," Buffering",[84,3092,102],{"class":94},[84,3094,3095],{"class":98}," Scrubber",[84,3097,634],{"class":94},[84,3099,3100,3103,3105,3108,3110,3113],{"class":86,"line":616},[84,3101,3102],{"class":98},"  VolumeSlider",[84,3104,102],{"class":94},[84,3106,3107],{"class":98}," TimeDisplay",[84,3109,102],{"class":94},[84,3111,3112],{"class":98}," Transcript",[84,3114,634],{"class":94},[84,3116,3117,3119,3121,3123,3125],{"class":86,"line":637},[84,3118,737],{"class":94},[84,3120,131],{"class":90},[84,3122,134],{"class":94},[84,3124,138],{"class":137},[84,3126,141],{"class":94},[155,3128,3129,3141],{},[158,3130,3131],{},[161,3132,3133,3136,3139],{},[164,3134,3135],{},"Component",[164,3137,3138],{},"Custom element",[164,3140,169],{},[171,3142,3143,3158,3173,3188,3203,3221,3238,3256,3274,3292,3311,3329,3364],{},[161,3144,3145,3150,3155],{},[176,3146,3147],{},[81,3148,3149],{},"PlayButton",[176,3151,3152],{},[81,3153,3154],{},"\u003Cml-controls-play-button>",[176,3156,3157],{},"Toggles play\u002Fpause",[161,3159,3160,3165,3170],{},[176,3161,3162],{},[81,3163,3164],{},"MuteButton",[176,3166,3167],{},[81,3168,3169],{},"\u003Cml-controls-mute-button>",[176,3171,3172],{},"Toggles mute",[161,3174,3175,3180,3185],{},[176,3176,3177],{},[81,3178,3179],{},"FullscreenButton",[176,3181,3182],{},[81,3183,3184],{},"\u003Cml-controls-fullscreen-button>",[176,3186,3187],{},"Toggles fullscreen",[161,3189,3190,3195,3200],{},[176,3191,3192],{},[81,3193,3194],{},"LoopButton",[176,3196,3197],{},[81,3198,3199],{},"\u003Cml-controls-loop-button>",[176,3201,3202],{},"Toggles loop",[161,3204,3205,3210,3215],{},[176,3206,3207],{},[81,3208,3209],{},"PipButton",[176,3211,3212],{},[81,3213,3214],{},"\u003Cml-controls-pip-button>",[176,3216,3217,3218],{},"Toggles Picture-in-Picture - only renders when ",[81,3219,3220],{},"supportsPip",[161,3222,3223,3228,3233],{},[176,3224,3225],{},[81,3226,3227],{},"CaptionsButton",[176,3229,3230],{},[81,3231,3232],{},"\u003Cml-controls-captions-button>",[176,3234,3235,3236],{},"Cycles Off → track 1 → ... → Off - only renders when ",[81,3237,518],{},[161,3239,3240,3245,3250],{},[176,3241,3242],{},[81,3243,3244],{},"QualityButton",[176,3246,3247],{},[81,3248,3249],{},"\u003Cml-controls-quality-button>",[176,3251,3252,3253],{},"Cycles Auto → highest → ... → lowest → Auto - only renders when ",[81,3254,3255],{},"supportsQuality",[161,3257,3258,3263,3268],{},[176,3259,3260],{},[81,3261,3262],{},"PlaybackRateButton",[176,3264,3265],{},[81,3266,3267],{},"\u003Cml-controls-playback-rate-button>",[176,3269,3270,3271],{},"Cycles through ",[81,3272,3273],{},"[0.5, 0.75, 1, 1.25, 1.5, 2]",[161,3275,3276,3281,3286],{},[176,3277,3278],{},[81,3279,3280],{},"Buffering",[176,3282,3283],{},[81,3284,3285],{},"\u003Cml-controls-buffering>",[176,3287,3288,3289],{},"Renders its content only while ",[81,3290,3291],{},"isBuffering",[161,3293,3294,3299,3304],{},[176,3295,3296],{},[81,3297,3298],{},"Scrubber",[176,3300,3301],{},[81,3302,3303],{},"\u003Cml-controls-scrubber>",[176,3305,3306,3307,3310],{},"Drag-to-seek ",[81,3308,3309],{},"\u003Cinput type=\"range\">"," - pauses on drag start, shows a live time preview, commits and resumes on release",[161,3312,3313,3318,3323],{},[176,3314,3315],{},[81,3316,3317],{},"VolumeSlider",[176,3319,3320],{},[81,3321,3322],{},"\u003Cml-controls-volume-slider>",[176,3324,3325,3326,3328],{},"Drag-to-set-volume ",[81,3327,3309],{},", with a percentage readout",[161,3330,3331,3336,3341],{},[176,3332,3333],{},[81,3334,3335],{},"TimeDisplay",[176,3337,3338],{},[81,3339,3340],{},"\u003Cml-controls-time-display>",[176,3342,3343,3344,3347,3348,3351,3352,3355,3356,3359,3360,3363],{},"Shows ",[81,3345,3346],{},"current \u002F total"," (formatted), or a \"Live\" badge when ",[81,3349,3350],{},"isLive",". The default non-live render wraps the current time in ",[81,3353,3354],{},".mlv-time-display__time"," and the total in ",[81,3357,3358],{},".mlv-time-display__total"," for independent styling via ",[81,3361,3362],{},":where()"," selectors",[161,3365,3366,3371,3376],{},[176,3367,3368],{},[81,3369,3370],{},"Transcript",[176,3372,3373],{},[81,3374,3375],{},"\u003Cml-controls-transcript>",[176,3377,3378,3379,3382,3383,3386,3387,3390,3391,3394,3395],{},"Clickable transcript from a ",[81,3380,3381],{},"cues"," array (",[81,3384,3385],{},"{ time, end?, text }[]",", or an inline JSON string attribute) - clicking a cue seeks to its timestamp (starting playback if paused), the cue at the playhead is highlighted (",[81,3388,3389],{},"aria-current",") and kept scrolled into view, and a scoped slot (",[81,3392,3393],{},"{ cue, index, isActive, formatTime }",") customises each cue's markup. Works on every platform, embeds included - it only needs the current time and ",[81,3396,3397],{},"seek",[286,3399,3400,3401,3403,3404,300,3406,300,3408,3410],{},"Every control takes a ",[81,3402,1865],{}," prop pointing at the same object ",[81,3405,180],{},[81,3407,190],{},[81,3409,200],{}," expose via a template ref (or, for a raw custom element, the element itself - see below).",[373,3412,3414],{"id":3413},"vue-usage","Vue usage",[74,3416,3418],{"className":1777,"code":3417,"language":1779,"meta":79,"style":79},"\u003Cscript setup>\nimport { ref } from 'vue'\nimport { VideoPlayer, PlayButton, MuteButton, Scrubber } from '@munsonlabs\u002Fvideo-player'\nconst player = ref(null)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CVideoPlayer ref=\"player\" src=\"...\" :controls=\"false\" \u002F>\n  \u003CPlayButton :player=\"player\" \u002F>\n  \u003CMuteButton :player=\"player\" \u002F>\n  \u003CScrubber :player=\"player\" \u002F>\n\u003C\u002Ftemplate>\n",[81,3419,3420,3430,3448,3479,3495,3503,3507,3515,3555,3575,3595,3615],{"__ignoreMap":79},[84,3421,3422,3424,3426,3428],{"class":86,"line":87},[84,3423,852],{"class":94},[84,3425,855],{"class":619},[84,3427,1790],{"class":655},[84,3429,872],{"class":94},[84,3431,3432,3434,3436,3438,3440,3442,3444,3446],{"class":86,"line":144},[84,3433,91],{"class":90},[84,3435,95],{"class":94},[84,3437,1801],{"class":98},[84,3439,128],{"class":94},[84,3441,131],{"class":90},[84,3443,134],{"class":94},[84,3445,1779],{"class":137},[84,3447,141],{"class":94},[84,3449,3450,3452,3454,3456,3458,3461,3463,3465,3467,3469,3471,3473,3475,3477],{"class":86,"line":604},[84,3451,91],{"class":90},[84,3453,95],{"class":94},[84,3455,99],{"class":98},[84,3457,102],{"class":94},[84,3459,3460],{"class":98}," PlayButton",[84,3462,102],{"class":94},[84,3464,3053],{"class":98},[84,3466,102],{"class":94},[84,3468,3095],{"class":98},[84,3470,128],{"class":94},[84,3472,131],{"class":90},[84,3474,134],{"class":94},[84,3476,138],{"class":137},[84,3478,141],{"class":94},[84,3480,3481,3483,3485,3487,3489,3491,3493],{"class":86,"line":616},[84,3482,1816],{"class":655},[84,3484,979],{"class":98},[84,3486,861],{"class":94},[84,3488,1801],{"class":607},[84,3490,610],{"class":98},[84,3492,1641],{"class":94},[84,3494,740],{"class":98},[84,3496,3497,3499,3501],{"class":86,"line":637},[84,3498,1051],{"class":94},[84,3500,855],{"class":619},[84,3502,872],{"class":94},[84,3504,3505],{"class":86,"line":681},[84,3506,601],{"emptyLinePlaceholder":600},[84,3508,3509,3511,3513],{"class":86,"line":699},[84,3510,852],{"class":94},[84,3512,1847],{"class":619},[84,3514,872],{"class":94},[84,3516,3517,3519,3521,3523,3525,3527,3529,3531,3533,3535,3537,3539,3541,3543,3545,3547,3549,3551,3553],{"class":86,"line":734},[84,3518,1854],{"class":94},[84,3520,180],{"class":619},[84,3522,1801],{"class":655},[84,3524,861],{"class":94},[84,3526,864],{"class":94},[84,3528,1865],{"class":137},[84,3530,864],{"class":94},[84,3532,1250],{"class":655},[84,3534,861],{"class":94},[84,3536,864],{"class":94},[84,3538,1876],{"class":137},[84,3540,864],{"class":94},[84,3542,2392],{"class":94},[84,3544,1676],{"class":655},[84,3546,861],{"class":94},[84,3548,864],{"class":94},[84,3550,1412],{"class":689},[84,3552,864],{"class":94},[84,3554,1881],{"class":94},[84,3556,3557,3559,3561,3563,3565,3567,3569,3571,3573],{"class":86,"line":1915},[84,3558,1854],{"class":94},[84,3560,3149],{"class":619},[84,3562,2392],{"class":94},[84,3564,1865],{"class":655},[84,3566,861],{"class":94},[84,3568,864],{"class":94},[84,3570,1865],{"class":98},[84,3572,864],{"class":94},[84,3574,1881],{"class":94},[84,3576,3577,3579,3581,3583,3585,3587,3589,3591,3593],{"class":86,"line":2804},[84,3578,1854],{"class":94},[84,3580,3164],{"class":619},[84,3582,2392],{"class":94},[84,3584,1865],{"class":655},[84,3586,861],{"class":94},[84,3588,864],{"class":94},[84,3590,1865],{"class":98},[84,3592,864],{"class":94},[84,3594,1881],{"class":94},[84,3596,3597,3599,3601,3603,3605,3607,3609,3611,3613],{"class":86,"line":2837},[84,3598,1854],{"class":94},[84,3600,3298],{"class":619},[84,3602,2392],{"class":94},[84,3604,1865],{"class":655},[84,3606,861],{"class":94},[84,3608,864],{"class":94},[84,3610,1865],{"class":98},[84,3612,864],{"class":94},[84,3614,1881],{"class":94},[84,3616,3617,3619,3621],{"class":86,"line":2867},[84,3618,1051],{"class":94},[84,3620,1847],{"class":619},[84,3622,872],{"class":94},[286,3624,3625,3626,3629],{},"Or, ",[81,3627,3628],{},"\u003Clabel for>","-style, skip the ref and point at an element id instead - useful when the control isn't a sibling of the player, or you'd rather not thread a ref through:",[74,3631,3633],{"className":1777,"code":3632,"language":1779,"meta":79,"style":79},"\u003CVideoPlayer id=\"my-player\" src=\"...\" :controls=\"false\" \u002F>\n\u003CPlayButton for=\"my-player\" \u002F>\n",[81,3634,3635,3675],{"__ignoreMap":79},[84,3636,3637,3639,3641,3643,3645,3647,3649,3651,3653,3655,3657,3659,3661,3663,3665,3667,3669,3671,3673],{"class":86,"line":87},[84,3638,852],{"class":94},[84,3640,180],{"class":619},[84,3642,2812],{"class":655},[84,3644,861],{"class":94},[84,3646,864],{"class":94},[84,3648,2819],{"class":137},[84,3650,864],{"class":94},[84,3652,1250],{"class":655},[84,3654,861],{"class":94},[84,3656,864],{"class":94},[84,3658,1876],{"class":137},[84,3660,864],{"class":94},[84,3662,2392],{"class":94},[84,3664,1676],{"class":655},[84,3666,861],{"class":94},[84,3668,864],{"class":94},[84,3670,1412],{"class":689},[84,3672,864],{"class":94},[84,3674,1881],{"class":94},[84,3676,3677,3679,3681,3683,3685,3687,3689,3691],{"class":86,"line":144},[84,3678,852],{"class":94},[84,3680,3149],{"class":619},[84,3682,2939],{"class":655},[84,3684,861],{"class":94},[84,3686,864],{"class":94},[84,3688,2819],{"class":137},[84,3690,864],{"class":94},[84,3692,1881],{"class":94},[286,3694,3695,357,3697,3700,3701,3703,3704,3707],{},[81,3696,1865],{},[81,3698,3699],{},"for"," are both optional - if both are given, ",[81,3702,1865],{}," wins. Internally these look up ",[81,3705,3706],{},"document.getElementById(...)"," (this package never uses shadow DOM, so a plain id lookup is always correct, not just a shortcut).",[373,3709,3711],{"id":3710},"custom-element-non-vue-usage","Custom-element (non-Vue) usage",[74,3713,3715],{"className":843,"code":3714,"language":845,"meta":79,"style":79},"\u003Cscript type=\"module\">\n  import '@munsonlabs\u002Fvideo-player\u002Fstyle'\n  import '@munsonlabs\u002Fvideo-player\u002Felement'\n\u003C\u002Fscript>\n\n\u003Cml-video-player id=\"player\" src=\"...\">\u003C\u002Fml-video-player>\n\n\u003Cml-controls-play-button for=\"player\">\u003C\u002Fml-controls-play-button>\n\u003Cml-controls-mute-button for=\"player\">\u003C\u002Fml-controls-mute-button>\n\u003Cml-controls-scrubber for=\"player\" style=\"flex: 1\">\u003C\u002Fml-controls-scrubber>\n",[81,3716,3717,3735,3745,3755,3763,3767,3799,3803,3825,3848],{"__ignoreMap":79},[84,3718,3719,3721,3723,3725,3727,3729,3731,3733],{"class":86,"line":87},[84,3720,852],{"class":94},[84,3722,855],{"class":619},[84,3724,858],{"class":655},[84,3726,861],{"class":94},[84,3728,864],{"class":94},[84,3730,867],{"class":137},[84,3732,864],{"class":94},[84,3734,872],{"class":94},[84,3736,3737,3739,3741,3743],{"class":86,"line":144},[84,3738,877],{"class":90},[84,3740,134],{"class":94},[84,3742,151],{"class":137},[84,3744,141],{"class":94},[84,3746,3747,3749,3751,3753],{"class":86,"line":604},[84,3748,877],{"class":90},[84,3750,134],{"class":94},[84,3752,291],{"class":137},[84,3754,141],{"class":94},[84,3756,3757,3759,3761],{"class":86,"line":616},[84,3758,1051],{"class":94},[84,3760,855],{"class":619},[84,3762,872],{"class":94},[84,3764,3765],{"class":86,"line":637},[84,3766,601],{"emptyLinePlaceholder":600},[84,3768,3769,3771,3773,3775,3777,3779,3781,3783,3785,3787,3789,3791,3793,3795,3797],{"class":86,"line":681},[84,3770,852],{"class":94},[84,3772,299],{"class":619},[84,3774,2812],{"class":655},[84,3776,861],{"class":94},[84,3778,864],{"class":94},[84,3780,1865],{"class":137},[84,3782,864],{"class":94},[84,3784,1250],{"class":655},[84,3786,861],{"class":94},[84,3788,864],{"class":94},[84,3790,1876],{"class":137},[84,3792,864],{"class":94},[84,3794,1261],{"class":94},[84,3796,299],{"class":619},[84,3798,872],{"class":94},[84,3800,3801],{"class":86,"line":699},[84,3802,601],{"emptyLinePlaceholder":600},[84,3804,3805,3807,3809,3811,3813,3815,3817,3819,3821,3823],{"class":86,"line":734},[84,3806,852],{"class":94},[84,3808,318],{"class":619},[84,3810,2939],{"class":655},[84,3812,861],{"class":94},[84,3814,864],{"class":94},[84,3816,1865],{"class":137},[84,3818,864],{"class":94},[84,3820,1261],{"class":94},[84,3822,318],{"class":619},[84,3824,872],{"class":94},[84,3826,3827,3829,3832,3834,3836,3838,3840,3842,3844,3846],{"class":86,"line":1915},[84,3828,852],{"class":94},[84,3830,3831],{"class":619},"ml-controls-mute-button",[84,3833,2939],{"class":655},[84,3835,861],{"class":94},[84,3837,864],{"class":94},[84,3839,1865],{"class":137},[84,3841,864],{"class":94},[84,3843,1261],{"class":94},[84,3845,3831],{"class":619},[84,3847,872],{"class":94},[84,3849,3850,3852,3855,3857,3859,3861,3863,3865,3868,3870,3872,3875,3877,3879,3881],{"class":86,"line":2804},[84,3851,852],{"class":94},[84,3853,3854],{"class":619},"ml-controls-scrubber",[84,3856,2939],{"class":655},[84,3858,861],{"class":94},[84,3860,864],{"class":94},[84,3862,1865],{"class":137},[84,3864,864],{"class":94},[84,3866,3867],{"class":655}," style",[84,3869,861],{"class":94},[84,3871,864],{"class":94},[84,3873,3874],{"class":137},"flex: 1",[84,3876,864],{"class":94},[84,3878,1261],{"class":94},[84,3880,3854],{"class":619},[84,3882,872],{"class":94},[286,3884,3885,3888,3889,3892,3893,3896,3897,3899,3900,3902],{},[81,3886,3887],{},"for=\"player\""," is the zero-JS path - no ",[81,3890,3891],{},"\u003Cscript>"," needed for the wiring itself. The equivalent JS-property form (",[81,3894,3895],{},"el.player = document.getElementById('player')",") is only necessary when the two elements can't share a stable id (e.g. the player is created dynamically), since ",[81,3898,1865],{}," is an object reference, not a string, so it can't be written as a plain HTML attribute the way ",[81,3901,3699],{}," can.",[286,3904,3905,3906,3909,3910,3912,3913,3916],{},"Setting ",[81,3907,3908],{},"controls=\"false\""," on ",[81,3911,1080],{}," still has to go through a property too (",[81,3914,3915],{},"playerEl.controls = false","), for the same reason - it's a boolean prop, and HTML attributes are strings-only.",[373,3918,3920],{"id":3919},"styling","Styling",[286,3922,3923,3924,3926],{},"Every control's own CSS uses ",[81,3925,3362],{}," (zero specificity), so a single class you add always wins over the built-in default, regardless of source order.",[286,3928,3929,3932],{},[391,3930,3931],{},"In Vue",", a class fallthroughs onto the control's own root element like any single-root component:",[74,3934,3936],{"className":1777,"code":3935,"language":1779,"meta":79,"style":79},"\u003CPlayButton :player=\"player\" class=\"my-play-btn\" \u002F>\n",[81,3937,3938],{"__ignoreMap":79},[84,3939,3940,3942,3944,3946,3948,3950,3952,3954,3956,3959,3961,3963,3966,3968],{"class":86,"line":87},[84,3941,852],{"class":94},[84,3943,3149],{"class":619},[84,3945,2392],{"class":94},[84,3947,1865],{"class":655},[84,3949,861],{"class":94},[84,3951,864],{"class":94},[84,3953,1865],{"class":98},[84,3955,864],{"class":94},[84,3957,3958],{"class":655}," class",[84,3960,861],{"class":94},[84,3962,864],{"class":94},[84,3964,3965],{"class":137},"my-play-btn",[84,3967,864],{"class":94},[84,3969,1881],{"class":94},[286,3971,3972,3979,3980,3983,3984,3987,3988,3991,3992,3995],{},[391,3973,3974,3975,3978],{},"As a raw custom element, this does ",[468,3976,3977],{},"not"," work the same way."," A custom element is a real, persistent DOM node that Vue renders a child element ",[468,3981,3982],{},"into"," - ",[81,3985,3986],{},"class=\"...\""," set on ",[81,3989,3990],{},"\u003Cml-play-button>"," stays on that outer tag; it never reaches the ",[81,3993,3994],{},"\u003Cbutton>"," Vue renders inside it. Target the inner element with a descendant selector instead:",[74,3997,4001],{"className":3998,"code":3999,"language":4000,"meta":79,"style":79},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ml-controls-play-button button { color: red; }\n\u002F* or, using the built-in class: *\u002F\nml-controls-play-button .mlv-play-button { color: red; }\n","css",[81,4002,4003,4028,4033],{"__ignoreMap":79},[84,4004,4005,4008,4011,4013,4017,4019,4022,4025],{"class":86,"line":87},[84,4006,318],{"class":4007},"sBMFI",[84,4009,4010],{"class":4007}," button",[84,4012,95],{"class":94},[84,4014,4016],{"class":4015},"sqsOY"," color",[84,4018,623],{"class":94},[84,4020,4021],{"class":98}," red",[84,4023,4024],{"class":94},";",[84,4026,4027],{"class":94}," }\n",[84,4029,4030],{"class":86,"line":144},[84,4031,4032],{"class":695},"\u002F* or, using the built-in class: *\u002F\n",[84,4034,4035,4037,4040,4043,4045,4047,4049,4051,4053],{"class":86,"line":604},[84,4036,318],{"class":4007},[84,4038,4039],{"class":94}," .",[84,4041,4042],{"class":4007},"mlv-play-button",[84,4044,95],{"class":94},[84,4046,4016],{"class":4015},[84,4048,623],{"class":94},[84,4050,4021],{"class":98},[84,4052,4024],{"class":94},[84,4054,4027],{"class":94},[373,4056,4058],{"id":4057},"css-entry-points","CSS entry points",[155,4060,4061,4074],{},[158,4062,4063],{},[161,4064,4065,4068,4071],{},[164,4066,4067],{},"Import",[164,4069,4070],{},"Pairs with",[164,4072,4073],{},"Covers",[171,4075,4076,4090,4113],{},[161,4077,4078,4082,4087],{},[176,4079,4080],{},[81,4081,151],{},[176,4083,4084,4086],{},[81,4085,291],{}," (and plain Vue usage)",[176,4088,4089],{},"Everything - core player + all thirteen headless controls",[161,4091,4092,4097,4101],{},[176,4093,4094],{},[81,4095,4096],{},"@munsonlabs\u002Fvideo-player\u002Fstyle\u002Fcore",[176,4098,4099],{},[81,4100,333],{},[176,4102,4103,4104,300,4106,300,4108,300,4110,4112],{},"Just ",[81,4105,180],{},[81,4107,200],{},[81,4109,190],{},[81,4111,213],{},"'s own styles",[161,4114,4115,4120,4124],{},[176,4116,4117],{},[81,4118,4119],{},"@munsonlabs\u002Fvideo-player\u002Fstyle\u002Fcontrols",[176,4121,4122],{},[81,4123,337],{},[176,4125,4126],{},"Just the thirteen headless controls' own styles",[286,4128,4129,4130,4132,4133,4136,4137,357,4139,4141,4142,4145],{},"Only the combined ",[81,4131,344],{}," bundle auto-injects ",[81,4134,4135],{},"\u002Fstyle"," for you - ",[81,4138,348],{},[81,4140,351],{}," don't inject anything, so import the matching stylesheet yourself alongside whichever half you use. If you're building a fully custom HUD with the headless controls and never render the built-in one, ",[81,4143,4144],{},"\u002Fstyle\u002Fcontrols"," alone is enough - no need to ship the core player's CSS you're not using.",[373,4147,4149],{"id":4148},"themeable-css-variables","Themeable CSS variables",[286,4151,4152],{},"Override these from your own stylesheet to adjust layout without forking the player:",[155,4154,4155,4169],{},[158,4156,4157],{},[161,4158,4159,4162,4164,4167],{},[164,4160,4161],{},"Variable",[164,4163,1306],{},[164,4165,4166],{},"Used by",[164,4168,169],{},[171,4170,4171,4189,4215,4234,4251],{},[161,4172,4173,4178,4183,4186],{},[176,4174,4175],{},[81,4176,4177],{},"--mlv-controls-width",[176,4179,4180],{},[81,4181,4182],{},"min(450px, calc(100% - 32px))",[176,4184,4185],{},"Controls popup",[176,4187,4188],{},"Width of the expanded controls panel - widen it for a larger HUD, or narrow it for a tighter fit",[161,4190,4191,4196,4201,4203],{},[176,4192,4193],{},[81,4194,4195],{},"--mlv-popup-align",[176,4197,4198],{},[81,4199,4200],{},"center",[176,4202,4185],{},[176,4204,4205,4206,345,4208,345,4211,4214],{},"Horizontal alignment of the popup (",[81,4207,4200],{},[81,4209,4210],{},"left",[81,4212,4213],{},"right",", or any CSS alignment value)",[161,4216,4217,4221,4225,4228],{},[176,4218,4219],{},[81,4220,2454],{},[176,4222,4223],{},[81,4224,2458],{},[176,4226,4227],{},"Pinned stage \u002F player",[176,4229,4230,4231,4233],{},"Width of the sliver left visible when ",[81,4232,275],{}," tucks the pinned box off-screen",[161,4235,4236,4241,4246,4248],{},[176,4237,4238],{},[81,4239,4240],{},"--mlv-radius",[176,4242,4243],{},[81,4244,4245],{},"12px",[176,4247,4227],{},[176,4249,4250],{},"Border-radius of the corner-pinned box",[161,4252,4253,4258,4261,4264],{},[176,4254,4255],{},[81,4256,4257],{},"--mlv-accent",[176,4259,4260],{},"—",[176,4262,4263],{},"Controls \"More\" menu",[176,4265,4266],{},"Active-state highlight color for the loop and autoplay toggle buttons",[286,4268,4269],{},"Example - widening the controls popup:",[74,4271,4273],{"className":3998,"code":4272,"language":4000,"meta":79,"style":79},".mlv-controls { --mlv-controls-width: min(600px, calc(100% - 32px)); }\n",[81,4274,4275],{"__ignoreMap":79},[84,4276,4277,4279,4282,4284,4287,4289,4292,4294,4298,4300,4303,4305,4308,4311,4314,4317],{"class":86,"line":87},[84,4278,662],{"class":94},[84,4280,4281],{"class":4007},"mlv-controls",[84,4283,95],{"class":94},[84,4285,4286],{"class":98}," --mlv-controls-width",[84,4288,623],{"class":94},[84,4290,4291],{"class":607}," min",[84,4293,610],{"class":94},[84,4295,4297],{"class":4296},"sbssI","600px",[84,4299,102],{"class":94},[84,4301,4302],{"class":607}," calc",[84,4304,610],{"class":94},[84,4306,4307],{"class":4296},"100%",[84,4309,4310],{"class":94}," -",[84,4312,4313],{"class":4296}," 32px",[84,4315,4316],{"class":94},"));",[84,4318,4027],{"class":94},[373,4320,4322],{"id":4321},"scoped-slots-vue-only","Scoped slots (Vue only)",[286,4324,4325,4326,4328,4329,4332,4333,4336,4337,4340,4341,4343],{},"Each button exposes its state via a scoped slot for full custom markup, e.g. ",[81,4327,3149],{},"'s ",[81,4330,4331],{},"#default=\"{ isPlaying }\"",". This only works from a Vue template - a scoped slot is a render-function callback, which has no HTML\u002FDOM equivalent. Static children placed inside a custom element tag (e.g. ",[81,4334,4335],{},"\u003Cml-buffering>\u003Cdiv class=\"my-spinner\">\u003C\u002Fdiv>\u003C\u002Fml-buffering>",") still work as a ",[468,4338,4339],{},"non-scoped"," default slot, but a raw custom-element consumer wanting markup that reactively changes with state has to do it themselves, listening for ",[81,4342,1623],{}," and toggling their own elements\u002Fclasses.",[69,4345,4347],{"id":4346},"events","Events",[373,4349,4350],{"id":1623},[81,4351,1623],{},[286,4353,4354,4355,345,4357,2282,4359,662],{},"Emitted by ",[81,4356,190],{},[81,4358,180],{},[81,4360,200],{},[74,4362,4364],{"className":76,"code":4363,"language":78,"meta":79,"style":79},"interface StateChangeEvent {\n  type:\n    | 'play' | 'pause' | 'ended' | 'seeked' | 'error'\n    | 'adstart' | 'adend'\n    | 'volumechange' | 'ratechange'\n    | 'captionchange' | 'qualitychange' | 'pipchange' | 'loopchange'\n    | 'firstQuartile' | 'midpoint' | 'thirdQuartile'\n    | 'controlsopen' | 'controlsclose'\n    | 'stageopen' | 'stageclose'\n    | 'bufferstart' | 'bufferend'\n    | 'timeupdate'\n    | 'tap'\n  currentTime: number\n  duration: number\n  src: string\n  error?: { code: number; message: string } | null\n  isMuted?: boolean \u002F\u002F volumechange only\n  playbackRate?: number \u002F\u002F ratechange only\n  captionIndex?: number | null \u002F\u002F captionchange only; null means captions are off\n  qualityIndex?: number | null \u002F\u002F qualitychange only; null means Auto\n  isPipActive?: boolean \u002F\u002F pipchange only\n  isLooping?: boolean \u002F\u002F loopchange only\n  element?: HTMLElement | null \u002F\u002F controlsopen\u002Fcontrolsclose only\n  payload?: Record\u003Cstring, unknown>\n}\n",[81,4365,4366,4376,4384,4429,4449,4468,4502,4531,4551,4571,4591,4601,4612,4622,4632,4643,4679,4693,4706,4724,4741,4754,4767,4785,4807],{"__ignoreMap":79},[84,4367,4368,4371,4374],{"class":86,"line":87},[84,4369,4370],{"class":655},"interface",[84,4372,4373],{"class":4007}," StateChangeEvent",[84,4375,3043],{"class":94},[84,4377,4378,4381],{"class":86,"line":144},[84,4379,4380],{"class":619},"  type",[84,4382,4383],{"class":94},":\n",[84,4385,4386,4389,4391,4393,4395,4398,4400,4402,4404,4406,4408,4410,4412,4414,4416,4419,4421,4423,4425,4427],{"class":86,"line":604},[84,4387,4388],{"class":94},"    |",[84,4390,134],{"class":94},[84,4392,483],{"class":137},[84,4394,631],{"class":94},[84,4396,4397],{"class":94}," |",[84,4399,134],{"class":94},[84,4401,486],{"class":137},[84,4403,631],{"class":94},[84,4405,4397],{"class":94},[84,4407,134],{"class":94},[84,4409,787],{"class":137},[84,4411,631],{"class":94},[84,4413,4397],{"class":94},[84,4415,134],{"class":94},[84,4417,4418],{"class":137},"seeked",[84,4420,631],{"class":94},[84,4422,4397],{"class":94},[84,4424,134],{"class":94},[84,4426,2082],{"class":137},[84,4428,141],{"class":94},[84,4430,4431,4433,4435,4438,4440,4442,4444,4447],{"class":86,"line":616},[84,4432,4388],{"class":94},[84,4434,134],{"class":94},[84,4436,4437],{"class":137},"adstart",[84,4439,631],{"class":94},[84,4441,4397],{"class":94},[84,4443,134],{"class":94},[84,4445,4446],{"class":137},"adend",[84,4448,141],{"class":94},[84,4450,4451,4453,4455,4458,4460,4462,4464,4466],{"class":86,"line":637},[84,4452,4388],{"class":94},[84,4454,134],{"class":94},[84,4456,4457],{"class":137},"volumechange",[84,4459,631],{"class":94},[84,4461,4397],{"class":94},[84,4463,134],{"class":94},[84,4465,2024],{"class":137},[84,4467,141],{"class":94},[84,4469,4470,4472,4474,4476,4478,4480,4482,4484,4486,4488,4490,4492,4494,4496,4498,4500],{"class":86,"line":681},[84,4471,4388],{"class":94},[84,4473,134],{"class":94},[84,4475,2040],{"class":137},[84,4477,631],{"class":94},[84,4479,4397],{"class":94},[84,4481,134],{"class":94},[84,4483,2056],{"class":137},[84,4485,631],{"class":94},[84,4487,4397],{"class":94},[84,4489,134],{"class":94},[84,4491,2069],{"class":137},[84,4493,631],{"class":94},[84,4495,4397],{"class":94},[84,4497,134],{"class":94},[84,4499,2011],{"class":137},[84,4501,141],{"class":94},[84,4503,4504,4506,4508,4511,4513,4515,4517,4520,4522,4524,4526,4529],{"class":86,"line":699},[84,4505,4388],{"class":94},[84,4507,134],{"class":94},[84,4509,4510],{"class":137},"firstQuartile",[84,4512,631],{"class":94},[84,4514,4397],{"class":94},[84,4516,134],{"class":94},[84,4518,4519],{"class":137},"midpoint",[84,4521,631],{"class":94},[84,4523,4397],{"class":94},[84,4525,134],{"class":94},[84,4527,4528],{"class":137},"thirdQuartile",[84,4530,141],{"class":94},[84,4532,4533,4535,4537,4540,4542,4544,4546,4549],{"class":86,"line":734},[84,4534,4388],{"class":94},[84,4536,134],{"class":94},[84,4538,4539],{"class":137},"controlsopen",[84,4541,631],{"class":94},[84,4543,4397],{"class":94},[84,4545,134],{"class":94},[84,4547,4548],{"class":137},"controlsclose",[84,4550,141],{"class":94},[84,4552,4553,4555,4557,4560,4562,4564,4566,4569],{"class":86,"line":1915},[84,4554,4388],{"class":94},[84,4556,134],{"class":94},[84,4558,4559],{"class":137},"stageopen",[84,4561,631],{"class":94},[84,4563,4397],{"class":94},[84,4565,134],{"class":94},[84,4567,4568],{"class":137},"stageclose",[84,4570,141],{"class":94},[84,4572,4573,4575,4577,4580,4582,4584,4586,4589],{"class":86,"line":2804},[84,4574,4388],{"class":94},[84,4576,134],{"class":94},[84,4578,4579],{"class":137},"bufferstart",[84,4581,631],{"class":94},[84,4583,4397],{"class":94},[84,4585,134],{"class":94},[84,4587,4588],{"class":137},"bufferend",[84,4590,141],{"class":94},[84,4592,4593,4595,4597,4599],{"class":86,"line":2837},[84,4594,4388],{"class":94},[84,4596,134],{"class":94},[84,4598,489],{"class":137},[84,4600,141],{"class":94},[84,4602,4603,4605,4607,4610],{"class":86,"line":2867},[84,4604,4388],{"class":94},[84,4606,134],{"class":94},[84,4608,4609],{"class":137},"tap",[84,4611,141],{"class":94},[84,4613,4614,4617,4619],{"class":86,"line":2877},[84,4615,4616],{"class":4007},"  currentTime",[84,4618,623],{"class":94},[84,4620,4621],{"class":4007}," number\n",[84,4623,4625,4628,4630],{"class":86,"line":4624},14,[84,4626,4627],{"class":4007},"  duration",[84,4629,623],{"class":94},[84,4631,4621],{"class":4007},[84,4633,4635,4638,4640],{"class":86,"line":4634},15,[84,4636,4637],{"class":4007},"  src",[84,4639,623],{"class":94},[84,4641,4642],{"class":4007}," string\n",[84,4644,4646,4649,4652,4654,4657,4659,4662,4664,4667,4669,4672,4674,4676],{"class":86,"line":4645},16,[84,4647,4648],{"class":4007},"  error",[84,4650,4651],{"class":94},"?:",[84,4653,95],{"class":94},[84,4655,4656],{"class":619}," code",[84,4658,623],{"class":94},[84,4660,4661],{"class":4007}," number",[84,4663,4024],{"class":94},[84,4665,4666],{"class":619}," message",[84,4668,623],{"class":94},[84,4670,4671],{"class":4007}," string",[84,4673,128],{"class":94},[84,4675,4397],{"class":94},[84,4677,4678],{"class":4007}," null\n",[84,4680,4682,4685,4687,4690],{"class":86,"line":4681},17,[84,4683,4684],{"class":4007},"  isMuted",[84,4686,4651],{"class":94},[84,4688,4689],{"class":4007}," boolean",[84,4691,4692],{"class":695}," \u002F\u002F volumechange only\n",[84,4694,4696,4699,4701,4703],{"class":86,"line":4695},18,[84,4697,4698],{"class":619},"  playbackRate",[84,4700,4651],{"class":94},[84,4702,4661],{"class":4007},[84,4704,4705],{"class":695}," \u002F\u002F ratechange only\n",[84,4707,4709,4712,4714,4716,4718,4721],{"class":86,"line":4708},19,[84,4710,4711],{"class":619},"  captionIndex",[84,4713,4651],{"class":94},[84,4715,4661],{"class":4007},[84,4717,4397],{"class":94},[84,4719,4720],{"class":4007}," null",[84,4722,4723],{"class":695}," \u002F\u002F captionchange only; null means captions are off\n",[84,4725,4727,4730,4732,4734,4736,4738],{"class":86,"line":4726},20,[84,4728,4729],{"class":619},"  qualityIndex",[84,4731,4651],{"class":94},[84,4733,4661],{"class":4007},[84,4735,4397],{"class":94},[84,4737,4720],{"class":4007},[84,4739,4740],{"class":695}," \u002F\u002F qualitychange only; null means Auto\n",[84,4742,4744,4747,4749,4751],{"class":86,"line":4743},21,[84,4745,4746],{"class":619},"  isPipActive",[84,4748,4651],{"class":94},[84,4750,4689],{"class":4007},[84,4752,4753],{"class":695}," \u002F\u002F pipchange only\n",[84,4755,4757,4760,4762,4764],{"class":86,"line":4756},22,[84,4758,4759],{"class":619},"  isLooping",[84,4761,4651],{"class":94},[84,4763,4689],{"class":4007},[84,4765,4766],{"class":695}," \u002F\u002F loopchange only\n",[84,4768,4770,4773,4775,4778,4780,4782],{"class":86,"line":4769},23,[84,4771,4772],{"class":619},"  element",[84,4774,4651],{"class":94},[84,4776,4777],{"class":4007}," HTMLElement",[84,4779,4397],{"class":94},[84,4781,4720],{"class":4007},[84,4783,4784],{"class":695}," \u002F\u002F controlsopen\u002Fcontrolsclose only\n",[84,4786,4788,4791,4793,4796,4798,4800,4802,4805],{"class":86,"line":4787},24,[84,4789,4790],{"class":619},"  payload",[84,4792,4651],{"class":94},[84,4794,4795],{"class":4007}," Record",[84,4797,852],{"class":94},[84,4799,1321],{"class":4007},[84,4801,102],{"class":94},[84,4803,4804],{"class":4007}," unknown",[84,4806,872],{"class":94},[84,4808,4810],{"class":86,"line":4809},25,[84,4811,4812],{"class":94},"}\n",[155,4814,4815,4824],{},[158,4816,4817],{},[161,4818,4819,4821],{},[164,4820,1303],{},[164,4822,4823],{},"Notes",[171,4825,4826,4839,4859,4876,4894,4903,4915,4945,4967],{},[161,4827,4828,4836],{},[176,4829,4830,1289,4832,1289,4834],{},[81,4831,4510],{},[81,4833,4519],{},[81,4835,4528],{},[176,4837,4838],{},"Fire once each as playback crosses 25%, 50%, 75% of duration. Useful for IAB-style progress analytics. Reset and can fire again on loop restart.",[161,4840,4841,4847],{},[176,4842,4843,1289,4845],{},[81,4844,4539],{},[81,4846,4548],{},[176,4848,4849,4850,4853,4854,345,4856,4858],{},"Fire when the expanded controls popup mounts\u002Funmounts, with ",[81,4851,4852],{},"element"," set to its root DOM node. On ",[81,4855,4548],{},[81,4857,4852],{}," is a snapshot - it's detached from the DOM immediately after.",[161,4860,4861,4867],{},[176,4862,4863,1289,4865],{},[81,4864,4559],{},[81,4866,4568],{},[176,4868,4869,4870,4872,4873,4875],{},"Fire from ",[81,4871,200],{}," only, when the stage mounts its inner player (the first video arrives) and when it tears it down again. Arrive on the same ",[81,4874,1623],{}," stream rather than as a separate event.",[161,4877,4878,4884],{},[176,4879,4880,1289,4882],{},[81,4881,2040],{},[81,4883,2056],{},[176,4885,4886,4887,300,4890,4893],{},"Fire on every ",[81,4888,4889],{},"setCaptionTrack()",[81,4891,4892],{},"setQuality()"," call and whenever the adapter's own ABR switches the active track\u002Flevel, but never before playback has started.",[161,4895,4896,4900],{},[176,4897,4898],{},[81,4899,2069],{},[176,4901,4902],{},"Fires on entering\u002Fexiting Picture-in-Picture, whether triggered by the player's own button or the user closing the browser's floating PiP window directly.",[161,4904,4905,4909],{},[176,4906,4907],{},[81,4908,2011],{},[176,4910,4911,4912,4914],{},"Fires on every ",[81,4913,2005],{}," call, never before playback has started.",[161,4916,4917,4923],{},[176,4918,4919,1289,4921],{},[81,4920,4579],{},[81,4922,4588],{},[176,4924,4925,4927,4928,4931,4932,4934,4935,300,4938,4941,4942,4944],{},[81,4926,4579],{}," fires once the player has been stalled on ",[81,4929,4930],{},"waiting"," longer than the buffering-spinner delay; ",[81,4933,4588],{}," fires once ",[81,4936,4937],{},"playing",[81,4939,4940],{},"canplay"," resolves it (or on ",[81,4943,787],{},"). Useful for tracking rebuffer count\u002Fratio.",[161,4946,4947,4951],{},[176,4948,4949],{},[81,4950,489],{},[176,4952,4953,4954,300,4956,4959,4960,4963,4964,4966],{},"Fires at most every 250ms during playback, once it's started. A Vue consumer gets live ",[81,4955,515],{},[81,4957,4958],{},"total"," for free through the ",[265,4961,4962],{"href":1696},"template-ref API","'s reactivity - this event exists for non-Vue consumers (e.g. a raw ",[81,4965,1080],{}," element with no surrounding Vue app) who need a signal to know position changed, e.g. to drive a custom seekbar.",[161,4968,4969,4973],{},[176,4970,4971],{},[81,4972,4609],{},[176,4974,4975,4976,4978,4979,4981],{},"Fires from the tap-to-reveal-controls overlay, regardless of ",[81,4977,1676],{},". The only signal a ",[81,4980,3908],{}," consumer gets that the user tapped the video - useful for showing\u002Fhiding your own HUD in response.",[286,4983,4984,4985,4987,4988,4990],{},"On ",[81,4986,2082],{},", the player shows a built-in \"Retry\" button, or call ",[81,4989,2076],{}," yourself via a template ref (see above).",[69,4992,4994],{"id":4993},"ads-ima-vast-vmap","Ads (IMA \u002F VAST \u002F VMAP)",[286,4996,4997,4998,5001,5002,5005,5006,5009,5010,5012],{},"Pass ",[81,4999,5000],{},"ad-tag-url"," for a plain VAST\u002FVMAP ad, or ",[81,5003,5004],{},"header-bidding"," to run a Prebid.js auction first and fall back to the plain ad tag on no-fill. Ads are not supported on YouTube, Vimeo, or Dailymotion. See the package ",[81,5007,5008],{},"README.md"," for the full step-by-step setup, ",[81,5011,1548],{}," macro-filling, and header-bidding config shape.",[373,5014,5016],{"id":5015},"ad-overlay-ui","Ad overlay UI",[286,5018,5019],{},"While an ad is playing, a small overlay shows an \"Ad\" badge with a countdown to the ad's end, a dedicated pause\u002Fresume button, and a mute button that controls the ad creative's own independent audio (separate from the content video's volume\u002Fmute state: muting the player has no effect on ad audio, and vice versa).",[373,5021,5023],{"id":5022},"ad-visibility-behaviour","Ad visibility behaviour",[286,5025,5026,5027,300,5030,5033,5034,5036],{},"An ad pauses itself whenever the tab is hidden or the window loses focus (checked on ",[81,5028,5029],{},"visibilitychange",[81,5031,5032],{},"blur",", and once up front when the ad starts, so a mid-roll beginning on an already-backgrounded tab is caught too): no manual setup needed, and it doesn't auto-resume, since the point is to stop burning an impression on nobody watching. If Picture-in-Picture is active when an ad starts, it's exited too (skipped on iOS, where the ad creative renders directly into the same ",[81,5035,423],{}," element PiP is already mirroring, so there's nothing to lose by staying in PiP there).",[286,5038,5039,5040,5042,5043,300,5045,300,5047,5050,5051,300,5053,300,5055,5058,5059,5061,5062,5064],{},"That same iOS behaviour - the ad creative playing through the content's own ",[81,5041,423],{}," element rather than a separate one - means the browser fires real ",[81,5044,489],{},[81,5046,492],{},[81,5048,5049],{},"progress"," events for the ad's own timeline while it plays. The player ignores all three while an ad is active, so ",[81,5052,515],{},[81,5054,4958],{},[81,5056,5057],{},"bufferedDisplay"," (and anything built on them, like a ",[81,5060,3298],{}," or ",[81,5063,3370],{},") stay on the content's position throughout the ad instead of briefly reflecting the ad's, and resume tracking automatically the moment it ends.",[286,5066,5067,5068,5070,5071,5074,5075,5078],{},"A second iOS-specific issue: after a post-roll ad finishes, the IMA SDK may not restore the original content source, leaving the ",[81,5069,423],{}," element pointing at the ad creative. Clicking \"Replay\" would then replay the ad instead of the content. The player tracks whether content had already ended when the ad started (",[81,5072,5073],{},"postRollPending","), and on ",[81,5076,5077],{},"CONTENT_RESUME_REQUESTED"," restores the saved original source and seeks to the end to clear the browser's internal \"ended\" flag, letting the normal ended\u002Freplay flow work correctly.",[5080,5081,5082],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":79,"searchDepth":144,"depth":144,"links":5084},[5085,5088,5091,5093,5095,5097,5101,5109,5112],{"id":71,"depth":144,"text":72,"children":5086},[5087],{"id":375,"depth":604,"text":376},{"id":565,"depth":144,"text":566,"children":5089},[5090],{"id":829,"depth":604,"text":830},{"id":1285,"depth":144,"text":5092},"Props (VideoCard \u002F VideoPlayer)",{"id":1765,"depth":144,"text":5094},"Template-ref methods (VideoPlayer)",{"id":2085,"depth":144,"text":5096},"Template-ref methods (VideoCard and VideoStage)",{"id":2349,"depth":144,"text":2350,"children":5098},[5099,5100],{"id":2461,"depth":604,"text":2464},{"id":2635,"depth":604,"text":2638},{"id":3004,"depth":144,"text":3005,"children":5102},[5103,5104,5105,5106,5107,5108],{"id":3413,"depth":604,"text":3414},{"id":3710,"depth":604,"text":3711},{"id":3919,"depth":604,"text":3920},{"id":4057,"depth":604,"text":4058},{"id":4148,"depth":604,"text":4149},{"id":4321,"depth":604,"text":4322},{"id":4346,"depth":144,"text":4347,"children":5110},[5111],{"id":1623,"depth":604,"text":1623},{"id":4993,"depth":144,"text":4994,"children":5113},[5114,5115],{"id":5015,"depth":604,"text":5016},{"id":5022,"depth":604,"text":5023},"Components, props, template-ref methods, and the full state-change event list.","md",null,{},{"icon":43},{"title":40,"description":5116},"-a2VB3Gwop-GtTCU8Che14xyRMKOkc5wKpD8WzhIBtI",[5124,5126],{"title":35,"path":36,"stem":37,"description":5125,"icon":38,"children":-1},"Install, mount a video, and read the state-change event stream.",{"title":11,"path":51,"stem":52,"description":5127,"icon":46,"children":-1},"Shared build tooling and CLI.",1789409982724]