1"use strict"; 2(globalThis["webpackChunk_flippingbook_publication"] = globalThis["webpackChunk_flippingbook_publication"] || []).push([[7],{ 3 4/***/ 409: 5/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 6 7__webpack_require__.r(__webpack_exports__); 8/* harmony export */ __webpack_require__.d(__webpack_exports__, { 9/* harmony export */ CaptionsRenderer: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.C), 10/* harmony export */ ParseError: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.P), 11/* harmony export */ ParseErrorCode: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.c), 12/* harmony export */ TextCue: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.T), 13/* harmony export */ VTTCue: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.b), 14/* harmony export */ VTTRegion: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.h), 15/* harmony export */ createVTTCueTemplate: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.i), 16/* harmony export */ parseByteStream: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.e), 17/* harmony export */ parseResponse: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.d), 18/* harmony export */ parseText: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.f), 19/* harmony export */ parseTextStream: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.g), 20/* harmony export */ parseVTTTimestamp: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.p), 21/* harmony export */ renderVTTCueString: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.r), 22/* harmony export */ renderVTTTokensString: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.j), 23/* harmony export */ tokenizeVTTCue: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.t), 24/* harmony export */ updateTimedVTTCueNodes: () => (/* reexport safe */ _prod_index_js__WEBPACK_IMPORTED_MODULE_0__.u) 25/* harmony export */ }); 26/* harmony import */ var _prod_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(574); 27 28 29 30/***/ }), 31 32/***/ 2557: 33/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 34 35__webpack_require__.r(__webpack_exports__); 36/* harmony export */ __webpack_require__.d(__webpack_exports__, { 37/* harmony export */ ParseErrorBuilder: () => (/* binding */ ParseErrorBuilder) 38/* harmony export */ }); 39/* harmony import */ var _index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(574); 40 41 42const ParseErrorBuilder = { 43 r() { 44 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 45 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadSignature, 46 reason: "missing WEBVTT file header", 47 line: 1 48 }); 49 }, 50 s(startTime, line) { 51 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 52 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadTimestamp, 53 reason: `cue start timestamp \`${startTime}\` is invalid on line ${line}`, 54 line 55 }); 56 }, 57 t(endTime, line) { 58 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 59 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadTimestamp, 60 reason: `cue end timestamp \`${endTime}\` is invalid on line ${line}`, 61 line 62 }); 63 }, 64 u(startTime, endTime, line) { 65 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 66 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadTimestamp, 67 reason: `cue end timestamp \`${endTime}\` is greater than start \`${startTime}\` on line ${line}`, 68 line 69 }); 70 }, 71 y(name, value, line) { 72 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 73 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadSettingValue, 74 reason: `invalid value for cue setting \`${name}\` on line ${line} (value: ${value})`, 75 line 76 }); 77 }, 78 x(name, value, line) { 79 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 80 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.UnknownSetting, 81 reason: `unknown cue setting \`${name}\` on line ${line} (value: ${value})`, 82 line 83 }); 84 }, 85 w(name, value, line) { 86 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 87 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadSettingValue, 88 reason: `invalid value for region setting \`${name}\` on line ${line} (value: ${value})`, 89 line 90 }); 91 }, 92 v(name, value, line) { 93 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 94 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.UnknownSetting, 95 reason: `unknown region setting \`${name}\` on line ${line} (value: ${value})`, 96 line 97 }); 98 }, 99 // SSA-specific errors 100 T(type, line) { 101 return new _index_js__WEBPACK_IMPORTED_MODULE_0__.P({ 102 code: _index_js__WEBPACK_IMPORTED_MODULE_0__.c.BadFormat, 103 reason: `format missing for \`${type}\` block on line ${line}`, 104 line 105 }); 106 } 107}; 108 109 110 111 112/***/ }), 113 114/***/ 574: 115/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 116 117/* harmony export */ __webpack_require__.d(__webpack_exports__, { 118/* harmony export */ C: () => (/* binding */ CaptionsRenderer), 119/* harmony export */ P: () => (/* binding */ ParseError), 120/* harmony export */ T: () => (/* binding */ TextCue), 121/* harmony export */ V: () => (/* binding */ VTTParser), 122/* harmony export */ a: () => (/* binding */ VTTBlock), 123/* harmony export */ b: () => (/* binding */ VTTCue), 124/* harmony export */ c: () => (/* binding */ ParseErrorCode), 125/* harmony export */ d: () => (/* binding */ parseResponse), 126/* harmony export */ e: () => (/* binding */ parseByteStream), 127/* harmony export */ f: () => (/* binding */ parseText),
vendor: 5,064 bytes, lines 128-304
128/* harmony export */ g: () => (/* binding */ parseTextStream), 129/* harmony export */ h: () => (/* binding */ VTTRegion), 130/* harmony export */ i: () => (/* binding */ createVTTCueTemplate), 131/* harmony export */ j: () => (/* binding */ renderVTTTokensString), 132/* harmony export */ p: () => (/* binding */ parseVTTTimestamp), 133/* harmony export */ r: () => (/* binding */ renderVTTCueString), 134/* harmony export */ t: () => (/* binding */ tokenizeVTTCue), 135/* harmony export */ u: () => (/* binding */ updateTimedVTTCueNodes) 136/* harmony export */ }); 137const ParseErrorCode = { 138 LoadFail: 0, 139 BadSignature: 1, 140 BadTimestamp: 2, 141 BadSettingValue: 3, 142 BadFormat: 4, 143 UnknownSetting: 5 144}; 145class ParseError extends Error { 146 code; 147 line; 148 constructor(init) { 149 super(init.reason); 150 this.code = init.code; 151 this.line = init.line; 152 } 153} 154 155const LINE_TERMINATOR_RE = /\r?\n|\r/gm; 156class TextLineTransformStream { 157 writable; 158 readable; 159 constructor(encoding) { 160 const transformer = new TextStreamLineIterator(encoding); 161 this.writable = new WritableStream({ 162 write(chunk) { 163 transformer.transform(chunk); 164 }, 165 close() { 166 transformer.close(); 167 } 168 }); 169 this.readable = new ReadableStream({ 170 start(controller) { 171 transformer.onLine = (line) => controller.enqueue(line); 172 transformer.onClose = () => controller.close(); 173 } 174 }); 175 } 176} 177class TextStreamLineIterator { 178 a = ""; 179 b; 180 onLine; 181 onClose; 182 constructor(encoding) { 183 this.b = new TextDecoder(encoding); 184 } 185 transform(chunk) { 186 this.a += this.b.decode(chunk, { stream: true }); 187 const lines = this.a.split(LINE_TERMINATOR_RE); 188 this.a = lines.pop() || ""; 189 for (let i = 0; i < lines.length; i++) 190 this.onLine(lines[i].trim()); 191 } 192 close() { 193 if (this.a) 194 this.onLine(this.a.trim()); 195 this.a = ""; 196 this.onClose(); 197 } 198} 199 200async function parseText(text, options) { 201 const stream = new ReadableStream({ 202 start(controller) { 203 const lines = text.split(LINE_TERMINATOR_RE); 204 for (const line of lines) 205 controller.enqueue(line); 206 controller.close(); 207 } 208 }); 209 return parseTextStream(stream, options); 210} 211async function parseTextStream(stream, options) { 212 const type = options?.type ?? "vtt"; 213 let factory; 214 if (typeof type === "string") { 215 switch (type) { 216 case "srt": 217 factory = (await __webpack_require__.e(/* import() */ 7).then(__webpack_require__.bind(__webpack_require__, 3892))).default; 218 break; 219 case "ssa": 220 case "ass": 221 factory = (await __webpack_require__.e(/* import() */ 7).then(__webpack_require__.bind(__webpack_require__, 6900))).default; 222 break; 223 default: 224 factory = (await Promise.resolve().then(function () { return vttParser; })).default; 225 } 226 } else { 227 factory = type; 228 } 229 let result; 230 const reader = stream.getReader(), parser = factory(), errors = !!options?.strict || !!options?.errors; 231 await parser.init({ 232 strict: false, 233 ...options, 234 errors, 235 type, 236 cancel() { 237 reader.cancel(); 238 result = parser.done(true); 239 } 240 }); 241 let i = 1; 242 while (true) { 243 const { value, done } = await reader.read(); 244 if (done) { 245 parser.parse("", i); 246 result = parser.done(false); 247 break; 248 } 249 parser.parse(value, i); 250 i++; 251 } 252 return result; 253} 254 255async function parseResponse(response, options) { 256 const res = await response; 257 if (!res.ok || !res.body) { 258 let error; 259 return { 260 metadata: {}, 261 cues: [], 262 regions: [], 263 errors: [error] 264 }; 265 } 266 const contentType = res.headers.get("content-type") || "", type = contentType.match(/text\/(.*?)(?:;|$)/)?.[1], encoding = contentType.match(/charset=(.*?)(?:;|$)/)?.[1]; 267 return parseByteStream(res.body, { type, encoding, ...options }); 268} 269async function parseByteStream(stream, { encoding = "utf-8", ...options } = {}) { 270 const textStream = stream.pipeThrough(new TextLineTransformStream(encoding)); 271 return parseTextStream(textStream, options); 272} 273 274class TextCue extends EventTarget { 275 /** 276 * A string that identifies the cue. 277 * 278 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextTrackCue/id} 279 */ 280 id = ""; 281 /** 282 * A `double` that represents the video time that the cue will start being displayed, in seconds. 283 * 284 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextTrackCue/startTime} 285 */ 286 startTime; 287 /** 288 * A `double` that represents the video time that the cue will stop being displayed, in seconds. 289 * 290 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextTrackCue/endTime} 291 */ 292 endTime; 293 /** 294 * Returns a string with the contents of the cue. 295 * 296 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/text} 297 */ 298 text; 299 /** 300 * A `boolean` for whether the video will pause when this cue stops being displayed. 301 * 302 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/TextTrackCue/pauseOnExit} 303 */ 304 pauseOnExit = false;
vendor: 19,627 bytes, lines 305-967
305 constructor(startTime, endTime, text) { 306 super(); 307 this.startTime = startTime; 308 this.endTime = endTime; 309 this.text = text; 310 } 311 addEventListener(type, listener, options) { 312 super.addEventListener(type, listener, options); 313 } 314 removeEventListener(type, listener, options) { 315 super.removeEventListener(type, listener, options); 316 } 317} 318 319const IS_SERVER = typeof document === "undefined"; 320 321const CueBase = IS_SERVER ? TextCue : window.VTTCue; 322class VTTCue extends CueBase { 323 /** 324 * A `VTTRegion` object describing the video's sub-region that the cue will be drawn onto, 325 * or `null` if none is assigned. 326 * 327 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/region} 328 */ 329 region = null; 330 /** 331 * The cue writing direction. 332 * 333 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/vertical} 334 */ 335 vertical = ""; 336 /** 337 * Returns `true` if the `VTTCue.line` attribute is an integer number of lines or a percentage 338 * of the video size. 339 * 340 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/snapToLines} 341 */ 342 snapToLines = true; 343 /** 344 * Returns the line positioning of the cue. This can be the string `'auto'` or a number whose 345 * interpretation depends on the value of `VTTCue.snapToLines`. 346 * 347 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/line} 348 */ 349 line = "auto"; 350 /** 351 * Returns an enum representing the alignment of the `VTTCue.line`. 352 * 353 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/lineAlign} 354 */ 355 lineAlign = "start"; 356 /** 357 * Returns the indentation of the cue within the line. This can be the string `'auto'` or a 358 * number representing the percentage of the `VTTCue.region`, or the video size if `VTTCue`.region` 359 * is `null`. 360 * 361 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/position} 362 */ 363 position = "auto"; 364 /** 365 * Returns an enum representing the alignment of the cue. This is used to determine what 366 * the `VTTCue.position` is anchored to. The default is `'auto'`. 367 * 368 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/positionAlign} 369 */ 370 positionAlign = "auto"; 371 /** 372 * Returns a double representing the size of the cue, as a percentage of the video size. 373 * 374 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/size} 375 */ 376 size = 100; 377 /** 378 * Returns an enum representing the alignment of all the lines of text within the cue box. 379 * 380 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/align} 381 */ 382 align = "center"; 383 /** 384 * Additional styles associated with the cue. 385 */ 386 style; 387} 388 389class VTTRegion { 390 /** 391 * A string that identifies the region. 392 */ 393 id = ""; 394 /** 395 * A `double` representing the width of the region, as a percentage of the video. 396 */ 397 width = 100; 398 /** 399 * A `double` representing the height of the region, in number of lines. 400 */ 401 lines = 3; 402 /** 403 * A `double` representing the region anchor X offset, as a percentage of the region. 404 */ 405 regionAnchorX = 0; 406 /** 407 * A `double` representing the region anchor Y offset, as a percentage of the region. 408 */ 409 regionAnchorY = 100; 410 /** 411 * A `double` representing the viewport anchor X offset, as a percentage of the video. 412 */ 413 viewportAnchorX = 0; 414 /** 415 * A `double` representing the viewport anchor Y offset, as a percentage of the video. 416 */ 417 viewportAnchorY = 100; 418 /** 419 * An enum representing how adding new cues will move existing cues. 420 */ 421 scroll = ""; 422} 423 424const COMMA$1 = ",", PERCENT_SIGN$1 = "%"; 425function toNumber(text) { 426 const num = parseInt(text, 10); 427 return !Number.isNaN(num) ? num : null; 428} 429function toPercentage(text) { 430 const num = parseInt(text.replace(PERCENT_SIGN$1, ""), 10); 431 return !Number.isNaN(num) && num >= 0 && num <= 100 ? num : null; 432} 433function toCoords(text) { 434 if (!text.includes(COMMA$1)) 435 return null; 436 const [x, y] = text.split(COMMA$1).map(toPercentage); 437 return x !== null && y !== null ? [x, y] : null; 438} 439function toFloat(text) { 440 const num = parseFloat(text); 441 return !Number.isNaN(num) ? num : null; 442} 443 444const HEADER_MAGIC = "WEBVTT", COMMA = ",", PERCENT_SIGN = "%", SETTING_SEP_RE = /[:=]/, SETTING_LINE_RE = /^[\s\t]*(region|vertical|line|position|size|align)[:=]/, NOTE_BLOCK_START = "NOTE", REGION_BLOCK_START = "REGION", REGION_BLOCK_START_RE = /^REGION:?[\s\t]+/, SPACE_RE = /[\s\t]+/, TIMESTAMP_SEP = "-->", TIMESTAMP_SEP_RE = /[\s\t]*-->[\s\t]+/, ALIGN_RE = /start|center|end|left|right/, LINE_ALIGN_RE = /start|center|end/, POS_ALIGN_RE = /line-(?:left|right)|center|auto/, TIMESTAMP_RE = /^(?:(\d{1,2}):)?(\d{2}):(\d{2})(?:\.(\d{1,3}))?$/; 445var VTTBlock = /* @__PURE__ */ ((VTTBlock2) => { 446 VTTBlock2[VTTBlock2["None"] = 0] = "None"; 447 VTTBlock2[VTTBlock2["Header"] = 1] = "Header"; 448 VTTBlock2[VTTBlock2["Cue"] = 2] = "Cue"; 449 VTTBlock2[VTTBlock2["Region"] = 3] = "Region"; 450 VTTBlock2[VTTBlock2["Note"] = 4] = "Note"; 451 return VTTBlock2; 452})(VTTBlock || {}); 453class VTTParser { 454 h; 455 e = 0; 456 i = {}; 457 j = {}; 458 l = []; 459 c = null; 460 d = null; 461 m = []; 462 f; 463 n = ""; 464 async init(init) { 465 this.h = init; 466 if (init.strict) 467 this.e = 1; 468 if (init.errors) 469 this.f = (await __webpack_require__.e(/* import() */ 7).then(__webpack_require__.bind(__webpack_require__, 2557))).ParseErrorBuilder; 470 } 471 parse(line, lineCount) { 472 if (line === "") { 473 if (this.c) { 474 this.l.push(this.c); 475 this.h.onCue?.(this.c); 476 this.c = null; 477 } else if (this.d) { 478 this.j[this.d.id] = this.d; 479 this.h.onRegion?.(this.d); 480 this.d = null; 481 } else if (this.e === 1) { 482 this.k(line, lineCount); 483 this.h.onHeaderMetadata?.(this.i); 484 } 485 this.e = 0; 486 } else if (this.e) { 487 switch (this.e) { 488 case 1: 489 this.k(line, lineCount); 490 break; 491 case 2: 492 if (this.c) { 493 const hasText = this.c.text.length > 0; 494 if (!hasText && SETTING_LINE_RE.test(line)) { 495 this.o(line.split(SPACE_RE), lineCount); 496 } else { 497 this.c.text += (hasText ? "\n" : "") + line; 498 } 499 } 500 break; 501 case 3: 502 this.p(line.split(SPACE_RE), lineCount); 503 break; 504 } 505 } else if (line.startsWith(NOTE_BLOCK_START)) { 506 this.e = 4; 507 } else if (line.startsWith(REGION_BLOCK_START)) { 508 this.e = 3; 509 this.d = new VTTRegion(); 510 this.p(line.replace(REGION_BLOCK_START_RE, "").split(SPACE_RE), lineCount); 511 } else if (line.includes(TIMESTAMP_SEP)) { 512 const result = this.q(line, lineCount); 513 if (result) { 514 this.c = new VTTCue(result[0], result[1], ""); 515 this.c.id = this.n; 516 this.o(result[2], lineCount); 517 } 518 this.e = 2; 519 } else if (lineCount === 1) { 520 this.k(line, lineCount); 521 } 522 this.n = line; 523 } 524 done() { 525 return { 526 metadata: this.i, 527 cues: this.l, 528 regions: Object.values(this.j), 529 errors: this.m 530 }; 531 } 532 k(line, lineCount) { 533 if (lineCount > 1) { 534 if (SETTING_SEP_RE.test(line)) { 535 const [key, value] = line.split(SETTING_SEP_RE); 536 if (key) 537 this.i[key] = (value || "").replace(SPACE_RE, ""); 538 } 539 } else if (line.startsWith(HEADER_MAGIC)) { 540 this.e = 1; 541 } else { 542 this.g(this.f?.r()); 543 } 544 } 545 q(line, lineCount) { 546 const [startTimeText, trailingText = ""] = line.split(TIMESTAMP_SEP_RE), [endTimeText, ...settingsText] = trailingText.split(SPACE_RE), startTime = parseVTTTimestamp(startTimeText), endTime = parseVTTTimestamp(endTimeText); 547 if (startTime !== null && endTime !== null && endTime > startTime) { 548 return [startTime, endTime, settingsText]; 549 } else { 550 if (startTime === null) { 551 this.g(this.f?.s(startTimeText, lineCount)); 552 } 553 if (endTime === null) { 554 this.g(this.f?.t(endTimeText, lineCount)); 555 } 556 if (startTime != null && endTime !== null && endTime > startTime) { 557 this.g(this.f?.u(startTime, endTime, lineCount)); 558 } 559 } 560 } 561 /** 562 * @see {@link https://www.w3.org/TR/webvtt1/#region-settings-parsing} 563 */ 564 p(settings, line) { 565 let badValue; 566 for (let i = 0; i < settings.length; i++) { 567 if (SETTING_SEP_RE.test(settings[i])) { 568 badValue = false; 569 const [name, value] = settings[i].split(SETTING_SEP_RE); 570 switch (name) { 571 case "id": 572 this.d.id = value; 573 break; 574 case "width": 575 const width = toPercentage(value); 576 if (width !== null) 577 this.d.width = width; 578 else 579 badValue = true; 580 break; 581 case "lines": 582 const lines = toNumber(value); 583 if (lines !== null) 584 this.d.lines = lines; 585 else 586 badValue = true; 587 break; 588 case "regionanchor": 589 const region = toCoords(value); 590 if (region !== null) { 591 this.d.regionAnchorX = region[0]; 592 this.d.regionAnchorY = region[1]; 593 } else 594 badValue = true; 595 break; 596 case "viewportanchor": 597 const viewport = toCoords(value); 598 if (viewport !== null) { 599 this.d.viewportAnchorX = viewport[0]; 600 this.d.viewportAnchorY = viewport[1]; 601 } else 602 badValue = true; 603 break; 604 case "scroll": 605 if (value === "up") 606 this.d.scroll = "up"; 607 else 608 badValue = true; 609 break; 610 default: 611 this.g(this.f?.v(name, value, line)); 612 } 613 if (badValue) { 614 this.g(this.f?.w(name, value, line)); 615 } 616 } 617 } 618 } 619 /** 620 * @see {@link https://www.w3.org/TR/webvtt1/#cue-timings-and-settings-parsing} 621 */ 622 o(settings, line) { 623 let badValue; 624 for (let i = 0; i < settings.length; i++) { 625 badValue = false; 626 if (SETTING_SEP_RE.test(settings[i])) { 627 const [name, value] = settings[i].split(SETTING_SEP_RE); 628 switch (name) { 629 case "region": 630 const region = this.j[value]; 631 if (region) 632 this.c.region = region; 633 break; 634 case "vertical": 635 if (value === "lr" || value === "rl") { 636 this.c.vertical = value; 637 this.c.region = null; 638 } else 639 badValue = true; 640 break; 641 case "line": 642 const [linePos, lineAlign] = value.split(COMMA); 643 if (linePos.includes(PERCENT_SIGN)) { 644 const percentage = toPercentage(linePos); 645 if (percentage !== null) { 646 this.c.line = percentage; 647 this.c.snapToLines = false; 648 } else 649 badValue = true; 650 } else { 651 const number = toFloat(linePos); 652 if (number !== null) 653 this.c.line = number; 654 else 655 badValue = true; 656 } 657 if (LINE_ALIGN_RE.test(lineAlign)) { 658 this.c.lineAlign = lineAlign; 659 } else if (lineAlign) { 660 badValue = true; 661 } 662 if (this.c.line !== "auto") 663 this.c.region = null; 664 break; 665 case "position": 666 const [colPos, colAlign] = value.split(COMMA), position = toPercentage(colPos); 667 if (position !== null) 668 this.c.position = position; 669 else 670 badValue = true; 671 if (colAlign && POS_ALIGN_RE.test(colAlign)) { 672 this.c.positionAlign = colAlign; 673 } else if (colAlign) { 674 badValue = true; 675 } 676 break; 677 case "size": 678 const size = toPercentage(value); 679 if (size !== null) { 680 this.c.size = size; 681 if (size < 100) 682 this.c.region = null; 683 } else { 684 badValue = true; 685 } 686 break; 687 case "align": 688 if (ALIGN_RE.test(value)) { 689 this.c.align = value; 690 } else { 691 badValue = true; 692 } 693 break; 694 default: 695 this.g(this.f?.x(name, value, line)); 696 } 697 if (badValue) { 698 this.g(this.f?.y(name, value, line)); 699 } 700 } 701 } 702 } 703 g(error) { 704 if (!error) 705 return; 706 this.m.push(error); 707 if (this.h.strict) { 708 this.h.cancel(); 709 throw error; 710 } else { 711 this.h.onError?.(error); 712 } 713 } 714} 715function parseVTTTimestamp(timestamp) { 716 const match = timestamp.match(TIMESTAMP_RE); 717 if (!match) 718 return null; 719 const hours = match[1] ? parseInt(match[1], 10) : 0, minutes = parseInt(match[2], 10), seconds = parseInt(match[3], 10), milliseconds = match[4] ? parseInt(match[4].padEnd(3, "0"), 10) : 0, total = hours * 3600 + minutes * 60 + seconds + milliseconds / 1e3; 720 if (hours < 0 || minutes < 0 || seconds < 0 || milliseconds < 0 || minutes > 59 || seconds > 59) { 721 return null; 722 } 723 return total; 724} 725function createVTTParser() { 726 return new VTTParser(); 727} 728 729var vttParser = /*#__PURE__*/Object.freeze({ 730 __proto__: null, 731 VTTBlock: VTTBlock, 732 VTTParser: VTTParser, 733 default: createVTTParser, 734 parseVTTTimestamp: parseVTTTimestamp 735}); 736 737const DIGIT_RE = /[0-9]/, MULTI_SPACE_RE = /[\s\t]+/, TAG_NAME = { 738 c: "span", 739 i: "i", 740 b: "b", 741 u: "u", 742 ruby: "ruby", 743 rt: "rt", 744 v: "span", 745 lang: "span", 746 timestamp: "span" 747}, HTML_ENTITIES = { 748 "&": "&", 749 "<": "<", 750 ">": ">", 751 """: '"', 752 "'": "'", 753 " ": "\xA0", 754 "‎": "\u200E", 755 "‏": "\u200F" 756}, HTML_ENTITY_RE = /&(?:amp|lt|gt|quot|#(0+)?39|nbsp|lrm|rlm);/g, COLORS = /* @__PURE__ */ new Set([ 757 "white", 758 "lime", 759 "cyan", 760 "red", 761 "yellow", 762 "magenta", 763 "blue", 764 "black" 765]), BLOCK_TYPES = /* @__PURE__ */ new Set(Object.keys(TAG_NAME)); 766function tokenizeVTTCue(cue) { 767 let buffer = "", mode = 1, result = [], stack = [], node; 768 for (let i = 0; i < cue.text.length; i++) { 769 const char = cue.text[i]; 770 switch (mode) { 771 case 1: 772 if (char === "<") { 773 addText(); 774 mode = 2; 775 } else { 776 buffer += char; 777 } 778 break; 779 case 2: 780 switch (char) { 781 case "\n": 782 case " ": 783 case " ": 784 addNode(); 785 mode = 4; 786 break; 787 case ".": 788 addNode(); 789 mode = 3; 790 break; 791 case "/": 792 mode = 5; 793 break; 794 case ">": 795 addNode(); 796 mode = 1; 797 break; 798 default: 799 if (!buffer && DIGIT_RE.test(char)) 800 mode = 6; 801 buffer += char; 802 break; 803 } 804 break; 805 case 3: 806 switch (char) { 807 case " ": 808 case " ": 809 case "\n": 810 addClass(); 811 if (node) 812 node.class?.trim(); 813 mode = 4; 814 break; 815 case ".": 816 addClass(); 817 break; 818 case ">": 819 addClass(); 820 if (node) 821 node.class?.trim(); 822 mode = 1; 823 break; 824 default: 825 buffer += char; 826 } 827 break; 828 case 4: 829 if (char === ">") { 830 buffer = buffer.replace(MULTI_SPACE_RE, " "); 831 if (node?.type === "v") 832 node.voice = replaceHTMLEntities(buffer); 833 else if (node?.type === "lang") 834 node.lang = replaceHTMLEntities(buffer); 835 buffer = ""; 836 mode = 1; 837 } else { 838 buffer += char; 839 } 840 break; 841 case 5: 842 if (char === ">") { 843 buffer = ""; 844 node = stack.pop(); 845 mode = 1; 846 } 847 break; 848 case 6: 849 if (char === ">") { 850 const time = parseVTTTimestamp(buffer); 851 if (time !== null && time >= cue.startTime && time <= cue.endTime) { 852 buffer = "timestamp"; 853 addNode(); 854 node.time = time; 855 } 856 buffer = ""; 857 mode = 1; 858 } else { 859 buffer += char; 860 } 861 break; 862 } 863 } 864 function addNode() { 865 if (BLOCK_TYPES.has(buffer)) { 866 const parent = node; 867 node = createBlockNode(buffer); 868 if (parent) { 869 if (stack[stack.length - 1] !== parent) 870 stack.push(parent); 871 parent.children.push(node); 872 } else 873 result.push(node); 874 } 875 buffer = ""; 876 mode = 1; 877 } 878 function addClass() { 879 if (node && buffer) { 880 const color = buffer.replace("bg_", ""); 881 if (COLORS.has(color)) { 882 node[buffer.startsWith("bg_") ? "bgColor" : "color"] = color; 883 } else { 884 node.class = !node.class ? buffer : node.class + " " + buffer; 885 } 886 } 887 buffer = ""; 888 } 889 function addText() { 890 if (!buffer) 891 return; 892 const text = { type: "text", data: replaceHTMLEntities(buffer) }; 893 node ? node.children.push(text) : result.push(text); 894 buffer = ""; 895 } 896 if (mode === 1) 897 addText(); 898 return result; 899} 900function createBlockNode(type) { 901 return { 902 tagName: TAG_NAME[type], 903 type, 904 children: [] 905 }; 906} 907function replaceHTMLEntities(text) { 908 return text.replace(HTML_ENTITY_RE, (entity) => HTML_ENTITIES[entity] || "'"); 909} 910 911function setCSSVar(el, name, value) { 912 el.style.setProperty(`--${name}`, value + ""); 913} 914function setDataAttr(el, name, value = true) { 915 el.setAttribute(`data-${name}`, value === true ? "" : value + ""); 916} 917function setPartAttr(el, name) { 918 el.setAttribute("data-part", name); 919} 920function getLineHeight(el) { 921 return parseFloat(getComputedStyle(el).lineHeight) || 0; 922} 923 924function createVTTCueTemplate(cue) { 925 if (IS_SERVER) { 926 throw Error( 927 "[media-captions] called `createVTTCueTemplate` on the server - use `renderVTTCueString`" 928 ); 929 } 930 const template = document.createElement("template"); 931 template.innerHTML = renderVTTCueString(cue); 932 return { cue, content: template.content }; 933} 934function renderVTTCueString(cue, currentTime = 0) { 935 return renderVTTTokensString(tokenizeVTTCue(cue), currentTime); 936} 937function renderVTTTokensString(tokens, currentTime = 0) { 938 let attrs, result = ""; 939 for (const token of tokens) { 940 if (token.type === "text") { 941 result += token.data; 942 } else { 943 const isTimestamp = token.type === "timestamp"; 944 attrs = {}; 945 attrs.class = token.class; 946 attrs.title = token.type === "v" && token.voice; 947 attrs.lang = token.type === "lang" && token.lang; 948 attrs["data-part"] = token.type === "v" && "voice"; 949 if (isTimestamp) { 950 attrs["data-part"] = "timed"; 951 attrs["data-time"] = token.time; 952 attrs["data-future"] = token.time > currentTime; 953 attrs["data-past"] = token.time < currentTime; 954 } 955 attrs.style = `${token.color ? `color: ${token.color};` : ""}${token.bgColor ? `background-color: ${token.bgColor};` : ""}`; 956 const attributes = Object.entries(attrs).filter((v) => v[1]).map((v) => `${v[0]}="${v[1] === true ? "" : v[1]}"`).join(" "); 957 result += `<${token.tagName}${attributes ? " " + attributes : ""}>${renderVTTTokensString( 958 token.children 959 )}</${token.tagName}>`; 960 } 961 } 962 return result; 963} 964function updateTimedVTTCueNodes(root, currentTime) { 965 if (IS_SERVER) 966 return; 967 for (const el of root.querySelectorAll('[data-
vendor: 7,564 bytes, lines 967-1226
967part="timed"]')) { 968 const time = Number(el.getAttribute("data-time")); 969 if (Number.isNaN(time)) 970 continue; 971 if (time > currentTime) 972 setDataAttr(el, "future"); 973 else 974 el.removeAttribute("data-future"); 975 if (time < currentTime) 976 setDataAttr(el, "past"); 977 else 978 el.removeAttribute("data-past"); 979 } 980} 981 982function debounce(fn, delay) { 983 let timeout = null, args; 984 function run() { 985 clear(); 986 fn(...args); 987 args = void 0; 988 } 989 function clear() { 990 clearTimeout(timeout); 991 timeout = null; 992 } 993 function debounce2() { 994 args = [].slice.call(arguments); 995 clear(); 996 timeout = setTimeout(run, delay); 997 } 998 return debounce2; 999} 1000 1001const STARTING_BOX = Symbol(0); 1002function createBox(box) { 1003 if (box instanceof HTMLElement) { 1004 return { 1005 top: box.offsetTop, 1006 width: box.clientWidth, 1007 height: box.clientHeight, 1008 left: box.offsetLeft, 1009 right: box.offsetLeft + box.clientWidth, 1010 bottom: box.offsetTop + box.clientHeight 1011 }; 1012 } 1013 return { ...box }; 1014} 1015function moveBox(box, axis, delta) { 1016 switch (axis) { 1017 case "+x": 1018 box.left += delta; 1019 box.right += delta; 1020 break; 1021 case "-x": 1022 box.left -= delta; 1023 box.right -= delta; 1024 break; 1025 case "+y": 1026 box.top += delta; 1027 box.bottom += delta; 1028 break; 1029 case "-y": 1030 box.top -= delta; 1031 box.bottom -= delta; 1032 break; 1033 } 1034} 1035function isBoxCollision(a, b) { 1036 return a.left <= b.right && a.right >= b.left && a.top <= b.bottom && a.bottom >= b.top; 1037} 1038function isAnyBoxCollision(box, boxes) { 1039 for (let i = 0; i < boxes.length; i++) 1040 if (isBoxCollision(box, boxes[i])) 1041 return boxes[i]; 1042 return null; 1043} 1044function isWithinBox(container, box) { 1045 return box.top >= 0 && box.bottom <= container.height && box.left >= 0 && box.right <= container.width; 1046} 1047function isBoxOutOfBounds(container, box, axis) { 1048 switch (axis) { 1049 case "+x": 1050 return box.left < 0; 1051 case "-x": 1052 return box.right > container.width; 1053 case "+y": 1054 return box.top < 0; 1055 case "-y": 1056 return box.bottom > container.height; 1057 } 1058} 1059function calcBoxIntersectPercentage(container, box) { 1060 const x = Math.max(0, Math.min(container.width, box.right) - Math.max(0, box.left)), y = Math.max(0, Math.min(container.height, box.bottom) - Math.max(0, box.top)), intersectArea = x * y; 1061 return intersectArea / (container.height * container.width); 1062} 1063function createCSSBox(container, box) { 1064 return { 1065 top: box.top / container.height, 1066 left: box.left / container.width, 1067 right: (container.width - box.right) / container.width, 1068 bottom: (container.height - box.bottom) / container.height 1069 }; 1070} 1071function resolveRelativeBox(container, box) { 1072 box.top = box.top * container.height; 1073 box.left = box.left * container.width; 1074 box.right = container.width - box.right * container.width; 1075 box.bottom = container.height - box.bottom * container.height; 1076 return box; 1077} 1078const BOX_SIDES = ["top", "left", "right", "bottom"]; 1079function setBoxCSSVars(el, container, box, prefix) { 1080 const cssBox = createCSSBox(container, box); 1081 for (const side of BOX_SIDES) { 1082 setCSSVar(el, `${prefix}-${side}`, cssBox[side] * 100 + "%"); 1083 } 1084} 1085function avoidBoxCollisions(container, box, boxes, axis) { 1086 let percentage = 1, positionedBox, startBox = { ...box }; 1087 for (let i = 0; i < axis.length; i++) { 1088 while (isBoxOutOfBounds(container, box, axis[i]) || isWithinBox(container, box) && isAnyBoxCollision(box, boxes)) { 1089 moveBox(box, axis[i], 1); 1090 } 1091 if (isWithinBox(container, box)) 1092 return box; 1093 const intersection = calcBoxIntersectPercentage(container, box); 1094 if (percentage > intersection) { 1095 positionedBox = { ...box }; 1096 percentage = intersection; 1097 } 1098 box = { ...startBox }; 1099 } 1100 return positionedBox || startBox; 1101} 1102 1103const POSITION_OVERRIDE = Symbol(0); 1104function positionCue(container, cue, displayEl, boxes) { 1105 let cueEl = displayEl.firstElementChild, line = computeCueLine(cue), displayBox, axis = []; 1106 if (!displayEl[STARTING_BOX]) { 1107 displayEl[STARTING_BOX] = createStartingBox(container, displayEl); 1108 } 1109 displayBox = resolveRelativeBox(container, { ...displayEl[STARTING_BOX] }); 1110 if (displayEl[POSITION_OVERRIDE]) { 1111 axis = [displayEl[POSITION_OVERRIDE] === "top" ? "+y" : "-y", "+x", "-x"]; 1112 } else if (cue.snapToLines) { 1113 let size; 1114 switch (cue.vertical) { 1115 case "": 1116 axis = ["+y", "-y"]; 1117 size = "height"; 1118 break; 1119 case "rl": 1120 axis = ["+x", "-x"]; 1121 size = "width"; 1122 break; 1123 case "lr": 1124 axis = ["-x", "+x"]; 1125 size = "width"; 1126 break; 1127 } 1128 let step = getLineHeight(cueEl), position = step * Math.round(line), maxPosition = container[size] + step, initialAxis = axis[0]; 1129 if (Math.abs(position) > maxPosition) { 1130 position = position < 0 ? -1 : 1; 1131 position *= Math.ceil(maxPosition / step) * step; 1132 } 1133 if (line < 0) { 1134 position += cue.vertical === "" ? container.height : container.width; 1135 axis = axis.reverse(); 1136 } 1137 moveBox(displayBox, initialAxis, position); 1138 } else { 1139 const isHorizontal = cue.vertical === "", posAxis = isHorizontal ? "+y" : "+x", size = isHorizontal ? displayBox.height : displayBox.width; 1140 moveBox( 1141 displayBox, 1142 posAxis, 1143 (isHorizontal ? container.height : container.width) * line / 100 1144 ); 1145 moveBox( 1146 displayBox, 1147 posAxis, 1148 cue.lineAlign === "center" ? size / 2 : cue.lineAlign === "end" ? size : 0 1149 ); 1150 axis = isHorizontal ? ["-y", "+y", "-x", "+x"] : ["-x", "+x", "-y", "+y"]; 1151 } 1152 displayBox = avoidBoxCollisions(container, displayBox, boxes, axis); 1153 setBoxCSSVars(displayEl, container, displayBox, "cue"); 1154 return displayBox; 1155} 1156function createStartingBox(container, cueEl) { 1157 const box = createBox(cueEl), pos = getStyledPositions(cueEl); 1158 cueEl[POSITION_OVERRIDE] = false; 1159 if (pos.top) { 1160 box.top = pos.top; 1161 box.bottom = pos.top + box.height; 1162 cueEl[POSITION_OVERRIDE] = "top"; 1163 } 1164 if (pos.bottom) { 1165 const bottom = container.height - pos.bottom; 1166 box.top = bottom - box.height; 1167 box.bottom = bottom; 1168 cueEl[POSITION_OVERRIDE] = "bottom"; 1169 } 1170 if (pos.left) 1171 box.left = pos.left; 1172 if (pos.right) 1173 box.right = container.width - pos.right; 1174 return createCSSBox(container, box); 1175} 1176function getStyledPositions(el) { 1177 const positions = {}; 1178 for (const side of BOX_SIDES) { 1179 positions[side] = parseFloat(el.style.getPropertyValue(`--cue-${side}`)); 1180 } 1181 return positions; 1182} 1183function computeCueLine(cue) { 1184 if (cue.line === "auto") { 1185 if (!cue.snapToLines) { 1186 return 100; 1187 } else { 1188 return -1; 1189 } 1190 } 1191 return cue.line; 1192} 1193function computeCuePosition(cue) { 1194 if (cue.position === "auto") { 1195 switch (cue.align) { 1196 case "start": 1197 case "left": 1198 return 0; 1199 case "right": 1200 case "end": 1201 return 100; 1202 default: 1203 return 50; 1204 } 1205 } 1206 return cue.position; 1207} 1208function computeCuePositionAlignment(cue, dir) { 1209 if (cue.positionAlign === "auto") { 1210 switch (cue.align) { 1211 case "start": 1212 return dir === "ltr" ? "line-left" : "line-right"; 1213 case "end": 1214 return dir === "ltr" ? "line-right" : "line-left"; 1215 case "center": 1216 return "center"; 1217 default: 1218 return `line-${cue.align}`; 1219 } 1220 } 1221 return cue.positionAlign; 1222} 1223 1224const REGION_AXIS = ["-y", "+y", "-x", "+x"]; 1225function positionRegion(container, region, regionEl, boxes) { 1226 let cues = Array.from(regionEl.querySelectorAll('[
vendor: 6,866 bytes, lines 1226-1450
1226data-part="cue-display"]')), height = 0, limit = Math.max(0, cues.length - region.lines); 1227 for (let i = cues.length - 1; i >= limit; i--) { 1228 height += cues[i].offsetHeight; 1229 } 1230 setCSSVar(regionEl, "region-height", height + "px"); 1231 if (!regionEl[STARTING_BOX]) { 1232 regionEl[STARTING_BOX] = createCSSBox(container, createBox(regionEl)); 1233 } 1234 let box = { ...regionEl[STARTING_BOX] }; 1235 box = resolveRelativeBox(container, box); 1236 box.width = regionEl.clientWidth; 1237 box.height = height; 1238 box.right = box.left + box.width; 1239 box.bottom = box.top + height; 1240 box = avoidBoxCollisions(container, box, boxes, REGION_AXIS); 1241 setBoxCSSVars(regionEl, container, box, "region"); 1242 return box; 1243} 1244 1245class CaptionsRenderer { 1246 overlay; 1247 z; 1248 A = 0; 1249 C = "ltr"; 1250 B = []; 1251 D = false; 1252 E; 1253 j = /* @__PURE__ */ new Map(); 1254 l = /* @__PURE__ */ new Map(); 1255 /* Text direction. */ 1256 get dir() { 1257 return this.C; 1258 } 1259 set dir(dir) { 1260 this.C = dir; 1261 setDataAttr(this.overlay, "dir", dir); 1262 } 1263 get currentTime() { 1264 return this.A; 1265 } 1266 set currentTime(time) { 1267 this.A = time; 1268 this.update(); 1269 } 1270 constructor(overlay, init) { 1271 this.overlay = overlay; 1272 this.dir = init?.dir ?? "ltr"; 1273 overlay.setAttribute("translate", "yes"); 1274 overlay.setAttribute("aria-live", "off"); 1275 overlay.setAttribute("aria-atomic", "true"); 1276 setPartAttr(overlay, "captions"); 1277 this.G(); 1278 this.E = new ResizeObserver(this.I.bind(this)); 1279 this.E.observe(overlay); 1280 } 1281 changeTrack({ regions, cues }) { 1282 this.reset(); 1283 this.J(regions); 1284 for (const cue of cues) 1285 this.l.set(cue, null); 1286 this.update(); 1287 } 1288 addCue(cue) { 1289 this.l.set(cue, null); 1290 this.update(); 1291 } 1292 removeCue(cue) { 1293 this.l.delete(cue); 1294 this.update(); 1295 } 1296 update(forceUpdate = false) { 1297 this.H(forceUpdate); 1298 } 1299 reset() { 1300 this.l.clear(); 1301 this.j.clear(); 1302 this.B = []; 1303 this.overlay.textContent = ""; 1304 } 1305 destroy() { 1306 this.reset(); 1307 this.E.disconnect(); 1308 } 1309 I() { 1310 this.D = true; 1311 this.K(); 1312 } 1313 K = debounce(() => { 1314 this.D = false; 1315 this.G(); 1316 for (const el of this.j.values()) { 1317 el[STARTING_BOX] = null; 1318 } 1319 for (const el of this.l.values()) { 1320 if (el) 1321 el[STARTING_BOX] = null; 1322 } 1323 this.H(true); 1324 }, 50); 1325 G() { 1326 this.z = createBox(this.overlay); 1327 setCSSVar(this.overlay, "overlay-width", this.z.width + "px"); 1328 setCSSVar(this.overlay, "overlay-height", this.z.height + "px"); 1329 } 1330 H(forceUpdate = false) { 1331 if (!this.l.size || this.D) 1332 return; 1333 let cue, activeCues = [...this.l.keys()].filter((cue2) => this.A >= cue2.startTime && this.A <= cue2.endTime).sort( 1334 (cueA, cueB) => cueA.startTime !== cueB.startTime ? cueA.startTime - cueB.startTime : cueA.endTime - cueB.endTime 1335 ), activeRegions = activeCues.map((cue2) => cue2.region); 1336 for (let i = 0; i < this.B.length; i++) { 1337 cue = this.B[i]; 1338 if (activeCues[i] === cue) 1339 continue; 1340 if (cue.region && !activeRegions.includes(cue.region)) { 1341 const regionEl = this.j.get(cue.region.id); 1342 if (regionEl) { 1343 regionEl.removeAttribute("data-active"); 1344 forceUpdate = true; 1345 } 1346 } 1347 const cueEl = this.l.get(cue); 1348 if (cueEl) { 1349 cueEl.remove(); 1350 forceUpdate = true; 1351 } 1352 } 1353 for (let i = 0; i < activeCues.length; i++) { 1354 cue = activeCues[i]; 1355 let cueEl = this.l.get(cue); 1356 if (!cueEl) 1357 this.l.set(cue, cueEl = this.L(cue)); 1358 const regionEl = this.F(cue) && this.j.get(cue.region.id); 1359 if (regionEl && !regionEl.hasAttribute("data-active")) { 1360 requestAnimationFrame(() => setDataAttr(regionEl, "active")); 1361 forceUpdate = true; 1362 } 1363 if (!cueEl.isConnected) { 1364 (regionEl || this.overlay).append(cueEl); 1365 forceUpdate = true; 1366 } 1367 } 1368 if (forceUpdate) { 1369 const boxes = [], seen = /* @__PURE__ */ new Set(); 1370 for (let i = activeCues.length - 1; i >= 0; i--) { 1371 cue = activeCues[i]; 1372 if (seen.has(cue.region || cue)) 1373 continue; 1374 const isRegion = this.F(cue), el = isRegion ? this.j.get(cue.region.id) : this.l.get(cue); 1375 if (isRegion) { 1376 boxes.push(positionRegion(this.z, cue.region, el, boxes)); 1377 } else { 1378 boxes.push(positionCue(this.z, cue, el, boxes)); 1379 } 1380 seen.add(isRegion ? cue.region : cue); 1381 } 1382 } 1383 updateTimedVTTCueNodes(this.overlay, this.A); 1384 this.B = activeCues; 1385 } 1386 J(regions) { 1387 if (!regions) 1388 return; 1389 for (const region of regions) { 1390 const el = this.M(region); 1391 this.j.set(region.id, el); 1392 this.overlay.append(el); 1393 } 1394 } 1395 M(region) { 1396 const el = document.createElement("div"); 1397 setPartAttr(el, "region"); 1398 setDataAttr(el, "id", region.id); 1399 setDataAttr(el, "scroll", region.scroll); 1400 setCSSVar(el, "region-width", region.width + "%"); 1401 setCSSVar(el, "region-anchor-x", region.regionAnchorX); 1402 setCSSVar(el, "region-anchor-y", region.regionAnchorY); 1403 setCSSVar(el, "region-viewport-anchor-x", region.viewportAnchorX); 1404 setCSSVar(el, "region-viewport-anchor-y", region.viewportAnchorY); 1405 setCSSVar(el, "region-lines", region.lines); 1406 return el; 1407 } 1408 L(cue) { 1409 const display = document.createElement("div"), position = computeCuePosition(cue), positionAlignment = computeCuePositionAlignment(cue, this.C); 1410 setPartAttr(display, "cue-display"); 1411 if (cue.vertical !== "") 1412 setDataAttr(display, "vertical"); 1413 setCSSVar(display, "cue-text-align", cue.align); 1414 if (cue.style) { 1415 for (const prop of Object.keys(cue.style)) { 1416 display.style.setProperty(prop, cue.style[prop]); 1417 } 1418 } 1419 if (!this.F(cue)) { 1420 setCSSVar( 1421 display, 1422 "cue-writing-mode", 1423 cue.vertical === "" ? "horizontal-tb" : cue.vertical === "lr" ? "vertical-lr" : "vertical-rl" 1424 ); 1425 if (!cue.style?.["--cue-width"]) { 1426 let maxSize = position; 1427 if (positionAlignment === "line-left") { 1428 maxSize = 100 - position; 1429 } else if (positionAlignment === "center" && position <= 50) { 1430 maxSize = position * 2; 1431 } else if (positionAlignment === "center" && position > 50) { 1432 maxSize = (100 - position) * 2; 1433 } 1434 const size = cue.size < maxSize ? cue.size : maxSize; 1435 if (cue.vertical === "") 1436 setCSSVar(display, "cue-width", size + "%"); 1437 else 1438 setCSSVar(display, "cue-height", size + "%"); 1439 } 1440 } else { 1441 setCSSVar( 1442 display, 1443 "cue-offset", 1444 `${position - (positionAlignment === "line-right" ? 100 : positionAlignment === "center" ? 50 : 0)}%` 1445 ); 1446 } 1447 const el = document.createElement("div"); 1448 setPartAttr(el, "cue"); 1449 if (cue.id) 1450 setDataAttr(el, "id", cue.id);
1451 el.innerHTML = renderVTTCueString(cue); 1452 display.append(el); 1453 return display; 1454 } 1455 F(cue) { 1456 return cue.region && cue.size === 100 && cue.vertical === "" && cue.line === "auto"; 1457 } 1458} 1459 1460 1461 1462 1463/***/ }), 1464 1465/***/ 3892: 1466/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1467 1468__webpack_require__.r(__webpack_exports__); 1469/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1470/* harmony export */ SRTParser: () => (/* binding */ SRTParser), 1471/* harmony export */ "default": () => (/* binding */ createSRTParser) 1472/* harmony export */ }); 1473/* harmony import */ var _index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(574); 1474 1475 1476const MILLISECOND_SEP_RE = /,/g, TIMESTAMP_SEP = "-->"; 1477class SRTParser extends _index_js__WEBPACK_IMPORTED_MODULE_0__.V { 1478 parse(line, lineCount) { 1479 if (line === "") { 1480 if (this.c) { 1481 this.l.push(this.c); 1482 this.h.onCue?.(this.c); 1483 this.c = null; 1484 } 1485 this.e = _index_js__WEBPACK_IMPORTED_MODULE_0__.a.None; 1486 } else if (this.e === _index_js__WEBPACK_IMPORTED_MODULE_0__.a.Cue) { 1487 this.c.text += (this.c.text ? "\n" : "") + line; 1488 } else if (line.includes(TIMESTAMP_SEP)) { 1489 const result = this.q(line, lineCount); 1490 if (result) { 1491 this.c = new _index_js__WEBPACK_IMPORTED_MODULE_0__.b(result[0], result[1], result[2].join(" ")); 1492 this.c.id = this.n; 1493 this.e = _index_js__WEBPACK_IMPORTED_MODULE_0__.a.Cue; 1494 } 1495 } 1496 this.n = line; 1497 } 1498 q(line, lineCount) { 1499 return super.q(line.replace(MILLISECOND_SEP_RE, "."), lineCount); 1500 } 1501} 1502function createSRTParser() { 1503 return new SRTParser(); 1504} 1505 1506 1507 1508 1509/***/ }), 1510 1511/***/ 6900: 1512/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 1513 1514__webpack_require__.r(__webpack_exports__); 1515/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1516/* harmony export */ SSAParser: () => (/* binding */ SSAParser), 1517/* harmony export */ "default": () => (/* binding */ createSSAParser) 1518/* harmony export */ }); 1519/* harmony import */ var _index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(574); 1520 1521 1522const FORMAT_START_RE = /^Format:[\s\t]*/, STYLE_START_RE = /^Style:[\s\t]*/, DIALOGUE_START_RE = /^Dialogue:[\s\t]*/, FORMAT_SPLIT_RE = /[\s\t]*,[\s\t]*/, STYLE_FUNCTION_RE = /\{[^}]+\}/g, NEW_LINE_RE = /\\N/g, STYLES_SECTION_START_RE = /^\[(.*)[\s\t]?Styles\]$/, EVENTS_SECTION_START_RE = /^\[(.*)[\s\t]?Events\]$/; 1523class SSAParser { 1524 h; 1525 O = 0; 1526 c = null; 1527 l = []; 1528 m = []; 1529 N = null; 1530 f; 1531 P = {}; 1532 async init(init) { 1533 this.h = init; 1534 if (init.errors) 1535 this.f = (await __webpack_require__.e(/* import() */ 7).then(__webpack_require__.bind(__webpack_require__, 2557))).ParseErrorBuilder; 1536 } 1537 parse(line, lineCount) { 1538 if (this.O) { 1539 switch (this.O) { 1540 case 1: 1541 if (line === "") { 1542 this.O = 0; 1543 } else if (STYLE_START_RE.test(line)) { 1544 if (this.N) { 1545 const styles = line.replace(STYLE_START_RE, "").split(FORMAT_SPLIT_RE); 1546 this.S(styles); 1547 } else { 1548 this.g(this.f?.T("Style", lineCount)); 1549 } 1550 } else if (FORMAT_START_RE.test(line)) { 1551 this.N = line.replace(FORMAT_START_RE, "").split(FORMAT_SPLIT_RE); 1552 } else if (EVENTS_SECTION_START_RE.test(line)) { 1553 this.N = null; 1554 this.O = 2; 1555 } 1556 break; 1557 case 2: 1558 if (line === "") { 1559 this.Q(); 1560 } else if (DIALOGUE_START_RE.test(line)) { 1561 this.Q(); 1562 if (this.N) { 1563 const dialogue = line.replace(DIALOGUE_START_RE, "").split(FORMAT_SPLIT_RE), cue = this.U(dialogue, lineCount); 1564 if (cue) 1565 this.c = cue; 1566 } else { 1567 this.g(this.f?.T("Dialogue", lineCount)); 1568 } 1569 } else if (this.c) { 1570 this.c.text += "\n" + line.replace(STYLE_FUNCTION_RE, "").replace(NEW_LINE_RE, "\n"); 1571 } else if (FORMAT_START_RE.test(line)) { 1572 this.N = line.replace(FORMAT_START_RE, "").split(FORMAT_SPLIT_RE); 1573 } else if (STYLES_SECTION_START_RE.test(line)) { 1574 this.N = null; 1575 this.O = 1; 1576 } else if (EVENTS_SECTION_START_RE.test(line)) { 1577 this.N = null; 1578 } 1579 } 1580 } else if (line === "") ; else if (STYLES_SECTION_START_RE.test(line)) { 1581 this.N = null; 1582 this.O = 1; 1583 } else if (EVENTS_SECTION_START_RE.test(line)) { 1584 this.N = null; 1585 this.O = 2; 1586 } 1587 } 1588 done() { 1589 return { 1590 metadata: {}, 1591 cues: this.l, 1592 regions: [], 1593 errors: this.m 1594 }; 1595 } 1596 Q() { 1597 if (!this.c) 1598 return; 1599 this.l.push(this.c); 1600 this.h.onCue?.(this.c); 1601 this.c = null; 1602 } 1603 S(values) { 1604 let name = "Default", styles = {}, outlineX, align = "center", vertical = "bottom", marginV, outlineY = 1.2, outlineColor, bgColor, borderStyle = 3, transform = []; 1605 for (let i = 0; i < this.N.length; i++) { 1606 const field = this.N[i], value = values[i]; 1607 switch (field) { 1608 case "Name": 1609 name = value; 1610 break; 1611 case "Fontname": 1612 styles["font-family"] = value; 1613 break; 1614 case "Fontsize": 1615 styles["font-size"] = `calc(${value} / var(--overlay-height))`; 1616 break; 1617 case "PrimaryColour": 1618 const color = parseColor(value); 1619 if (color) 1620 styles["--cue-color"] = color; 1621 break; 1622 case "BorderStyle": 1623 borderStyle = parseInt(value, 10); 1624 break; 1625 case "BackColour": 1626 bgColor = parseColor(value); 1627 break; 1628 case "OutlineColour": 1629 const _outlineColor = parseColor(value); 1630 if (_outlineColor) 1631 outlineColor = _outlineColor; 1632 break; 1633 case "Bold": 1634 if (parseInt(value)) 1635 styles["font-weight"] = "bold"; 1636 break; 1637 case "Italic": 1638 if (parseInt(value)) 1639 styles["font-style"] = "italic"; 1640 break; 1641 case "Underline": 1642 if (parseInt(value)) 1643 styles["text-decoration"] = "underline"; 1644 break; 1645 case "StrikeOut": 1646 if (parseInt(value)) 1647 styles["text-decoration"] = "line-through"; 1648 break; 1649 case "Spacing": 1650 styles["letter-spacing"] = value + "px"; 1651 break; 1652 case "AlphaLevel": 1653 styles["opacity"] = parseFloat(value); 1654 break; 1655 case "ScaleX":
vendor: 5,291 bytes, lines 1656-1817
1656 transform.push(`scaleX(${parseFloat(value) / 100})`); 1657 break; 1658 case "ScaleY": 1659 transform.push(`scaleY(${parseFloat(value) / 100})`); 1660 break; 1661 case "Angle": 1662 transform.push(`rotate(${value}deg)`); 1663 break; 1664 case "Shadow": 1665 outlineY = parseInt(value, 10) * 1.2; 1666 break; 1667 case "MarginL": 1668 styles["--cue-width"] = "auto"; 1669 styles["--cue-left"] = parseFloat(value) + "px"; 1670 break; 1671 case "MarginR": 1672 styles["--cue-width"] = "auto"; 1673 styles["--cue-right"] = parseFloat(value) + "px"; 1674 break; 1675 case "MarginV": 1676 marginV = parseFloat(value); 1677 break; 1678 case "Outline": 1679 outlineX = parseInt(value, 10); 1680 break; 1681 case "Alignment": 1682 const alignment = parseInt(value, 10); 1683 if (alignment >= 4) 1684 vertical = alignment >= 7 ? "top" : "center"; 1685 switch (alignment % 3) { 1686 case 1: 1687 align = "start"; 1688 break; 1689 case 2: 1690 align = "center"; 1691 break; 1692 case 3: 1693 align = "end"; 1694 break; 1695 } 1696 } 1697 } 1698 styles.R = vertical; 1699 styles["--cue-white-space"] = "normal"; 1700 styles["--cue-line-height"] = "normal"; 1701 styles["--cue-text-align"] = align; 1702 if (vertical === "center") { 1703 styles[`--cue-top`] = "50%"; 1704 transform.push("translateY(-50%)"); 1705 } else { 1706 styles[`--cue-${vertical}`] = (marginV || 0) + "px"; 1707 } 1708 if (borderStyle === 1) { 1709 styles["--cue-padding-y"] = "0"; 1710 } 1711 if (borderStyle === 1 || bgColor) { 1712 styles["--cue-bg-color"] = borderStyle === 1 ? "none" : bgColor; 1713 } 1714 if (borderStyle === 3 && outlineColor) { 1715 styles["--cue-outline"] = `${outlineX}px solid ${outlineColor}`; 1716 } 1717 if (borderStyle === 1 && typeof outlineX === "number") { 1718 const color = bgColor ?? "#000"; 1719 styles["--cue-text-shadow"] = [ 1720 outlineColor && buildTextShadow(outlineX * 1.2, outlineY * 1.2, outlineColor), 1721 outlineColor ? buildTextShadow(outlineX * (outlineX / 2), outlineY * (outlineX / 2), color) : buildTextShadow(outlineX, outlineY, color) 1722 ].filter(Boolean).join(", "); 1723 } 1724 if (transform.length) 1725 styles["--cue-transform"] = transform.join(" "); 1726 this.P[name] = styles; 1727 } 1728 U(values, lineCount) { 1729 const fields = this.V(values); 1730 const timestamp = this.q(fields.Start, fields.End, lineCount); 1731 if (!timestamp) 1732 return; 1733 const cue = new _index_js__WEBPACK_IMPORTED_MODULE_0__.b(timestamp[0], timestamp[1], ""), styles = { ...this.P[fields.Style] || {} }, voice = fields.Name ? `<v ${fields.Name}>` : ""; 1734 const vertical = styles.R, marginLeft = fields.MarginL && parseFloat(fields.MarginL), marginRight = fields.MarginR && parseFloat(fields.MarginR), marginV = fields.MarginV && parseFloat(fields.MarginV); 1735 if (marginLeft) { 1736 styles["--cue-width"] = "auto"; 1737 styles["--cue-left"] = marginLeft + "px"; 1738 } 1739 if (marginRight) { 1740 styles["--cue-width"] = "auto"; 1741 styles["--cue-right"] = marginRight + "px"; 1742 } 1743 if (marginV && vertical !== "center") { 1744 styles[`--cue-${vertical}`] = marginV + "px"; 1745 } 1746 cue.text = voice + values.slice(this.N.length - 1).join(", ").replace(STYLE_FUNCTION_RE, "").replace(NEW_LINE_RE, "\n"); 1747 delete styles.R; 1748 if (Object.keys(styles).length) 1749 cue.style = styles; 1750 return cue; 1751 } 1752 V(values) { 1753 const fields = {}; 1754 for (let i = 0; i < this.N.length; i++) { 1755 fields[this.N[i]] = values[i]; 1756 } 1757 return fields; 1758 } 1759 q(startTimeText, endTimeText, lineCount) { 1760 const startTime = (0,_index_js__WEBPACK_IMPORTED_MODULE_0__.p)(startTimeText), endTime = (0,_index_js__WEBPACK_IMPORTED_MODULE_0__.p)(endTimeText); 1761 if (startTime !== null && endTime !== null && endTime > startTime) { 1762 return [startTime, endTime]; 1763 } else { 1764 if (startTime === null) { 1765 this.g(this.f?.s(startTimeText, lineCount)); 1766 } 1767 if (endTime === null) { 1768 this.g(this.f?.t(endTimeText, lineCount)); 1769 } 1770 if (startTime != null && endTime !== null && endTime > startTime) { 1771 this.g(this.f?.u(startTime, endTime, lineCount)); 1772 } 1773 } 1774 } 1775 g(error) { 1776 if (!error) 1777 return; 1778 this.m.push(error); 1779 if (this.h.strict) { 1780 this.h.cancel(); 1781 throw error; 1782 } else { 1783 this.h.onError?.(error); 1784 } 1785 } 1786} 1787function parseColor(color) { 1788 const abgr = parseInt(color.replace("&H", ""), 16); 1789 if (abgr >= 0) { 1790 const a = abgr >> 24 & 255 ^ 255; 1791 const alpha = a / 255; 1792 const b = abgr >> 16 & 255; 1793 const g = abgr >> 8 & 255; 1794 const r = abgr & 255; 1795 return "rgba(" + [r, g, b, alpha].join(",") + ")"; 1796 } 1797 return null; 1798} 1799function buildTextShadow(x, y, color) { 1800 const noOfShadows = Math.ceil(2 * Math.PI * x); 1801 let textShadow = ""; 1802 for (let i = 0; i < noOfShadows; i++) { 1803 const theta = 2 * Math.PI * i / noOfShadows; 1804 textShadow += x * Math.cos(theta) + "px " + y * Math.sin(theta) + "px 0 " + color + (i == noOfShadows - 1 ? "" : ","); 1805 } 1806 return textShadow; 1807} 1808function createSSAParser() { 1809 return new SSAParser(); 1810} 1811 1812 1813 1814 1815/***/ }) 1816 1817}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.